Skip to content

Commit d026163

Browse files
[#120] Move the schema documentation to where it is useful (#136)
SQLite only keeps the text of the CREATE statement itself in sqlite_master, so the 58 comment lines documenting the schema in Init.sql reached nobody: .schema on a produced database showed bare column names. Comments now go inside the CREATE statements, where SQLite preserves them, so a produced .db is self-describing. Only facts needed to write a correct query and not guessable from the column name are kept there; the prose moved into the documentation, which ships in the release zip since #118. The same fix applies to AssetBundle.sql, the ContentLayout*.sql files (which already had good in-paren column notes plus a discarded prose block above each statement) and ContentSummary.sql. AGENTS.md records the convention. Documentation/analyzer.md was 81% schema reference, so the schema moved to a new strictly formatted Documentation/analyzer-schema.md and analyzer.md became the overview. contentlayout-database.md gained the same markdown-table format. The schema version history moved out of the Init.sql comment into a table on the new page, and serialized_files, types, property_names and property_types gained documentation they never had. No table, view or column changed, so PRAGMA user_version stays at 7. Also fixed while here: the ResX file-reference encoding for Init.sql and Finalize.sql (Windows-1252 since the initial commit, every other .sql is utf-8), the duplicated DDL in the Commands/SerializedFile classes (AddPreloadDependency declared a primary key the real DDL never had), and nine pre-existing broken documentation links.
1 parent c066841 commit d026163

36 files changed

Lines changed: 807 additions & 567 deletions

‎AGENTS.md‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ The feature libraries each build on UnityBinaryFormat and UnityFileSystem. See t
126126

127127
**Handlers**: Type-specific handlers extract specialized properties for Unity object types and populate additional tables. For example Mesh, AnimationClip, Shader, BuildReport, MonoScript.
128128

129-
**Views**: The database schema includes convenient views for seeing the data in useful ways, e.g. `object_view`. See `Documentation/analyzer.md` and `Documentation/addressables-build-reports.md` for schema details.
129+
**Views**: The database schema includes convenient views for seeing the data in useful ways, e.g. `object_view`. See `Documentation/analyzer-schema.md` for the core schema, and `Documentation/contentlayout-database.md`, `Documentation/buildreport.md` and `Documentation/addressables-build-reports.md` for the parts documented on their own pages.
130130

131131
CLI entry point is `UnityDataTool/Program.cs` using System.CommandLine. Per-command documentation is in `Documentation/`.
132132

@@ -135,9 +135,24 @@ CLI entry point is `UnityDataTool/Program.cs` using System.CommandLine. Per-comm
135135
### Extending Analyze
136136

137137
* New Unity types can be added by following the same pattern as the existing types, for example MonoScripts.
138-
* Any database schema change (new or changed tables, views, or columns) must bump `PRAGMA user_version` in `Analyzer/Resources/Init.sql` and extend the version-history comment above it.
138+
* Any database schema change (new or changed tables, views, or columns) must bump `PRAGMA user_version` in `Analyzer/Resources/Init.sql` and add a row to the version table in `Documentation/analyzer-schema.md`.
139139
* Analysis of additional file formats could be added, for example AssetBundle manifest files by following the pattern of Addressables build layout files are handled.
140140

141+
#### Commenting the .sql resources
142+
143+
SQLite only keeps the text of the `CREATE` statement itself in `sqlite_master`, so a comment placed
144+
*above* a statement is discarded and never reaches a produced database. Comments therefore go inside
145+
the statement:
146+
147+
* One short note on the first line inside the `CREATE TABLE ( ... )` parentheses saying what a row
148+
represents, and a trailing `--` note on a column only where the fact is needed to write a correct
149+
query and is not guessable from the column name (a foreign key, a sentinel like `''`, an option
150+
that leaves the column empty). Views get one purpose line as the first line of the body, after `AS`.
151+
* Full prose belongs in the documentation, not in the `.sql` file.
152+
* `CREATE INDEX` has no body, so the only comments left outside a statement are ones that explain the
153+
code rather than the schema, such as why the ContentLayout indexes are created after population.
154+
* Keep `.sql` comments ASCII-only.
155+
141156
### Other Extensions
142157

143158
The UnityFileSystem API and UnityBinaryFormat parsing can be useful for other analysis. The "dump", "analyze" and "serialized-file" commands can be considered reference examples of how to use those lower level tools.

‎Analyzer/Properties/Resources.resx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,10 @@
131131
<value>..\Resources\BuildReport.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
132132
</data>
133133
<data name="Finalize" type="System.Resources.ResXFileRef, System.Windows.Forms">
134-
<value>..\Resources\Finalize.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
134+
<value>..\Resources\Finalize.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
135135
</data>
136136
<data name="Init" type="System.Resources.ResXFileRef, System.Windows.Forms">
137-
<value>..\Resources\Init.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
137+
<value>..\Resources\Init.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
138138
</data>
139139
<data name="Mesh" type="System.Resources.ResXFileRef, System.Windows.Forms">
140140
<value>..\Resources\Mesh.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>

‎Analyzer/Resources/AssetBundle.sql‎

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,28 @@
1-
-- tables related to the AssetBundle and PreloadData objects
2-
3-
-- Do not confuse the AssetBundle Unity object (the source of much of this data)
4-
-- with the archives table, which is general to any Unity Archive.
5-
6-
-- The "assets" that an AssetBundle explicitly exposes: each m_Container entry of the AssetBundle
7-
-- object names an object (the addressable/asset name -> object it maps to). Populated only from
8-
-- the AssetBundle object, so this table is empty for Player and ContentDirectory builds.
9-
-- For scene bundles the entry names the scene and points at the synthetic Scene object (see
10-
-- AssetBundleHandler / SerializedFileSQLiteWriter).
111
CREATE TABLE IF NOT EXISTS assetbundle_assets(
12-
object INTEGER,
13-
name TEXT
2+
-- The assets an AssetBundle explicitly exposes: one row per m_Container entry of the
3+
-- AssetBundle object. Empty for Player and ContentDirectory builds, which have no such object.
4+
object INTEGER, -- objects.id; for a scene bundle this is the synthetic Scene object
5+
name TEXT -- the container path the asset is addressed by
146
);
157

16-
-- object depends on dependency. This table has three sources, only the first of which is truly
17-
-- AssetBundle-specific:
18-
-- * AssetBundleHandler: an asset's slice of the AssetBundle object's m_PreloadTable.
19-
-- * SerializedFileSQLiteWriter: a scene object -> each object in the scene's SerializedFiles.
20-
-- * PreloadDataHandler: the PreloadData object's m_Assets. PreloadData is a *separate* Unity
21-
-- object (not part of the AssetBundle object) and also exists in Player builds (one per scene
22-
-- in its sharedAssetsN.assets, plus one in globalgamemanagers.assets), so this table is NOT
23-
-- empty there. Player builds have no scene object, so those rows hang off the PreloadData
24-
-- object itself; scene bundles hang them off the synthetic Scene object.
258
CREATE TABLE IF NOT EXISTS preload_dependencies(
26-
object INTEGER,
27-
dependency INTEGER
9+
-- Objects that Unity preloads alongside another object. Populated for AssetBundle and Player
10+
-- builds, but not ContentDirectory builds. See Documentation/analyzer-schema.md.
11+
object INTEGER, -- objects.id: an AssetBundle asset, a synthetic Scene, or a PreloadData object
12+
dependency INTEGER -- objects.id, or dangling_refs.id when the target was not analyzed
2813
);
2914

3015
CREATE VIEW IF NOT EXISTS assetbundle_asset_view AS
16+
-- AssetBundle assets with their object columns resolved. Inner join, so an asset whose object was
17+
-- not analyzed is omitted here but still present in assetbundle_assets.
3118
SELECT
3219
a.name AS asset_name,
3320
o.*
3421
FROM assetbundle_assets a INNER JOIN object_view o ON o.id = a.object;
3522

3623
CREATE VIEW IF NOT EXISTS preload_dependencies_view AS
24+
-- Preload dependencies of AssetBundle assets and scenes, with both sides resolved. Narrower than
25+
-- the table: Player-build rows and dangling dependencies drop out of the inner joins.
3726
SELECT a.id, a.asset_name, a.archive, a.type, od.id dep_id, od.archive dep_archive, od.name dep_name, od.type dep_type
3827
FROM assetbundle_asset_view a
3928
INNER JOIN preload_dependencies d ON a.id = d.object

‎Analyzer/Resources/ContentLayout.sql‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
-- Identity of the imported ContentLayout.json (see Documentation/contentlayout.md). The
2-
-- content_layout* tables are only created when a ContentLayout.json is part of the analyzed
3-
-- input. A single layout per database is supported.
41
CREATE TABLE IF NOT EXISTS content_layout
52
(
3+
-- Identity of the imported ContentLayout.json. The content_layout* tables exist only when a
4+
-- layout was part of the analyzed input. See Documentation/contentlayout-database.md.
65
id INTEGER, -- always 0 (single layout per database)
76
name TEXT, -- path of the imported ContentLayout.json
87
version INTEGER, -- schema version of the json file

‎Analyzer/Resources/ContentLayoutArtifactReferences.sql‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
-- Direct references between binary artifacts (ArtifactReferences in the json), e.g. a
2-
-- serialized file referencing its .resS/.resource data files. References that go through a
3-
-- loadable are not included, and the graph is never cyclical. References to other serialized
4-
-- files are not recorded here either; those are in content_layout_serialized_file_dependencies.
51
CREATE TABLE IF NOT EXISTS content_layout_artifact_references
62
(
3+
-- Direct references between binary artifacts, e.g. a content file to its .resS/.resource data
4+
-- files. Never cyclical. Content-file-to-content-file edges live in
5+
-- content_layout_serialized_file_dependencies instead.
76
artifact_index INTEGER, -- references content_layout_binary_artifacts.artifact_index
87
referenced_artifact_index INTEGER,
98
PRIMARY KEY (artifact_index, referenced_artifact_index)

‎Analyzer/Resources/ContentLayoutBinaryArtifacts.sql‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
-- The artifacts that make up the build output (BinaryArtifacts in the json): the serialized
2-
-- files themselves plus the data files they use (.resS, .resource) and the manifest. This is the
3-
-- standard place to find artifact sizes. When stored as a file the filename is the content hash
4-
-- plus an extension derived from the category (content_layout_binary_artifacts_view adds it).
51
CREATE TABLE IF NOT EXISTS content_layout_binary_artifacts
62
(
3+
-- Every artifact making up the build output: the content files plus the data files they use
4+
-- (.resS, .resource) and the manifest. The standard place to find artifact sizes.
75
artifact_index INTEGER,
8-
content_hash TEXT,
6+
content_hash TEXT, -- the on-disk filename is content_hash plus an extension from category
97
category TEXT, -- 'texture' | 'mesh' | 'audio' | 'video' | 'contentfile' | 'manifest'
108
size INTEGER,
119
PRIMARY KEY (artifact_index)

‎Analyzer/Resources/ContentLayoutIndexes.sql‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
-- Created after the content_layout tables are populated, so inserts stay fast for very large
2-
-- layouts. The content_hash and asset_path indexes carry the views; the rest serve reverse
3-
-- lookups ("who depends on X", "which loadables live in file Y").
1+
-- Created after the content_layout tables are populated so inserts stay fast for very large layouts.
42
CREATE INDEX content_layout_binary_artifacts_content_hash ON content_layout_binary_artifacts(content_hash);
53
CREATE INDEX content_layout_source_assets_asset_path ON content_layout_source_assets(asset_path);
64
CREATE INDEX content_layout_source_assets_file ON content_layout_source_assets(serialized_file_index);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
-- Loadable objects referenced from each serialized file (LoadableDependencies in the json).
21
CREATE TABLE IF NOT EXISTS content_layout_loadable_dependencies
32
(
3+
-- The loadable objects each content file references.
44
serialized_file_index INTEGER, -- references content_layout_serialized_files.file_index
55
object_id_hash TEXT -- references content_layout_loadable_objects.object_id_hash
66
);
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
-- The objects that can be loaded on demand (LoadableObjectIds in the json), identified
2-
-- independently of the serialized file that contains them. Also records where each one came from
3-
-- in the source project. The json's top-level RootAssets list is folded into the is_root_asset
4-
-- flag. serialized_file_index is NULL when the object was dropped from the build (json value -1,
5-
-- e.g. server build shader references).
61
CREATE TABLE IF NOT EXISTS content_layout_loadable_objects
72
(
3+
-- The objects that can be loaded on demand, identified independently of the content file that
4+
-- holds them, plus where each came from in the source project.
85
object_id_hash TEXT, -- hash of GUID, LFID and identifier_type
96
guid TEXT, -- AssetDatabase GUID of the source asset
107
asset_path TEXT,
118
lfid INTEGER, -- local file id of the object in the source asset
129
identifier_type INTEGER,
13-
serialized_file_index INTEGER, -- references content_layout_serialized_files.file_index, or NULL
14-
output_lfid INTEGER, -- local file id of the object in its output serialized file
10+
serialized_file_index INTEGER, -- content_layout_serialized_files.file_index; NULL if dropped from the build
11+
output_lfid INTEGER, -- local file id of the object in its output content file
1512
is_root_asset INTEGER,
1613
PRIMARY KEY (object_id_hash)
1714
);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
-- Scenes referenced from each serialized file (LoadableSceneDependencies in the json).
21
CREATE TABLE IF NOT EXISTS content_layout_loadable_scene_dependencies
32
(
3+
-- The scenes each content file references.
44
serialized_file_index INTEGER, -- references content_layout_serialized_files.file_index
55
scene_path TEXT -- matches content_layout_loadable_scenes.path
66
);

0 commit comments

Comments
 (0)