Skip to content

Commit 095defd

Browse files
committed
Add SQLite asset custom editor, scripted importer and build processor
1 parent ab319db commit 095defd

9 files changed

+240
-1
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "Gilzoide.SqliteNet.Editor",
3+
"rootNamespace": "SQLite.Editor",
4+
"references": [
5+
"GUID:17f96cd3b93974f6493e51a2f25c1241"
6+
],
7+
"includePlatforms": [],
8+
"excludePlatforms": [],
9+
"allowUnsafeCode": false,
10+
"overrideReferences": false,
11+
"precompiledReferences": [],
12+
"autoReferenced": false,
13+
"defineConstraints": [],
14+
"versionDefines": [],
15+
"noEngineReferences": false
16+
}

Editor/Gilzoide.SqliteNet.Editor.asmdef.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#if !UNITY_ANDROID && !UNITY_WEBGL
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Linq;
6+
using UnityEditor;
7+
using UnityEditor.Build;
8+
using UnityEditor.Build.Reporting;
9+
10+
namespace SQLite.Editor
11+
{
12+
public class SQLiteAssetBuildProcessor : IPreprocessBuildWithReport, IPostprocessBuildWithReport
13+
{
14+
public int callbackOrder => 0;
15+
16+
public void OnPreprocessBuild(BuildReport report)
17+
{
18+
foreach (SQLiteAsset sqliteAsset in GetAffectedAssets())
19+
{
20+
string filePath = $"Assets/StreamingAssets/{sqliteAsset.StreamingAssetsPath}";
21+
string directoryPath = Path.GetDirectoryName(filePath);
22+
if (!Directory.Exists(directoryPath))
23+
{
24+
Directory.CreateDirectory(directoryPath);
25+
}
26+
File.WriteAllBytes(filePath, sqliteAsset.Bytes);
27+
sqliteAsset.Bytes = Array.Empty<byte>();
28+
}
29+
}
30+
31+
public void OnPostprocessBuild(BuildReport report)
32+
{
33+
foreach (SQLiteAsset sqliteAsset in GetAffectedAssets())
34+
{
35+
string filePath = $"Assets/StreamingAssets/{sqliteAsset.StreamingAssetsPath}";
36+
if (File.Exists(filePath))
37+
{
38+
sqliteAsset.Bytes = File.ReadAllBytes(filePath);
39+
FileUtil.DeleteFileOrDirectory(filePath);
40+
FileUtil.DeleteFileOrDirectory(filePath + ".meta");
41+
DeleteEmptyDirectories(Path.GetDirectoryName(filePath));
42+
}
43+
}
44+
}
45+
46+
private static void DeleteEmptyDirectories(string directory)
47+
{
48+
while (!string.IsNullOrWhiteSpace(directory))
49+
{
50+
if (Directory.EnumerateFileSystemEntries(directory).Any())
51+
{
52+
return;
53+
}
54+
FileUtil.DeleteFileOrDirectory(directory);
55+
FileUtil.DeleteFileOrDirectory(directory + ".meta");
56+
directory = Path.GetDirectoryName(directory);
57+
}
58+
}
59+
60+
private static IEnumerable<SQLiteAsset> GetAffectedAssets()
61+
{
62+
return AssetDatabase.FindAssets($"t:{nameof(SQLiteAsset)}")
63+
.Select(AssetDatabase.GUIDToAssetPath)
64+
.Select(AssetDatabase.LoadAssetAtPath<SQLiteAsset>)
65+
.Where(sqlite => sqlite.UseStreamingAssets);
66+
}
67+
}
68+
}
69+
#endif

Editor/SQLiteAssetBuildProcessor.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/SQLiteAssetEditor.cs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System.Collections.Generic;
2+
using UnityEditor;
3+
using UnityEngine;
4+
5+
namespace SQLite.Editor
6+
{
7+
[CustomEditor(typeof(SQLiteAsset))]
8+
[CanEditMultipleObjects]
9+
public class SQLiteAssetEditor : UnityEditor.Editor
10+
{
11+
private class TableInfo
12+
{
13+
public string Name { get; set; }
14+
public string Sql { get; set; }
15+
16+
public void Deconstruct(out string name, out string sql)
17+
{
18+
name = Name;
19+
sql = Sql;
20+
}
21+
}
22+
23+
[SerializeField] private List<string> _expandedTables = new List<string>();
24+
25+
public override void OnInspectorGUI()
26+
{
27+
DrawDefaultInspector();
28+
EditorGUILayout.Space();
29+
30+
using (new EditorGUI.DisabledScope(true))
31+
{
32+
EditorGUILayout.TextField("Database size in bytes", EditorUtility.FormatBytes(((SQLiteAsset) target).Bytes.Length));
33+
}
34+
35+
if (serializedObject.isEditingMultipleObjects)
36+
{
37+
return;
38+
}
39+
40+
EditorGUILayout.Space();
41+
42+
using (new EditorGUI.DisabledScope(true))
43+
using (var db = ((SQLiteAsset) target).CreateConnection())
44+
{
45+
EditorGUILayout.LabelField("Tables", EditorStyles.boldLabel);
46+
EditorGUI.indentLevel++;
47+
foreach ((string name, string sql) in db.Query<TableInfo>("SELECT name, sql FROM SQLite_schema WHERE type = 'table'"))
48+
{
49+
bool previouslyExpanded = _expandedTables.Contains(name);
50+
bool expanded = EditorGUILayout.Foldout(previouslyExpanded, name, true);
51+
if (previouslyExpanded && !expanded)
52+
{
53+
_expandedTables.Remove(name);
54+
}
55+
else if (!previouslyExpanded && expanded)
56+
{
57+
_expandedTables.Add(name);
58+
}
59+
60+
if (expanded)
61+
{
62+
EditorGUILayout.TextField("SQL", sql);
63+
int count = db.ExecuteScalar<int>($"SELECT COUNT(*) FROM {SQLiteConnection.Quote(name)}");
64+
EditorGUILayout.IntField("Row Count", count);
65+
}
66+
EditorGUILayout.Space();
67+
}
68+
EditorGUI.indentLevel--;
69+
}
70+
}
71+
}
72+
}

