feat(addressables): 补全 catalog 可校验字段
bat-rust / Build and test Rust (push) Canceled after 0s
bat-rust / Build and test Go API (push) Canceled after 0s

补充 JSON/compact catalog 的 provider ID、bundle name、资源类型、hash、size、CRC 和依赖字段,并贯通 ResourceEntry、SQLite 资源索引和回归 golden。对 compact extra data 与 resource type index 的损坏返回明确错误,不再把 bundle name 当作 hash fallback。\n\n验证:cargo fmt --check;cargo test -p bat-core --locked;cargo test -p bat-adapters --locked;cargo test -p bat-infrastructure --locked;git diff --check。\n\nClippy 仍受既有 core/src/domain/game_client.rs:141 的 needless-question-mark 和 items-after-test-module 基线问题影响,未混入本 issue 修复。\n\nFixes #2
This commit is contained in:
2026-08-19 23:10:16 +08:00
parent 72c1a879a3
commit 9d4f8d903c
18 changed files with 311 additions and 55 deletions
+2
View File
@@ -3611,6 +3611,8 @@ fn test_resource(id: &str, path: &str, resource_type: ResourceType) -> Resource
resource_type,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
metadata,
+16
View File
@@ -560,6 +560,8 @@ mod tests {
resource_type: ResourceType::AssetBundle,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
ResourceEntry {
@@ -569,6 +571,8 @@ mod tests {
resource_type: ResourceType::Manifest,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
ResourceEntry {
@@ -578,6 +582,8 @@ mod tests {
resource_type: ResourceType::TextAsset,
address: Some("dialogue".to_string()),
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
ResourceEntry {
@@ -587,6 +593,8 @@ mod tests {
resource_type: ResourceType::TableBundle,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
ResourceEntry {
@@ -596,6 +604,8 @@ mod tests {
resource_type: ResourceType::Media,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
],
@@ -627,6 +637,8 @@ mod tests {
resource_type: ResourceType::TextAsset,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
}
}
@@ -648,6 +660,8 @@ mod tests {
resource_type: ResourceType::AssetBundle,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
]);
@@ -801,6 +815,8 @@ mod tests {
resource_type: ResourceType::AssetBundle,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
}]);
@@ -211,6 +211,8 @@ impl<'a> OfficialReleaseImportService<'a> {
resource_type,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
metadata,
+33 -5
View File
@@ -129,6 +129,8 @@ impl SqliteResourceRepository {
resource_type TEXT NOT NULL,
local_path TEXT NOT NULL,
address TEXT,
provider_id TEXT,
bundle_name TEXT,
dependencies_json TEXT NOT NULL DEFAULT '[]',
crc INTEGER,
metadata_json TEXT NOT NULL DEFAULT '{}'
@@ -148,6 +150,8 @@ impl SqliteResourceRepository {
"TEXT NOT NULL DEFAULT '{}'",
)
.await?;
Self::ensure_column(&self.pool, "resources", "provider_id", "TEXT").await?;
Self::ensure_column(&self.pool, "resources", "bundle_name", "TEXT").await?;
Self::execute_query(
&self.pool,
@@ -280,6 +284,8 @@ impl SqliteResourceRepository {
resource_type,
local_path,
address,
provider_id,
bundle_name,
dependencies_json,
crc,
metadata_json,
@@ -294,6 +300,8 @@ impl SqliteResourceRepository {
resource_type: Self::resource_type_from_str(&resource_type)?,
address,
dependencies: Self::dependencies_from_json(&dependencies_json)?,
provider_id,
bundle_name,
crc: crc.and_then(|value| u32::try_from(value).ok()),
},
metadata: Self::metadata_from_json(&metadata_json)?,
@@ -341,7 +349,7 @@ impl SqliteResourceRepository {
limit: Option<usize>,
) -> bat_core::Result<Vec<Resource>> {
let mut builder = QueryBuilder::<Sqlite>::new(
"SELECT id, path, hash, size, resource_type, local_path, address, dependencies_json, crc, metadata_json FROM resources",
"SELECT id, path, hash, size, resource_type, local_path, address, provider_id, bundle_name, dependencies_json, crc, metadata_json FROM resources",
);
Self::apply_filters(&mut builder, query)?;
builder.push(" ORDER BY id");
@@ -392,9 +400,9 @@ impl ResourceRepository for SqliteResourceRepository {
sqlx::query(
r#"
INSERT INTO resources (
id, path, hash, size, resource_type, local_path, address, dependencies_json, crc, metadata_json
id, path, hash, size, resource_type, local_path, address, provider_id, bundle_name, dependencies_json, crc, metadata_json
)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
ON CONFLICT(id) DO UPDATE SET
path = excluded.path,
hash = excluded.hash,
@@ -402,6 +410,8 @@ impl ResourceRepository for SqliteResourceRepository {
resource_type = excluded.resource_type,
local_path = excluded.local_path,
address = excluded.address,
provider_id = excluded.provider_id,
bundle_name = excluded.bundle_name,
dependencies_json = excluded.dependencies_json,
crc = excluded.crc,
metadata_json = excluded.metadata_json
@@ -414,6 +424,8 @@ impl ResourceRepository for SqliteResourceRepository {
.bind(Self::resource_type_to_str(resource.entry.resource_type))
.bind(resource.local_path.to_string_lossy().to_string())
.bind(resource.entry.address.clone())
.bind(resource.entry.provider_id.clone())
.bind(resource.entry.bundle_name.clone())
.bind(dependencies)
.bind(resource.entry.crc.map(i64::from))
.bind(metadata),
@@ -426,7 +438,7 @@ impl ResourceRepository for SqliteResourceRepository {
async fn find_by_id(&self, id: &str) -> bat_core::Result<Resource> {
let row: Option<ResourceRow> = sqlx::query_as(
r#"
SELECT id, path, hash, size, resource_type, local_path, address, dependencies_json, crc, metadata_json
SELECT id, path, hash, size, resource_type, local_path, address, provider_id, bundle_name, dependencies_json, crc, metadata_json
FROM resources
WHERE id = ?1
"#,
@@ -444,7 +456,7 @@ impl ResourceRepository for SqliteResourceRepository {
async fn find_by_hash(&self, hash: &str) -> bat_core::Result<Resource> {
let row: Option<ResourceRow> = sqlx::query_as(
r#"
SELECT id, path, hash, size, resource_type, local_path, address, dependencies_json, crc, metadata_json
SELECT id, path, hash, size, resource_type, local_path, address, provider_id, bundle_name, dependencies_json, crc, metadata_json
FROM resources
WHERE hash = ?1
ORDER BY id
@@ -505,6 +517,8 @@ type ResourceRow = (
String,
String,
Option<String>,
Option<String>,
Option<String>,
String,
Option<i64>,
String,
@@ -652,6 +666,8 @@ mod tests {
resource_type,
address: None,
dependencies: Vec::new(),
provider_id: None,
bundle_name: None,
crc: None,
},
metadata: ResourceMetadata::default(),
@@ -796,6 +812,10 @@ mod tests {
.entry
.dependencies
.push("assets/shared.bundle".to_string());
resource.entry.provider_id = Some(
"UnityEngine.ResourceManagement.ResourceProviders.AssetBundleProvider".to_string(),
);
resource.entry.bundle_name = Some("assets/model.bundle".to_string());
resource.metadata.official_release_id = Some("release-1".to_string());
resource.metadata.platform = Some("windows".to_string());
resource.metadata.bundle_path = Some("assets/model.bundle".to_string());
@@ -813,6 +833,14 @@ mod tests {
by_id.entry.dependencies,
vec!["assets/shared.bundle".to_string()]
);
assert_eq!(
by_id.entry.provider_id.as_deref(),
Some("UnityEngine.ResourceManagement.ResourceProviders.AssetBundleProvider")
);
assert_eq!(
by_id.entry.bundle_name.as_deref(),
Some("assets/model.bundle")
);
assert_eq!(
by_id.metadata.official_release_id.as_deref(),
Some("release-1")