Editor/SQLiteAssetEditor.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/SQLiteAssetImporter.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.IO;
2+
#if UNITY_2020_2_OR_NEWER
3+
using UnityEditor.AssetImporters;
4+
#else
5+
using UnityEditor.Experimental.AssetImporters;
6+
#endif
7+
using UnityEngine;
8+
9+
namespace SQLite.Editor
10+
{
11+
[ScriptedImporter(0, new[] { "sqlite", "sqlite2", "sqlite3" })]
12+
public class SQLiteAssetImporter : ScriptedImporter
13+
{
14+
[Tooltip("Flags controlling how the SQLite connection should be opened. 'ReadWrite' and 'Create' flags will be ignored, since SQLite assets are read-only.")]
15+
[SerializeField] private SQLiteOpenFlags _openFlags = SQLiteOpenFlags.ReadOnly;
16+
17+
[Tooltip("Whether to store DateTime properties as ticks (true) or strings (false).")]
18+
[SerializeField] private bool _storeDateTimeAsTicks = true;
19+
20+
[Tooltip("Name of the file created for the database inside Streaming Assets folder during builds.\n\n"
21+
+ "If empty, the database bytes will be stored in the asset itself.\n\n"
22+
+ "Loading databases from Streaming Assets is not supported in Android and WebGL platforms.")]
23+
[SerializeField] private string _streamingAssetsPath;
24+
25+
public override void OnImportAsset(AssetImportContext ctx)
26+
{
27+
var asset = ScriptableObject.CreateInstance<SQLiteAsset>();
28+
asset.OpenFlags = _openFlags;
29+
asset.StoreDateTimeAsTicks = _storeDateTimeAsTicks;
30+
asset.Bytes = File.ReadAllBytes(ctx.assetPath);
31+
asset.StreamingAssetsPath = _streamingAssetsPath;
32+
ctx.AddObjectToAsset("sqlite", asset);
33+
ctx.SetMainObject(asset);
34+
}
35+
}
36+
}

Editor/SQLiteAssetImporter.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ This package provides the excelent [SQLite-net](https://github.com/praeclarum/sq
1414
+ Enabled modules: [R\*Tree](https://sqlite.org/rtree.html), [Geopoly](https://sqlite.org/geopoly.html), [FTS5](https://sqlite.org/fts5.html), [Built-In Math Functions](https://www.sqlite.org/lang_mathfunc.html)
1515
+ Supports Windows, Linux, macOS, WebGL, Android, iOS, tvOS and visionOS platforms
1616
+ Supports persisting data in WebGL builds by using a [custom VFS backed by Indexed DB](https://github.com/gilzoide/idbvfs).
17-
17+
- [SQLiteAsset](Runtime/SQLiteAsset.cs): read-only SQLite database Unity assets.
18+
+ Files with the extensions ".sqlite", ".sqlite2" and ".sqlite3" will be imported as SQLite database assets.
19+
+ Use the `CreateConnection()` method for connecting to the database provided by the asset.
20+
Make sure to `Dispose()` of any connections you create.
21+
+ SQLite assets may be loaded from Streaming Assets folder or from memory, depending on the value of their "Streaming Assets Path" property.
22+
+ **Warning**: Android and WebGL platforms don't support loading SQLite databases from Streaming Assets and will always load them in memory.
23+
+ `SQLiteConnection.SerializeToAsset` extension method for serializing a database to an instance of `SQLiteAsset`.
1824

1925
## Optional packages
2026
- [SQLite Asset](https://github.com/gilzoide/unity-sqlite-asset): read-only SQLite database assets for Unity with scripted importer for ".sqlite", ".sqlite2" and ".sqlite3" files

0 commit comments

Comments
 (0)