├── .gitignore ├── Editor ├── Icons │ ├── solar_database-bold.png │ ├── d_solar_database-bold.png │ ├── d_solar_database-bold@2x.png │ ├── solar_database-bold@2x.png │ ├── d_solar_database-bold.png.meta │ ├── solar_database-bold.png.meta │ ├── solar_database-bold@2x.png.meta │ └── d_solar_database-bold@2x.png.meta ├── Icons.meta ├── Gilzoide.SqliteNet.Editor.asmdef.meta ├── SQLiteAssetEditor.cs.meta ├── SQLiteAssetImporter.cs.meta ├── SQLScriptTextImporter.cs.meta ├── SQLiteAssetCsvImporter.cs.meta ├── SQLScriptDatabaseImporter.cs.meta ├── SQLiteAssetBuildProcessor.cs.meta ├── Gilzoide.SqliteNet.Editor.asmdef ├── SQLScriptTextImporter.cs ├── SQLiteAssetImporter.cs ├── SQLScriptDatabaseImporter.cs ├── SQLiteAssetEditor.cs ├── SQLiteAssetBuildProcessor.cs └── SQLiteAssetCsvImporter.cs ├── .gitmodules ├── Plugins ├── lib │ ├── macos │ │ ├── libgilzoide-sqlite-net.dylib │ │ └── libgilzoide-sqlite-net.dylib.meta │ ├── windows │ │ ├── x86 │ │ │ ├── gilzoide-sqlite-net.dll │ │ │ └── gilzoide-sqlite-net.dll.meta │ │ ├── arm64 │ │ │ ├── gilzoide-sqlite-net.dll │ │ │ └── gilzoide-sqlite-net.dll.meta │ │ ├── x86_64 │ │ │ ├── gilzoide-sqlite-net.dll │ │ │ └── gilzoide-sqlite-net.dll.meta │ │ ├── x86.meta │ │ ├── arm64.meta │ │ └── x86_64.meta │ ├── android │ │ ├── arm32 │ │ │ ├── libgilzoide-sqlite-net.so │ │ │ └── libgilzoide-sqlite-net.so.meta │ │ ├── arm64 │ │ │ ├── libgilzoide-sqlite-net.so │ │ │ └── libgilzoide-sqlite-net.so.meta │ │ ├── x86 │ │ │ ├── libgilzoide-sqlite-net.so │ │ │ └── libgilzoide-sqlite-net.so.meta │ │ ├── x86_64 │ │ │ ├── libgilzoide-sqlite-net.so │ │ │ └── libgilzoide-sqlite-net.so.meta │ │ ├── x86.meta │ │ ├── arm32.meta │ │ ├── arm64.meta │ │ └── x86_64.meta │ ├── linux │ │ ├── x86_64 │ │ │ ├── libgilzoide-sqlite-net.so │ │ │ └── libgilzoide-sqlite-net.so.meta │ │ └── x86_64.meta │ ├── android.meta │ ├── linux.meta │ ├── macos.meta │ └── windows.meta ├── Makefile.meta ├── idbvfs.meta ├── lib.meta ├── sqlite-amalgamation.meta ├── tools~ │ ├── Dockerfile.build.windows │ ├── Dockerfile.build.linux │ ├── Dockerfile.build.android │ └── fix-library-path.sed ├── sqlite-amalgamation │ ├── sqlite3_defines.h │ ├── sqlite3.h.meta │ ├── sqlite3ext.h.meta │ ├── sqlite3.c.meta │ └── sqlite3_defines.h.meta ├── idbvfs │ ├── idbvfs.h │ ├── SQLiteVfs.h.meta │ ├── idbvfs.cpp.meta │ ├── idbvfs.h.meta │ └── idbvfs.cpp └── Makefile ├── CHANGELOG.md.meta ├── LICENSE.txt.meta ├── README.md.meta ├── package.json.meta ├── Editor.meta ├── Plugins.meta ├── Runtime.meta ├── Samples~ ├── REPL │ ├── SQLiteREPL.unity.meta │ ├── Gilzoide.SqliteNet.Samples.REPL.asmdef.meta │ ├── SQLiteREPL.cs.meta │ ├── Gilzoide.SqliteNet.Samples.REPL.asmdef │ └── SQLiteREPL.cs ├── REPL.meta ├── Readme │ ├── ReadmeScene.unity.meta │ ├── Gilzoide.SqliteNet.Samples.Readme.asmdef.meta │ ├── TestSqlite.cs.meta │ ├── TestSqliteAsync.cs.meta │ ├── Gilzoide.SqliteNet.Samples.Readme.asmdef │ ├── TestSqliteAsync.cs │ ├── TestSqlite.cs │ └── ReadmeScene.unity └── Readme.meta ├── Tests.meta ├── Runtime ├── Csv.meta ├── sqlite-net │ ├── LICENSE.txt.meta │ ├── SQLite.cs.meta │ ├── AssemblyInfo.cs.meta │ ├── SQLiteAsync.cs.meta │ ├── LICENSE.txt │ └── AssemblyInfo.cs ├── sqlite-net.meta ├── Gilzoide.SqliteNet.asmdef.meta ├── Csv │ ├── CsvReader.cs.meta │ ├── CsvException.cs.meta │ ├── CsvException.cs │ └── CsvReader.cs ├── SQLiteExtensions.cs.meta ├── SQLiteAsyncExtensions.cs.meta ├── SQLitePreparedStatement.cs.meta ├── SQLiteConnectionExtensions.cs.meta ├── SQLiteAsset.cs.meta ├── Gilzoide.SqliteNet.asmdef ├── SQLiteAsyncExtensions.cs ├── SQLiteAsset.cs ├── SQLiteExtensions.cs ├── SQLiteConnectionExtensions.cs └── SQLitePreparedStatement.cs ├── Tests ├── Editor.meta └── Editor │ ├── Gilzoide.SqliteNet.Tests.Editor.asmdef.meta │ ├── TestSerialization.cs.meta │ ├── Gilzoide.SqliteNet.Tests.Editor.asmdef │ └── TestSerialization.cs ├── .editorconfig ├── package.json ├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── LICENSE.txt ├── CHANGELOG.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.o~ 3 | Samples 4 | Samples.meta 5 | -------------------------------------------------------------------------------- /Editor/Icons/solar_database-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Editor/Icons/solar_database-bold.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Plugins/sqlite-net~"] 2 | path = Plugins/sqlite-net~ 3 | url = https://github.com/praeclarum/sqlite-net.git 4 | -------------------------------------------------------------------------------- /Editor/Icons/d_solar_database-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Editor/Icons/d_solar_database-bold.png -------------------------------------------------------------------------------- /Editor/Icons/d_solar_database-bold@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Editor/Icons/d_solar_database-bold@2x.png -------------------------------------------------------------------------------- /Editor/Icons/solar_database-bold@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Editor/Icons/solar_database-bold@2x.png -------------------------------------------------------------------------------- /Plugins/lib/macos/libgilzoide-sqlite-net.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/macos/libgilzoide-sqlite-net.dylib -------------------------------------------------------------------------------- /Plugins/lib/windows/x86/gilzoide-sqlite-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/windows/x86/gilzoide-sqlite-net.dll -------------------------------------------------------------------------------- /Plugins/lib/android/arm32/libgilzoide-sqlite-net.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/android/arm32/libgilzoide-sqlite-net.so -------------------------------------------------------------------------------- /Plugins/lib/android/arm64/libgilzoide-sqlite-net.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/android/arm64/libgilzoide-sqlite-net.so -------------------------------------------------------------------------------- /Plugins/lib/android/x86/libgilzoide-sqlite-net.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/android/x86/libgilzoide-sqlite-net.so -------------------------------------------------------------------------------- /Plugins/lib/linux/x86_64/libgilzoide-sqlite-net.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/linux/x86_64/libgilzoide-sqlite-net.so -------------------------------------------------------------------------------- /Plugins/lib/windows/arm64/gilzoide-sqlite-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/windows/arm64/gilzoide-sqlite-net.dll -------------------------------------------------------------------------------- /Plugins/lib/windows/x86_64/gilzoide-sqlite-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/windows/x86_64/gilzoide-sqlite-net.dll -------------------------------------------------------------------------------- /Plugins/lib/android/x86_64/libgilzoide-sqlite-net.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-sqlite-net/HEAD/Plugins/lib/android/x86_64/libgilzoide-sqlite-net.so -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 923514db601094436a73902b0d903f44 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 81cfe1728e89140d2b3246a08a7eeb6d 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 214de60a9f5c549c99ca8bb4fcd0bf66 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Plugins/Makefile.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d937f0ae4113443b78db34d7d15cd41b 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a2dcee563e67d4c1b948cbf8bde1afb6 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2247b5abd5a1c47bd9c80355cc56c5ef 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59d6228b57ea44c22bf2acc6f71ce64c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1594d2f9e43f5463da091729acbc1b73 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/REPL/SQLiteREPL.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7d2d7d986ea434563997c818daa5adcd 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ce057e534c95043f9901d01fdc94207e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Icons.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 196a203c3f399425bbfae08500a87e46 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/idbvfs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 346c87c5708c44a7bbc2987f97045ee8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 643c7bd7804e942b597f2f4a297fb3a9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Csv.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1c2a8809fb9c4735a75582f79b026d4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/sqlite-net/LICENSE.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2c88e95b456274e3d8541f961a49a403 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/REPL.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d29c71b64cea544dd9148bff92e1aef2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Readme/ReadmeScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 75d38cfd44dd34801844c333c2792f66 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Tests/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3823dd185fb194578a096eb7275d43cc 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/android.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 475700be16f36411b950cc12259f8e0a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/linux.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 806517e1ae9d2e84f994c6d6df651af0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/macos.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e2b76ac96bd85474a97ccd9fb12e4220 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/windows.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ffde8862e849e442a9c6d9e16351bdb6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/sqlite-net.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fdd42b002eaee4f7e9226d236c618bf7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Readme.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a74ef68f0c81243a8a8390c845d87291 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/android/x86.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dfb87fba928c64a5b8facb61f2e0f711 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/linux/x86_64.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 71084fb9a073785c49eb8aac28f0bbfc 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/windows/x86.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d8321f9eff864a28863a1f1dfef2889 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Gilzoide.SqliteNet.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 17f96cd3b93974f6493e51a2f25c1241 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/Gilzoide.SqliteNet.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf1b03bab81fb4dbf9f325bfe2f10d29 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Plugins/lib/android/arm32.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60c565140771d401a95a1f1850ef8d2e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/android/arm64.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bfbafd25ec1ee4915a65b807012dd5eb 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/android/x86_64.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e25ff9771419c407db33c391a0fdadd1 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/windows/arm64.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49731d4518ba8405cb4a2da9941193a7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/lib/windows/x86_64.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4a09091ccc924403392207d037cc981e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/sqlite-amalgamation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b85a4855da6cd47cfa135c60a37af8c8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/tools~/Dockerfile.build.windows: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | FROM debian:12-slim 3 | 4 | RUN apt-get -qq update \ 5 | && apt-get -qq install -y --no-install-recommends \ 6 | make \ 7 | gcc-mingw-w64-x86-64 -------------------------------------------------------------------------------- /Plugins/tools~/Dockerfile.build.linux: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | FROM debian:12-slim 3 | 4 | RUN apt-get -qq update \ 5 | && apt-get -qq install -y --no-install-recommends \ 6 | gcc \ 7 | libc-dev \ 8 | make 9 | -------------------------------------------------------------------------------- /Samples~/REPL/Gilzoide.SqliteNet.Samples.REPL.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f39f6270f92af48c98c1f10c1583e814 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Tests/Editor/Gilzoide.SqliteNet.Tests.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 116377ddbe6df44f797197063a566aaf 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Readme/Gilzoide.SqliteNet.Samples.Readme.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b059faa0c92954cce8547d7f52cb3b2a 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | insert_final_newline = true 7 | 8 | [*.{asmdef,cs}] 9 | indent_style = space 10 | indent_size = 4 11 | 12 | [*.sed~] 13 | indent_style = tab 14 | indent_size = 4 15 | 16 | [Makefile] 17 | indent_style = tab 18 | indent_size = 8 -------------------------------------------------------------------------------- /Runtime/Csv/CsvReader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6af882ccfbbe24a8fbc2c99371ea98cf 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SQLiteAssetEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b01081d2adb9418391fe28f13086bcd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SQLiteAssetImporter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a82a308980f2947468fbbb0695613ed2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Csv/CsvException.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 267285bfe909149a9842f0bc1341cf70 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SQLiteExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5efe130b84bb4bd48a419af53aaf741 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/sqlite-net/SQLite.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ba12ff0c4a47416fbd764e8214ca6c9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/REPL/SQLiteREPL.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30f9ded1ab071463d97a0f594e7084d8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Readme/TestSqlite.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6adceb403221c46bfa7c0060aaff46f1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SQLScriptTextImporter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba03993677dd740da91b9a13653538e9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SQLiteAssetCsvImporter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc7f33370e31747c8b998403bea5e202 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SQLiteAsyncExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da6b73f57890c4a9ca69e882cd03e45e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SQLitePreparedStatement.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f832e590cb784ed490bb3c248063980 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/sqlite-net/AssemblyInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5c9be88643c0c40be8577f5969655b43 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/sqlite-net/SQLiteAsync.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cad9e8fa279d240a093308d4bad79e29 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Readme/TestSqliteAsync.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9217c1d35e7f4b009d100297fd6c4f0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests/Editor/TestSerialization.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e76b1568295e54de09960443991b1a0d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SQLScriptDatabaseImporter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 73f952aa6f2394d23a56915dfa8295a2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SQLiteAssetBuildProcessor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3c72b41ff6d7a4557bc93e8c99a1ce09 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SQLiteConnectionExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30836eea2610b493c892439e371095e2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SQLiteAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f2f61d07f5f634a01b7d297f944a71ef 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {fileID: 2800000, guid: d05789d285ed2446a97f5c3f99ef13b6, type: 3} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Gilzoide.SqliteNet.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Gilzoide.SqliteNet", 3 | "rootNamespace": "SQLite", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": true, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [], 13 | "noEngineReferences": false 14 | } -------------------------------------------------------------------------------- /Samples~/REPL/Gilzoide.SqliteNet.Samples.REPL.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Gilzoide.SqliteNet.Samples.REPL", 3 | "rootNamespace": "", 4 | "references": [ 5 | "Gilzoide.SqliteNet" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": false, 13 | "defineConstraints": [], 14 | "versionDefines": [], 15 | "noEngineReferences": false 16 | } -------------------------------------------------------------------------------- /Plugins/tools~/Dockerfile.build.android: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | FROM debian:12-slim 3 | 4 | ARG NDK_VERSION=r27c 5 | 6 | RUN apt-get -qq update \ 7 | && apt-get -qq install -y --no-install-recommends \ 8 | curl \ 9 | unzip \ 10 | make 11 | RUN curl -SLO http://dl.google.com/android/repository/android-ndk-$NDK_VERSION-linux.zip 12 | RUN unzip android-ndk-$NDK_VERSION-linux.zip 13 | RUN mv ./android-ndk-$NDK_VERSION /opt/ndk 14 | RUN rm android-ndk-$NDK_VERSION-linux.zip 15 | ENV ANDROID_NDK_ROOT=/opt/ndk 16 | -------------------------------------------------------------------------------- /Editor/Gilzoide.SqliteNet.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Gilzoide.SqliteNet.Editor", 3 | "rootNamespace": "SQLite.Editor", 4 | "references": [ 5 | "GUID:17f96cd3b93974f6493e51a2f25c1241" 6 | ], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": false, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Samples~/Readme/Gilzoide.SqliteNet.Samples.Readme.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Gilzoide.SqliteNet.Samples.Readme", 3 | "rootNamespace": "Gilzoide.SqliteNet.Samples.Readme", 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 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.gilzoide.sqlite-net", 3 | "displayName": "SQLite-net", 4 | "version": "1.3.2", 5 | "description": "SQLite-net for Unity, supports Windows, Linux, macOS, iOS, tvOS, visionOS, Android and WebGL", 6 | "homepage": "https://github.com/gilzoide/unity-sqlite-net", 7 | "license": "MIT", 8 | "author": { 9 | "name": "Gil Barbosa Reis" 10 | }, 11 | "samples": [ 12 | { 13 | "displayName": "SQLite REPL", 14 | "description": "Demonstrates a simple REPL for SQL statements.", 15 | "path": "Samples~/REPL" 16 | } 17 | ], 18 | "unity": "2021.2" 19 | } 20 | -------------------------------------------------------------------------------- /Tests/Editor/Gilzoide.SqliteNet.Tests.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Gilzoide.SqliteNet.Tests.Editor", 3 | "rootNamespace": "Gilzoide.SqliteNet.Tests.Editor", 4 | "references": [ 5 | "UnityEngine.TestRunner", 6 | "UnityEditor.TestRunner", 7 | "Gilzoide.SqliteNet" 8 | ], 9 | "includePlatforms": [ 10 | "Editor" 11 | ], 12 | "excludePlatforms": [], 13 | "allowUnsafeCode": false, 14 | "overrideReferences": true, 15 | "precompiledReferences": [ 16 | "nunit.framework.dll" 17 | ], 18 | "autoReferenced": false, 19 | "defineConstraints": [ 20 | "UNITY_INCLUDE_TESTS" 21 | ], 22 | "versionDefines": [], 23 | "noEngineReferences": false 24 | } -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [gilzoide] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: gilzoide # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: gilzoide # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /Plugins/sqlite-amalgamation/sqlite3_defines.h: -------------------------------------------------------------------------------- 1 | // Compile-time definitions used to build SQLite 2 | // This is a separate file so that IL2CPP can use the same flags on all platforms 3 | // Feel free to change this based on your needs 4 | #define SQLITE_USE_URI 1 5 | #define SQLITE_DQS 0 6 | #define SQLITE_DEFAULT_MEMSTATUS 0 7 | #define SQLITE_DEFAULT_WAL_SYNCHRONOUS 1 8 | #define SQLITE_LIKE_DOESNT_MATCH_BLOBS 1 9 | #define SQLITE_MAX_EXPR_DEPTH 0 10 | #define SQLITE_OMIT_DECLTYPE 1 11 | #define SQLITE_OMIT_DEPRECATED 1 12 | #define SQLITE_OMIT_PROGRESS_CALLBACK 1 13 | #define SQLITE_OMIT_SHARED_CACHE 1 14 | #define SQLITE_USE_ALLOCA 1 15 | #define SQLITE_ENABLE_RTREE 1 16 | #define SQLITE_ENABLE_MATH_FUNCTIONS 1 17 | #define HAVE_ISNAN 1 18 | #define SQLITE_ENABLE_GEOPOLY 1 19 | #define SQLITE_ENABLE_FTS5 1 20 | #define SQLITE_ENABLE_HIDDEN_COLUMNS 1 21 | // Default temporary storage to in-memory, since TEMP databases are not encrypted 22 | #define SQLITE_TEMP_STORE 2 23 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Gil Barbosa Reis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Runtime/sqlite-net/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Krueger Systems, Inc. 2 | 3 | All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Runtime/sqlite-net/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("SQLite-net Official Portable Library")] 10 | [assembly: AssemblyDescription("Light weight library providing easy SQLite database storage")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("Krueger Systems, Inc.")] 13 | [assembly: AssemblyProduct("SQLite-net")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | [assembly: NeutralResourcesLanguage("en")] 17 | 18 | // Version information for an assembly consists of the following four values: 19 | // 20 | // Major Version 21 | // Minor Version 22 | // Build Number 23 | // Revision 24 | // 25 | // You can specify all the values or you can default the Build and Revision Numbers 26 | // by using the '*' as shown below: 27 | // [assembly: AssemblyVersion("1.0.*")] 28 | [assembly: AssemblyVersion("1.0.0.0")] 29 | [assembly: AssemblyFileVersion("1.0.0.0")] 30 | -------------------------------------------------------------------------------- /Runtime/Csv/CsvException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System; 23 | 24 | namespace SQLite.Csv 25 | { 26 | public class CsvException : Exception 27 | { 28 | public CsvException(string message) : base(message) {} 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Plugins/tools~/fix-library-path.sed: -------------------------------------------------------------------------------- 1 | /const string LibraryPath/ { 2 | # Make LibraryPath public 3 | s/const string/public const string/ 4 | # Rename native library "sqlite3" -> "gilzoide-sqlite-net" 5 | s/sqlite3/gilzoide-sqlite-net/ 6 | # Use "__Internal" library path in WebGL builds 7 | i\ 8 | #if !UNITY_EDITOR && (UNITY_WEBGL || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS) 9 | i\ 10 | public const string LibraryPath = "__Internal"; 11 | i\ 12 | #else 13 | a\ 14 | #endif 15 | } 16 | 17 | # Fix constrain `sqlite3_win32*` functions to Windows only 18 | # This avoids breaking IL2CPP builds with managed stripping level set to Minimal 19 | /sqlite3_win32_/ { 20 | i\ 21 | #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN 22 | n 23 | a\ 24 | #endif 25 | } 26 | 27 | # Make Quote function public, for libraries making raw queries 28 | s/static string Quote/public static string Quote/ 29 | 30 | # Make SQLite3 class partial, to extend in another file 31 | s/class SQLite3/partial class SQLite3/ 32 | 33 | # Make column attributes inherit Unity's PreserveAttribute 34 | # This fixes managed code stripping removing getter/setter methods 35 | s/public class (Column|PrimaryKey|AutoIncrement|Indexed|MaxLength|Collation|NotNull|StoreAsText)Attribute : Attribute/public class \1Attribute : UnityEngine.Scripting.PreserveAttribute/ 36 | 37 | # Use main thread TaskScheduler in WebGL 38 | s/TaskScheduler\.Default/SQLiteAsyncExtensions.TaskScheduler/ 39 | 40 | # Disable fast setters when ObjectType is struct 41 | s/cols\[i] != null/!typeof(T).IsValueType \&\& cols[i] != null/ 42 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build native libraries 2 | on: [push, pull_request] 3 | defaults: 4 | run: 5 | shell: bash 6 | 7 | env: 8 | DOCKER_CACHE: ${{ github.workspace }}/.docker-cache 9 | 10 | jobs: 11 | build_with_docker: 12 | name: ${{ matrix.platform }} 13 | runs-on: ubuntu-latest 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | include: 18 | - platform: windows 19 | target: docker-all-windows-llvm 20 | - platform: linux 21 | target: docker-all-linux 22 | - platform: android 23 | target: docker-all-android 24 | steps: 25 | - uses: actions/checkout@v3 26 | - name: Cache Docker files 27 | uses: actions/cache@v4 28 | with: 29 | path: $DOCKER_CACHE 30 | key: ${{ matrix.platform }} 31 | - name: Build 32 | run: make -C Plugins ${{ matrix.target }} DOCKER_BUILD_ARGS="--cache-from type=gha --cache-to type=gha,mode=max" 33 | - name: Upload artifact 34 | uses: actions/upload-artifact@v4 35 | with: 36 | name: gilzoide-sqlite-net-${{ matrix.platform }} 37 | path: | 38 | Plugins/lib/${{ matrix.platform }}/**/*.dll 39 | Plugins/lib/${{ matrix.platform }}/**/*.dylib 40 | Plugins/lib/${{ matrix.platform }}/**/*.so 41 | 42 | build_with_macos: 43 | name: macOS 44 | runs-on: macos-latest 45 | steps: 46 | - uses: actions/checkout@v3 47 | - name: Build 48 | run: make -C Plugins all-apple 49 | - name: Upload artifact 50 | uses: actions/upload-artifact@v4 51 | with: 52 | name: gilzoide-sqlite-net-macos 53 | path: | 54 | Plugins/lib/macos/*.dylib 55 | -------------------------------------------------------------------------------- /Editor/SQLScriptTextImporter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System.IO; 23 | using UnityEditor.AssetImporters; 24 | using UnityEngine; 25 | 26 | namespace SQLite.Editor 27 | { 28 | [ScriptedImporter(0, "sql")] 29 | public class SQLScriptTextImporter : ScriptedImporter 30 | { 31 | public override void OnImportAsset(AssetImportContext ctx) 32 | { 33 | string contents = File.ReadAllText(assetPath); 34 | TextAsset asset = new(contents); 35 | ctx.AddObjectToAsset("main", asset); 36 | ctx.SetMainObject(asset); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Plugins/lib/macos/libgilzoide-sqlite-net.dylib.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ac500925e8a7402fabca3baf4eca437 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 0 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 0 23 | Exclude WebGL: 1 24 | Exclude Win: 1 25 | Exclude Win64: 1 26 | Exclude iOS: 1 27 | - first: 28 | Android: Android 29 | second: 30 | enabled: 0 31 | settings: 32 | AndroidSharedLibraryType: Executable 33 | CPU: ARMv7 34 | - first: 35 | Any: 36 | second: 37 | enabled: 0 38 | settings: {} 39 | - first: 40 | Editor: Editor 41 | second: 42 | enabled: 1 43 | settings: 44 | CPU: AnyCPU 45 | DefaultValueInitialized: true 46 | OS: OSX 47 | - first: 48 | Standalone: Linux64 49 | second: 50 | enabled: 0 51 | settings: 52 | CPU: AnyCPU 53 | - first: 54 | Standalone: OSXUniversal 55 | second: 56 | enabled: 1 57 | settings: 58 | CPU: AnyCPU 59 | - first: 60 | Standalone: Win 61 | second: 62 | enabled: 0 63 | settings: 64 | CPU: AnyCPU 65 | - first: 66 | Standalone: Win64 67 | second: 68 | enabled: 0 69 | settings: 70 | CPU: AnyCPU 71 | - first: 72 | iPhone: iOS 73 | second: 74 | enabled: 0 75 | settings: 76 | AddToEmbeddedBinaries: false 77 | CPU: AnyCPU 78 | CompileFlags: 79 | FrameworkDependencies: 80 | userData: 81 | assetBundleName: 82 | assetBundleVariant: 83 | -------------------------------------------------------------------------------- /Plugins/sqlite-amalgamation/sqlite3.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bd619249260364d7c9e09aa0015418e6 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 0 24 | Exclude WebGL: 0 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 0 28 | Exclude tvOS: 0 29 | - first: 30 | Any: 31 | second: 32 | enabled: 0 33 | settings: {} 34 | - first: 35 | Editor: Editor 36 | second: 37 | enabled: 0 38 | settings: 39 | DefaultValueInitialized: true 40 | - first: 41 | Standalone: Linux64 42 | second: 43 | enabled: 0 44 | settings: 45 | CPU: None 46 | - first: 47 | Standalone: OSXUniversal 48 | second: 49 | enabled: 0 50 | settings: 51 | CPU: None 52 | - first: 53 | Standalone: Win 54 | second: 55 | enabled: 0 56 | settings: 57 | CPU: None 58 | - first: 59 | Standalone: Win64 60 | second: 61 | enabled: 0 62 | settings: 63 | CPU: None 64 | - first: 65 | VisionOS: VisionOS 66 | second: 67 | enabled: 1 68 | settings: {} 69 | - first: 70 | WebGL: WebGL 71 | second: 72 | enabled: 1 73 | settings: {} 74 | - first: 75 | iPhone: iOS 76 | second: 77 | enabled: 1 78 | settings: {} 79 | - first: 80 | tvOS: tvOS 81 | second: 82 | enabled: 1 83 | settings: {} 84 | userData: 85 | assetBundleName: 86 | assetBundleVariant: 87 | -------------------------------------------------------------------------------- /Plugins/sqlite-amalgamation/sqlite3ext.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcb4567f69dc44be68b6b71003de7ee8 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 0 24 | Exclude WebGL: 0 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 0 28 | Exclude tvOS: 0 29 | - first: 30 | Any: 31 | second: 32 | enabled: 0 33 | settings: {} 34 | - first: 35 | Editor: Editor 36 | second: 37 | enabled: 0 38 | settings: 39 | DefaultValueInitialized: true 40 | - first: 41 | Standalone: Linux64 42 | second: 43 | enabled: 0 44 | settings: 45 | CPU: None 46 | - first: 47 | Standalone: OSXUniversal 48 | second: 49 | enabled: 0 50 | settings: 51 | CPU: None 52 | - first: 53 | Standalone: Win 54 | second: 55 | enabled: 0 56 | settings: 57 | CPU: None 58 | - first: 59 | Standalone: Win64 60 | second: 61 | enabled: 0 62 | settings: 63 | CPU: None 64 | - first: 65 | VisionOS: VisionOS 66 | second: 67 | enabled: 1 68 | settings: {} 69 | - first: 70 | WebGL: WebGL 71 | second: 72 | enabled: 1 73 | settings: {} 74 | - first: 75 | iPhone: iOS 76 | second: 77 | enabled: 1 78 | settings: {} 79 | - first: 80 | tvOS: tvOS 81 | second: 82 | enabled: 1 83 | settings: {} 84 | userData: 85 | assetBundleName: 86 | assetBundleVariant: 87 | -------------------------------------------------------------------------------- /Plugins/idbvfs/idbvfs.h: -------------------------------------------------------------------------------- 1 | /** @file idbvfs.h 2 | * 3 | * SQLite VFS that stores data in web browser's Indexed DB using Emscripten. 4 | */ 5 | /* 6 | * This is free and unencumbered software released into the public domain. 7 | * 8 | * Anyone is free to copy, modify, publish, use, compile, sell, or 9 | * distribute this software, either in source code form or as a compiled 10 | * binary, for any purpose, commercial or non-commercial, and by any 11 | * means. 12 | * 13 | * In jurisdictions that recognize copyright laws, the author or authors 14 | * of this software dedicate any and all copyright interest in the 15 | * software to the public domain. We make this dedication for the benefit 16 | * of the public at large and to the detriment of our heirs and 17 | * successors. We intend this dedication to be an overt act of 18 | * relinquishment in perpetuity of all present and future rights to this 19 | * software under copyright law. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 | * OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | * For more information, please refer to 30 | */ 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | /** 36 | * String containing idbvfs name. 37 | */ 38 | extern const char *IDBVFS_NAME; 39 | 40 | /** 41 | * Registers idbvfs in SQLite 3. 42 | * 43 | * @param makeDefault Whether idbvfs will be the new default VFS. 44 | * @return Return value from `sqlite3_vfs_register` 45 | * @see https://sqlite.org/c3ref/vfs_find.html 46 | */ 47 | int idbvfs_register(int makeDefault); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /Plugins/lib/windows/arm64/gilzoide-sqlite-net.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b53346b6b4b8438d8d3d69a36f38fc4 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 0 21 | Exclude Linux64: 0 22 | Exclude OSXUniversal: 0 23 | Exclude WebGL: 1 24 | Exclude Win: 1 25 | Exclude Win64: 0 26 | Exclude WindowsStoreApps: 0 27 | - first: 28 | Android: Android 29 | second: 30 | enabled: 0 31 | settings: 32 | AndroidSharedLibraryType: Executable 33 | CPU: ARMv7 34 | - first: 35 | Any: 36 | second: 37 | enabled: 0 38 | settings: {} 39 | - first: 40 | Editor: Editor 41 | second: 42 | enabled: 1 43 | settings: 44 | CPU: ARM64 45 | DefaultValueInitialized: true 46 | OS: Windows 47 | - first: 48 | Standalone: Linux64 49 | second: 50 | enabled: 1 51 | settings: 52 | CPU: AnyCPU 53 | - first: 54 | Standalone: OSXUniversal 55 | second: 56 | enabled: 1 57 | settings: 58 | CPU: AnyCPU 59 | - first: 60 | Standalone: Win 61 | second: 62 | enabled: 0 63 | settings: 64 | CPU: AnyCPU 65 | - first: 66 | Standalone: Win64 67 | second: 68 | enabled: 1 69 | settings: 70 | CPU: ARM64 71 | - first: 72 | Windows Store Apps: WindowsStoreApps 73 | second: 74 | enabled: 1 75 | settings: 76 | CPU: ARM64 77 | DontProcess: false 78 | PlaceholderPath: 79 | SDK: AnySDK 80 | ScriptingBackend: AnyScriptingBackend 81 | userData: 82 | assetBundleName: 83 | assetBundleVariant: -------------------------------------------------------------------------------- /Runtime/SQLiteAsyncExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System.Threading.Tasks; 23 | using UnityEngine; 24 | 25 | namespace SQLite 26 | { 27 | public static class SQLiteAsyncExtensions 28 | { 29 | #if UNITY_WEBGL 30 | // WebGL builds cannot use background threads, so use a 31 | // TaskScheduler that executes tasks on Unity's main thread. 32 | public static TaskScheduler TaskScheduler { get; private set; } 33 | 34 | [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] 35 | private static void InitializeTaskScheduler() 36 | { 37 | TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 38 | } 39 | #else 40 | // On all other platforms, use the default TaskScheduler 41 | public static TaskScheduler TaskScheduler => TaskScheduler.Default; 42 | #endif 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Samples~/Readme/TestSqliteAsync.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | using UnityEngine; 3 | 4 | namespace Gilzoide.SqliteNet.Samples.Readme 5 | { 6 | public class TestSqliteAsync : MonoBehaviour 7 | { 8 | async void Start() 9 | { 10 | // 1. Create a connection to the database. 11 | // The special ":memory:" in-memory database and 12 | // URIs like "file:///somefile" are also supported 13 | var path = $"{Application.persistentDataPath}/MyDb.db"; 14 | Debug.Log($"Opening database '{path}'"); 15 | var db = new SQLiteAsyncConnection(path); 16 | 17 | // 2. Once you have defined your entity, you can automatically 18 | // generate tables in your database by calling CreateTableAsync 19 | await db.CreateTableAsync(); 20 | 21 | // 3. You can insert rows in the database using InsertAsync 22 | // The Insert call fills Id, which is marked with [AutoIncremented] 23 | var newPlayer = new Player 24 | { 25 | Name = "gilzoide", 26 | }; 27 | await db.InsertAsync(newPlayer); 28 | Debug.Log($"Player new ID: {newPlayer.Id}"); 29 | // Similar methods exist for Update and Delete. 30 | 31 | // 4.a The most straightforward way to query for data 32 | // is using the Table method. This can take predicates 33 | // for constraining via WHERE clauses and/or adding ORDER BY clauses 34 | var query = await db.Table().Where(p => p.Name.StartsWith("g")).ToListAsync(); 35 | foreach (Player player in query) 36 | { 37 | Debug.Log($"Found player named {player.Name} with ID {player.Id}"); 38 | } 39 | 40 | // 4.b You can also make queries at a low-level using the QueryAsync method 41 | var players = await db.QueryAsync("SELECT * FROM Player WHERE Id = ?", 1); 42 | foreach (Player player in players) 43 | { 44 | Debug.Log($"Player with ID 1 is called {player.Name}"); 45 | } 46 | 47 | // 5. You can perform low-level updates to the database using the 48 | // ExecuteAsync method, for example for running PRAGMAs or VACUUM 49 | await db.ExecuteAsync("VACUUM"); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Plugins/lib/linux/x86_64/libgilzoide-sqlite-net.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5ad070f93c93bc05afd06384d710b49 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 0 21 | Exclude Linux64: 0 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 1 25 | Exclude Win: 0 26 | Exclude Win64: 0 27 | Exclude iOS: 1 28 | Exclude tvOS: 1 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 0 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: ARMv7 36 | - first: 37 | Any: 38 | second: 39 | enabled: 0 40 | settings: {} 41 | - first: 42 | Editor: Editor 43 | second: 44 | enabled: 1 45 | settings: 46 | CPU: x86_64 47 | DefaultValueInitialized: true 48 | OS: Linux 49 | - first: 50 | Standalone: Linux64 51 | second: 52 | enabled: 1 53 | settings: 54 | CPU: AnyCPU 55 | - first: 56 | Standalone: OSXUniversal 57 | second: 58 | enabled: 0 59 | settings: 60 | CPU: AnyCPU 61 | - first: 62 | Standalone: Win 63 | second: 64 | enabled: 1 65 | settings: 66 | CPU: AnyCPU 67 | - first: 68 | Standalone: Win64 69 | second: 70 | enabled: 1 71 | settings: 72 | CPU: AnyCPU 73 | - first: 74 | VisionOS: VisionOS 75 | second: 76 | enabled: 0 77 | settings: 78 | AddToEmbeddedBinaries: false 79 | CPU: ARM64 80 | CompileFlags: 81 | FrameworkDependencies: 82 | - first: 83 | iPhone: iOS 84 | second: 85 | enabled: 0 86 | settings: 87 | AddToEmbeddedBinaries: false 88 | CPU: AnyCPU 89 | CompileFlags: 90 | FrameworkDependencies: 91 | - first: 92 | tvOS: tvOS 93 | second: 94 | enabled: 0 95 | settings: 96 | CPU: AnyCPU 97 | CompileFlags: 98 | FrameworkDependencies: 99 | userData: 100 | assetBundleName: 101 | assetBundleVariant: 102 | -------------------------------------------------------------------------------- /Plugins/lib/android/arm64/libgilzoide-sqlite-net.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 087f5264fe8f3450f8b0e9fd5c0f52d8 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 0 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 1 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 1 28 | Exclude tvOS: 1 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 1 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: ARM64 36 | Is16KbAligned: true 37 | - first: 38 | Any: 39 | second: 40 | enabled: 0 41 | settings: {} 42 | - first: 43 | Editor: Editor 44 | second: 45 | enabled: 0 46 | settings: 47 | CPU: AnyCPU 48 | DefaultValueInitialized: true 49 | OS: AnyOS 50 | - first: 51 | Standalone: Linux64 52 | second: 53 | enabled: 0 54 | settings: 55 | CPU: None 56 | - first: 57 | Standalone: OSXUniversal 58 | second: 59 | enabled: 0 60 | settings: 61 | CPU: None 62 | - first: 63 | Standalone: Win 64 | second: 65 | enabled: 0 66 | settings: 67 | CPU: None 68 | - first: 69 | Standalone: Win64 70 | second: 71 | enabled: 0 72 | settings: 73 | CPU: None 74 | - first: 75 | VisionOS: VisionOS 76 | second: 77 | enabled: 0 78 | settings: 79 | AddToEmbeddedBinaries: false 80 | CPU: ARM64 81 | CompileFlags: 82 | FrameworkDependencies: 83 | - first: 84 | iPhone: iOS 85 | second: 86 | enabled: 0 87 | settings: 88 | AddToEmbeddedBinaries: false 89 | CPU: AnyCPU 90 | CompileFlags: 91 | FrameworkDependencies: 92 | - first: 93 | tvOS: tvOS 94 | second: 95 | enabled: 0 96 | settings: 97 | CPU: AnyCPU 98 | CompileFlags: 99 | FrameworkDependencies: 100 | userData: 101 | assetBundleName: 102 | assetBundleVariant: 103 | -------------------------------------------------------------------------------- /Plugins/lib/android/x86/libgilzoide-sqlite-net.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0af503a9536c24d738fdf908dfb115eb 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 0 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 1 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 1 28 | Exclude tvOS: 1 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 1 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: X86 36 | Is16KbAligned: false 37 | - first: 38 | Any: 39 | second: 40 | enabled: 0 41 | settings: {} 42 | - first: 43 | Editor: Editor 44 | second: 45 | enabled: 0 46 | settings: 47 | CPU: AnyCPU 48 | DefaultValueInitialized: true 49 | OS: AnyOS 50 | - first: 51 | Standalone: Linux64 52 | second: 53 | enabled: 0 54 | settings: 55 | CPU: None 56 | - first: 57 | Standalone: OSXUniversal 58 | second: 59 | enabled: 0 60 | settings: 61 | CPU: None 62 | - first: 63 | Standalone: Win 64 | second: 65 | enabled: 0 66 | settings: 67 | CPU: None 68 | - first: 69 | Standalone: Win64 70 | second: 71 | enabled: 0 72 | settings: 73 | CPU: None 74 | - first: 75 | VisionOS: VisionOS 76 | second: 77 | enabled: 0 78 | settings: 79 | AddToEmbeddedBinaries: false 80 | CPU: ARM64 81 | CompileFlags: 82 | FrameworkDependencies: 83 | - first: 84 | iPhone: iOS 85 | second: 86 | enabled: 0 87 | settings: 88 | AddToEmbeddedBinaries: false 89 | CPU: AnyCPU 90 | CompileFlags: 91 | FrameworkDependencies: 92 | - first: 93 | tvOS: tvOS 94 | second: 95 | enabled: 0 96 | settings: 97 | CPU: AnyCPU 98 | CompileFlags: 99 | FrameworkDependencies: 100 | userData: 101 | assetBundleName: 102 | assetBundleVariant: 103 | -------------------------------------------------------------------------------- /Plugins/lib/android/arm32/libgilzoide-sqlite-net.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57126b2d3bafb46e5a7a4ece8eb4d9f8 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 0 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 1 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 1 28 | Exclude tvOS: 1 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 1 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: ARMv7 36 | Is16KbAligned: false 37 | - first: 38 | Any: 39 | second: 40 | enabled: 0 41 | settings: {} 42 | - first: 43 | Editor: Editor 44 | second: 45 | enabled: 0 46 | settings: 47 | CPU: AnyCPU 48 | DefaultValueInitialized: true 49 | OS: AnyOS 50 | - first: 51 | Standalone: Linux64 52 | second: 53 | enabled: 0 54 | settings: 55 | CPU: None 56 | - first: 57 | Standalone: OSXUniversal 58 | second: 59 | enabled: 0 60 | settings: 61 | CPU: None 62 | - first: 63 | Standalone: Win 64 | second: 65 | enabled: 0 66 | settings: 67 | CPU: None 68 | - first: 69 | Standalone: Win64 70 | second: 71 | enabled: 0 72 | settings: 73 | CPU: None 74 | - first: 75 | VisionOS: VisionOS 76 | second: 77 | enabled: 0 78 | settings: 79 | AddToEmbeddedBinaries: false 80 | CPU: ARM64 81 | CompileFlags: 82 | FrameworkDependencies: 83 | - first: 84 | iPhone: iOS 85 | second: 86 | enabled: 0 87 | settings: 88 | AddToEmbeddedBinaries: false 89 | CPU: AnyCPU 90 | CompileFlags: 91 | FrameworkDependencies: 92 | - first: 93 | tvOS: tvOS 94 | second: 95 | enabled: 0 96 | settings: 97 | CPU: AnyCPU 98 | CompileFlags: 99 | FrameworkDependencies: 100 | userData: 101 | assetBundleName: 102 | assetBundleVariant: 103 | -------------------------------------------------------------------------------- /Plugins/lib/android/x86_64/libgilzoide-sqlite-net.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 31ad6577221064c96a1a580ff407e1a2 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 0 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 1 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 1 28 | Exclude tvOS: 1 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 1 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: X86_64 36 | Is16KbAligned: true 37 | - first: 38 | Any: 39 | second: 40 | enabled: 0 41 | settings: {} 42 | - first: 43 | Editor: Editor 44 | second: 45 | enabled: 0 46 | settings: 47 | CPU: AnyCPU 48 | DefaultValueInitialized: true 49 | OS: AnyOS 50 | - first: 51 | Standalone: Linux64 52 | second: 53 | enabled: 0 54 | settings: 55 | CPU: None 56 | - first: 57 | Standalone: OSXUniversal 58 | second: 59 | enabled: 0 60 | settings: 61 | CPU: None 62 | - first: 63 | Standalone: Win 64 | second: 65 | enabled: 0 66 | settings: 67 | CPU: None 68 | - first: 69 | Standalone: Win64 70 | second: 71 | enabled: 0 72 | settings: 73 | CPU: None 74 | - first: 75 | VisionOS: VisionOS 76 | second: 77 | enabled: 0 78 | settings: 79 | AddToEmbeddedBinaries: false 80 | CPU: ARM64 81 | CompileFlags: 82 | FrameworkDependencies: 83 | - first: 84 | iPhone: iOS 85 | second: 86 | enabled: 0 87 | settings: 88 | AddToEmbeddedBinaries: false 89 | CPU: AnyCPU 90 | CompileFlags: 91 | FrameworkDependencies: 92 | - first: 93 | tvOS: tvOS 94 | second: 95 | enabled: 0 96 | settings: 97 | CPU: AnyCPU 98 | CompileFlags: 99 | FrameworkDependencies: 100 | userData: 101 | assetBundleName: 102 | assetBundleVariant: 103 | -------------------------------------------------------------------------------- /Samples~/Readme/TestSqlite.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | using UnityEngine; 3 | 4 | namespace Gilzoide.SqliteNet.Samples.Readme 5 | { 6 | // The library contains simple attributes that you can use 7 | // to control the construction of tables, ORM style 8 | public class Player 9 | { 10 | [PrimaryKey, AutoIncrement] 11 | public int Id { get; set; } 12 | public string Name { get; set; } 13 | } 14 | 15 | public class TestSqlite : MonoBehaviour 16 | { 17 | void Start() 18 | { 19 | // 1. Create a connection to the database. 20 | // The special ":memory:" in-memory database and 21 | // URIs like "file:///somefile" are also supported 22 | var path = $"{Application.persistentDataPath}/MyDb.db"; 23 | Debug.Log($"Opening database '{path}'"); 24 | var db = new SQLiteConnection(path); 25 | 26 | // 2. Once you have defined your entity, you can automatically 27 | // generate tables in your database by calling CreateTable 28 | db.CreateTable(); 29 | 30 | // 3. You can insert rows in the database using Insert 31 | // The Insert call fills Id, which is marked with [AutoIncremented] 32 | var newPlayer = new Player 33 | { 34 | Name = "gilzoide", 35 | }; 36 | db.Insert(newPlayer); 37 | Debug.Log($"Player new ID: {newPlayer.Id}"); 38 | // Similar methods exist for Update and Delete. 39 | 40 | // 4.a The most straightforward way to query for data 41 | // is using the Table method. This can take predicates 42 | // for constraining via WHERE clauses and/or adding ORDER BY clauses 43 | var query = db.Table().Where(p => p.Name.StartsWith("g")); 44 | foreach (Player player in query) 45 | { 46 | Debug.Log($"Found player named {player.Name} with ID {player.Id}"); 47 | } 48 | 49 | // 4.b You can also make queries at a low-level using the Query method 50 | var players = db.Query("SELECT * FROM Player WHERE Id = ?", 1); 51 | foreach (Player player in players) 52 | { 53 | Debug.Log($"Player with ID 1 is called {player.Name}"); 54 | } 55 | 56 | // 5. You can perform low-level updates to the database using the Execute 57 | // method, for example for running PRAGMAs or VACUUM 58 | db.Execute("VACUUM"); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Plugins/idbvfs/SQLiteVfs.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aac1512bc2fa0445fbef81428fd172e6 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 0 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 1 28 | Exclude tvOS: 1 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 0 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: ARMv7 36 | - first: 37 | Any: 38 | second: 39 | enabled: 0 40 | settings: {} 41 | - first: 42 | Editor: Editor 43 | second: 44 | enabled: 0 45 | settings: 46 | CPU: AnyCPU 47 | DefaultValueInitialized: true 48 | OS: AnyOS 49 | - first: 50 | Standalone: Linux64 51 | second: 52 | enabled: 0 53 | settings: 54 | CPU: None 55 | - first: 56 | Standalone: OSXUniversal 57 | second: 58 | enabled: 0 59 | settings: 60 | CPU: None 61 | - first: 62 | Standalone: Win 63 | second: 64 | enabled: 0 65 | settings: 66 | CPU: None 67 | - first: 68 | Standalone: Win64 69 | second: 70 | enabled: 0 71 | settings: 72 | CPU: None 73 | - first: 74 | VisionOS: VisionOS 75 | second: 76 | enabled: 0 77 | settings: 78 | AddToEmbeddedBinaries: false 79 | CPU: ARM64 80 | CompileFlags: 81 | FrameworkDependencies: 82 | - first: 83 | WebGL: WebGL 84 | second: 85 | enabled: 1 86 | settings: {} 87 | - first: 88 | iPhone: iOS 89 | second: 90 | enabled: 0 91 | settings: 92 | AddToEmbeddedBinaries: false 93 | CPU: AnyCPU 94 | CompileFlags: 95 | FrameworkDependencies: 96 | - first: 97 | tvOS: tvOS 98 | second: 99 | enabled: 0 100 | settings: 101 | CPU: AnyCPU 102 | CompileFlags: 103 | FrameworkDependencies: 104 | userData: 105 | assetBundleName: 106 | assetBundleVariant: 107 | -------------------------------------------------------------------------------- /Plugins/idbvfs/idbvfs.cpp.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33b221fa6bef54ac996317b3a8ab2021 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 0 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 1 28 | Exclude tvOS: 1 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 0 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: ARMv7 36 | - first: 37 | Any: 38 | second: 39 | enabled: 0 40 | settings: {} 41 | - first: 42 | Editor: Editor 43 | second: 44 | enabled: 0 45 | settings: 46 | CPU: AnyCPU 47 | DefaultValueInitialized: true 48 | OS: AnyOS 49 | - first: 50 | Standalone: Linux64 51 | second: 52 | enabled: 0 53 | settings: 54 | CPU: None 55 | - first: 56 | Standalone: OSXUniversal 57 | second: 58 | enabled: 0 59 | settings: 60 | CPU: None 61 | - first: 62 | Standalone: Win 63 | second: 64 | enabled: 0 65 | settings: 66 | CPU: None 67 | - first: 68 | Standalone: Win64 69 | second: 70 | enabled: 0 71 | settings: 72 | CPU: None 73 | - first: 74 | VisionOS: VisionOS 75 | second: 76 | enabled: 0 77 | settings: 78 | AddToEmbeddedBinaries: false 79 | CPU: ARM64 80 | CompileFlags: 81 | FrameworkDependencies: 82 | - first: 83 | WebGL: WebGL 84 | second: 85 | enabled: 1 86 | settings: {} 87 | - first: 88 | iPhone: iOS 89 | second: 90 | enabled: 0 91 | settings: 92 | AddToEmbeddedBinaries: false 93 | CPU: AnyCPU 94 | CompileFlags: 95 | FrameworkDependencies: 96 | - first: 97 | tvOS: tvOS 98 | second: 99 | enabled: 0 100 | settings: 101 | CPU: AnyCPU 102 | CompileFlags: 103 | FrameworkDependencies: 104 | userData: 105 | assetBundleName: 106 | assetBundleVariant: 107 | -------------------------------------------------------------------------------- /Plugins/idbvfs/idbvfs.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 714e36bffffff4eeca3e5b12e47510eb 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 0 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 1 28 | Exclude tvOS: 1 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 0 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: ARMv7 36 | - first: 37 | Any: 38 | second: 39 | enabled: 0 40 | settings: {} 41 | - first: 42 | Editor: Editor 43 | second: 44 | enabled: 0 45 | settings: 46 | CPU: AnyCPU 47 | DefaultValueInitialized: true 48 | OS: AnyOS 49 | - first: 50 | Standalone: Linux64 51 | second: 52 | enabled: 0 53 | settings: 54 | CPU: None 55 | - first: 56 | Standalone: OSXUniversal 57 | second: 58 | enabled: 0 59 | settings: 60 | CPU: None 61 | - first: 62 | Standalone: Win 63 | second: 64 | enabled: 0 65 | settings: 66 | CPU: None 67 | - first: 68 | Standalone: Win64 69 | second: 70 | enabled: 0 71 | settings: 72 | CPU: None 73 | - first: 74 | VisionOS: VisionOS 75 | second: 76 | enabled: 0 77 | settings: 78 | AddToEmbeddedBinaries: false 79 | CPU: ARM64 80 | CompileFlags: 81 | FrameworkDependencies: 82 | - first: 83 | WebGL: WebGL 84 | second: 85 | enabled: 1 86 | settings: {} 87 | - first: 88 | iPhone: iOS 89 | second: 90 | enabled: 0 91 | settings: 92 | AddToEmbeddedBinaries: false 93 | CPU: AnyCPU 94 | CompileFlags: 95 | FrameworkDependencies: 96 | - first: 97 | tvOS: tvOS 98 | second: 99 | enabled: 0 100 | settings: 101 | CPU: AnyCPU 102 | CompileFlags: 103 | FrameworkDependencies: 104 | userData: 105 | assetBundleName: 106 | assetBundleVariant: 107 | -------------------------------------------------------------------------------- /Plugins/sqlite-amalgamation/sqlite3.c.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f4aecd216a78400d96ff7b4a39f0627 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 0 24 | Exclude WebGL: 0 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 0 28 | Exclude tvOS: 0 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 0 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: ARMv7 36 | - first: 37 | Any: 38 | second: 39 | enabled: 0 40 | settings: {} 41 | - first: 42 | Editor: Editor 43 | second: 44 | enabled: 0 45 | settings: 46 | CPU: AnyCPU 47 | DefaultValueInitialized: true 48 | OS: AnyOS 49 | - first: 50 | Standalone: Linux64 51 | second: 52 | enabled: 0 53 | settings: 54 | CPU: None 55 | - first: 56 | Standalone: OSXUniversal 57 | second: 58 | enabled: 0 59 | settings: 60 | CPU: None 61 | - first: 62 | Standalone: Win 63 | second: 64 | enabled: 0 65 | settings: 66 | CPU: None 67 | - first: 68 | Standalone: Win64 69 | second: 70 | enabled: 0 71 | settings: 72 | CPU: None 73 | - first: 74 | VisionOS: VisionOS 75 | second: 76 | enabled: 1 77 | settings: 78 | AddToEmbeddedBinaries: false 79 | CPU: ARM64 80 | CompileFlags: 81 | FrameworkDependencies: 82 | - first: 83 | WebGL: WebGL 84 | second: 85 | enabled: 1 86 | settings: {} 87 | - first: 88 | iPhone: iOS 89 | second: 90 | enabled: 1 91 | settings: 92 | AddToEmbeddedBinaries: false 93 | CPU: AnyCPU 94 | CompileFlags: 95 | FrameworkDependencies: 96 | - first: 97 | tvOS: tvOS 98 | second: 99 | enabled: 1 100 | settings: 101 | AddToEmbeddedBinaries: false 102 | CPU: AnyCPU 103 | CompileFlags: 104 | FrameworkDependencies: 105 | userData: 106 | assetBundleName: 107 | assetBundleVariant: 108 | -------------------------------------------------------------------------------- /Plugins/sqlite-amalgamation/sqlite3_defines.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 437dfc5ab03b74410aea0f06ebc8467b 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude VisionOS: 0 24 | Exclude WebGL: 0 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 0 28 | Exclude tvOS: 0 29 | - first: 30 | Android: Android 31 | second: 32 | enabled: 0 33 | settings: 34 | AndroidSharedLibraryType: Executable 35 | CPU: ARMv7 36 | - first: 37 | Any: 38 | second: 39 | enabled: 0 40 | settings: {} 41 | - first: 42 | Editor: Editor 43 | second: 44 | enabled: 0 45 | settings: 46 | CPU: AnyCPU 47 | DefaultValueInitialized: true 48 | OS: AnyOS 49 | - first: 50 | Standalone: Linux64 51 | second: 52 | enabled: 0 53 | settings: 54 | CPU: None 55 | - first: 56 | Standalone: OSXUniversal 57 | second: 58 | enabled: 0 59 | settings: 60 | CPU: None 61 | - first: 62 | Standalone: Win 63 | second: 64 | enabled: 0 65 | settings: 66 | CPU: None 67 | - first: 68 | Standalone: Win64 69 | second: 70 | enabled: 0 71 | settings: 72 | CPU: None 73 | - first: 74 | VisionOS: VisionOS 75 | second: 76 | enabled: 1 77 | settings: 78 | AddToEmbeddedBinaries: false 79 | CPU: AnyCPU 80 | CompileFlags: 81 | FrameworkDependencies: 82 | - first: 83 | WebGL: WebGL 84 | second: 85 | enabled: 1 86 | settings: {} 87 | - first: 88 | iPhone: iOS 89 | second: 90 | enabled: 1 91 | settings: 92 | AddToEmbeddedBinaries: false 93 | CPU: AnyCPU 94 | CompileFlags: 95 | FrameworkDependencies: 96 | - first: 97 | tvOS: tvOS 98 | second: 99 | enabled: 1 100 | settings: 101 | AddToEmbeddedBinaries: false 102 | CPU: AnyCPU 103 | CompileFlags: 104 | FrameworkDependencies: 105 | userData: 106 | assetBundleName: 107 | assetBundleVariant: 108 | -------------------------------------------------------------------------------- /Editor/SQLiteAssetImporter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System.IO; 23 | using UnityEditor.AssetImporters; 24 | using UnityEngine; 25 | 26 | namespace SQLite.Editor 27 | { 28 | [ScriptedImporter(0, new[] { "sqlite", "sqlite2", "sqlite3" })] 29 | public class SQLiteAssetImporter : ScriptedImporter 30 | { 31 | [Tooltip("Flags controlling how the SQLite connection should be opened. 'ReadWrite' and 'Create' flags will be ignored, since SQLite assets are read-only.")] 32 | [SerializeField] private SQLiteOpenFlags _openFlags = SQLiteOpenFlags.ReadOnly; 33 | 34 | [Tooltip("Whether to store DateTime properties as ticks (true) or strings (false).")] 35 | [SerializeField] private bool _storeDateTimeAsTicks = true; 36 | 37 | [Tooltip("Name of the file created for the database inside Streaming Assets folder during builds.\n\n" 38 | + "If empty, the database bytes will be stored in the asset itself.\n\n" 39 | + "Loading databases from Streaming Assets is not supported in Android and WebGL platforms.")] 40 | [SerializeField] private string _streamingAssetsPath; 41 | 42 | public override void OnImportAsset(AssetImportContext ctx) 43 | { 44 | var asset = ScriptableObject.CreateInstance(); 45 | asset.OpenFlags = _openFlags; 46 | asset.StoreDateTimeAsTicks = _storeDateTimeAsTicks; 47 | asset.Bytes = File.ReadAllBytes(ctx.assetPath); 48 | asset.StreamingAssetsPath = _streamingAssetsPath; 49 | ctx.AddObjectToAsset("sqlite", asset); 50 | ctx.SetMainObject(asset); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Tests/Editor/TestSerialization.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using NUnit.Framework; 23 | using SQLite; 24 | 25 | namespace Gilzoide.SqliteNet.Tests.Editor 26 | { 27 | public class TestSerialization 28 | { 29 | private class Row 30 | { 31 | [PrimaryKey] 32 | public int Id { get; set; } 33 | public int Value { get; set; } 34 | } 35 | 36 | [Test, TestCase(100)] 37 | public void TestSQLiteSerialization(int quantity) 38 | { 39 | byte[] serializedDatabase; 40 | using(var db = new SQLiteConnection("")) 41 | { 42 | db.CreateTable(); 43 | for (int i = 0; i < quantity; i++) 44 | { 45 | int added = db.Insert(new Row 46 | { 47 | Id = i, 48 | Value = i, 49 | }); 50 | Assert.That(added, Is.EqualTo(1)); 51 | } 52 | serializedDatabase = db.Serialize(); 53 | } 54 | Assert.That(serializedDatabase, Is.Not.Null); 55 | 56 | using(var db = new SQLiteConnection("")) 57 | { 58 | db.Deserialize(serializedDatabase, flags: SQLite3.DeserializeFlags.ReadOnly); 59 | for (int i = 0; i < quantity; i++) 60 | { 61 | Row row = db.Table().Where(r => r.Id == i).FirstOrDefault(); 62 | Assert.That(row, Is.Not.Null, $"Couldn't find row {i}"); 63 | Assert.That(row.Id, Is.EqualTo(row.Value)); 64 | } 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Plugins/lib/windows/x86/gilzoide-sqlite-net.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e350d0232f7f0422daaad868e5e48077 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 1 21 | Exclude Linux64: 0 22 | Exclude OSXUniversal: 0 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 1 25 | Exclude Win: 0 26 | Exclude Win64: 1 27 | Exclude WindowsStoreApps: 0 28 | Exclude iOS: 1 29 | Exclude tvOS: 1 30 | - first: 31 | Android: Android 32 | second: 33 | enabled: 0 34 | settings: 35 | AndroidSharedLibraryType: Executable 36 | CPU: ARMv7 37 | - first: 38 | Any: 39 | second: 40 | enabled: 0 41 | settings: {} 42 | - first: 43 | Editor: Editor 44 | second: 45 | enabled: 0 46 | settings: 47 | CPU: AnyCPU 48 | DefaultValueInitialized: true 49 | OS: AnyOS 50 | - first: 51 | Standalone: Linux64 52 | second: 53 | enabled: 1 54 | settings: 55 | CPU: AnyCPU 56 | - first: 57 | Standalone: OSXUniversal 58 | second: 59 | enabled: 1 60 | settings: 61 | CPU: AnyCPU 62 | - first: 63 | Standalone: Win 64 | second: 65 | enabled: 1 66 | settings: 67 | CPU: AnyCPU 68 | - first: 69 | Standalone: Win64 70 | second: 71 | enabled: 0 72 | settings: 73 | CPU: AnyCPU 74 | - first: 75 | VisionOS: VisionOS 76 | second: 77 | enabled: 0 78 | settings: 79 | AddToEmbeddedBinaries: false 80 | CPU: ARM64 81 | CompileFlags: 82 | FrameworkDependencies: 83 | - first: 84 | Windows Store Apps: WindowsStoreApps 85 | second: 86 | enabled: 1 87 | settings: 88 | CPU: X86 89 | DontProcess: false 90 | PlaceholderPath: 91 | SDK: AnySDK 92 | ScriptingBackend: AnyScriptingBackend 93 | - first: 94 | iPhone: iOS 95 | second: 96 | enabled: 0 97 | settings: 98 | AddToEmbeddedBinaries: false 99 | CPU: AnyCPU 100 | CompileFlags: 101 | FrameworkDependencies: 102 | - first: 103 | tvOS: tvOS 104 | second: 105 | enabled: 0 106 | settings: 107 | CPU: AnyCPU 108 | CompileFlags: 109 | FrameworkDependencies: 110 | userData: 111 | assetBundleName: 112 | assetBundleVariant: 113 | -------------------------------------------------------------------------------- /Plugins/lib/windows/x86_64/gilzoide-sqlite-net.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 93d2b1d9e859c496e83bc487cf09cf57 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 0 21 | Exclude Linux64: 0 22 | Exclude OSXUniversal: 0 23 | Exclude VisionOS: 1 24 | Exclude WebGL: 1 25 | Exclude Win: 1 26 | Exclude Win64: 0 27 | Exclude WindowsStoreApps: 0 28 | Exclude iOS: 1 29 | Exclude tvOS: 1 30 | - first: 31 | Android: Android 32 | second: 33 | enabled: 0 34 | settings: 35 | AndroidSharedLibraryType: Executable 36 | CPU: ARMv7 37 | - first: 38 | Any: 39 | second: 40 | enabled: 0 41 | settings: {} 42 | - first: 43 | Editor: Editor 44 | second: 45 | enabled: 1 46 | settings: 47 | CPU: x86_64 48 | DefaultValueInitialized: true 49 | OS: Windows 50 | - first: 51 | Standalone: Linux64 52 | second: 53 | enabled: 1 54 | settings: 55 | CPU: AnyCPU 56 | - first: 57 | Standalone: OSXUniversal 58 | second: 59 | enabled: 1 60 | settings: 61 | CPU: AnyCPU 62 | - first: 63 | Standalone: Win 64 | second: 65 | enabled: 0 66 | settings: 67 | CPU: AnyCPU 68 | - first: 69 | Standalone: Win64 70 | second: 71 | enabled: 1 72 | settings: 73 | CPU: AnyCPU 74 | - first: 75 | VisionOS: VisionOS 76 | second: 77 | enabled: 0 78 | settings: 79 | AddToEmbeddedBinaries: false 80 | CPU: ARM64 81 | CompileFlags: 82 | FrameworkDependencies: 83 | - first: 84 | Windows Store Apps: WindowsStoreApps 85 | second: 86 | enabled: 1 87 | settings: 88 | CPU: X64 89 | DontProcess: false 90 | PlaceholderPath: 91 | SDK: AnySDK 92 | ScriptingBackend: AnyScriptingBackend 93 | - first: 94 | iPhone: iOS 95 | second: 96 | enabled: 0 97 | settings: 98 | AddToEmbeddedBinaries: false 99 | CPU: AnyCPU 100 | CompileFlags: 101 | FrameworkDependencies: 102 | - first: 103 | tvOS: tvOS 104 | second: 105 | enabled: 0 106 | settings: 107 | CPU: AnyCPU 108 | CompileFlags: 109 | FrameworkDependencies: 110 | userData: 111 | assetBundleName: 112 | assetBundleVariant: 113 | -------------------------------------------------------------------------------- /Editor/SQLScriptDatabaseImporter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System.IO; 23 | using UnityEditor.AssetImporters; 24 | using UnityEngine; 25 | 26 | namespace SQLite.Editor 27 | { 28 | [ScriptedImporter(0, null, new[] { "sql" })] 29 | public class SQLScriptDatabaseImporter : ScriptedImporter 30 | { 31 | [Header("SQLite asset options")] 32 | [Tooltip("Flags controlling how the SQLite connection should be opened. 'ReadWrite' and 'Create' flags will be ignored, since SQLite assets are read-only.")] 33 | [SerializeField] private SQLiteOpenFlags _openFlags = SQLiteOpenFlags.ReadOnly; 34 | 35 | [Tooltip("Whether to store DateTime properties as ticks (true) or strings (false).")] 36 | [SerializeField] private bool _storeDateTimeAsTicks = true; 37 | 38 | [Tooltip("Name of the file created for the database inside Streaming Assets folder during builds.\n\n" 39 | + "If empty, the database bytes will be stored in the asset itself.\n\n" 40 | + "Loading databases from Streaming Assets is not supported in Android and WebGL platforms.")] 41 | [SerializeField] private string _streamingAssetsPath; 42 | 43 | public override void OnImportAsset(AssetImportContext ctx) 44 | { 45 | SQLiteAsset asset; 46 | using (var tempDb = new SQLiteConnection("")) 47 | { 48 | string contents = File.ReadAllText(assetPath); 49 | tempDb.ExecuteScript(contents); 50 | asset = tempDb.SerializeToAsset(null, _openFlags, _storeDateTimeAsTicks, _streamingAssetsPath); 51 | } 52 | ctx.AddObjectToAsset("main", asset); 53 | ctx.SetMainObject(asset); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Editor/SQLiteAssetEditor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System.Collections.Generic; 23 | using UnityEditor; 24 | using UnityEngine; 25 | 26 | namespace SQLite.Editor 27 | { 28 | [CustomEditor(typeof(SQLiteAsset))] 29 | [CanEditMultipleObjects] 30 | public class SQLiteAssetEditor : UnityEditor.Editor 31 | { 32 | [SerializeField] private List _expandedTables = new List(); 33 | 34 | public override void OnInspectorGUI() 35 | { 36 | DrawDefaultInspector(); 37 | if (serializedObject.isEditingMultipleObjects) 38 | { 39 | return; 40 | } 41 | 42 | EditorGUILayout.Space(); 43 | using (new EditorGUI.DisabledScope(true)) 44 | { 45 | EditorGUILayout.TextField("Database size in bytes", EditorUtility.FormatBytes(((SQLiteAsset) target).Bytes.Length)); 46 | } 47 | 48 | EditorGUILayout.Space(); 49 | using (new EditorGUI.DisabledScope(true)) 50 | using (var db = ((SQLiteAsset) target).CreateConnection()) 51 | { 52 | EditorGUILayout.LabelField("Tables", EditorStyles.boldLabel); 53 | EditorGUI.indentLevel++; 54 | foreach ((string name, string sql) in db.Query<(string, string)>("SELECT name, sql FROM SQLite_schema WHERE type = 'table'")) 55 | { 56 | bool previouslyExpanded = _expandedTables.Contains(name); 57 | bool expanded = EditorGUILayout.Foldout(previouslyExpanded, name, true); 58 | if (previouslyExpanded && !expanded) 59 | { 60 | _expandedTables.Remove(name); 61 | } 62 | else if (!previouslyExpanded && expanded) 63 | { 64 | _expandedTables.Add(name); 65 | } 66 | 67 | if (expanded) 68 | { 69 | EditorGUILayout.TextField("SQL", sql); 70 | int count = db.ExecuteScalar($"SELECT COUNT(*) FROM {SQLiteConnection.Quote(name)}"); 71 | EditorGUILayout.IntField("Row Count", count); 72 | } 73 | EditorGUILayout.Space(); 74 | } 75 | EditorGUI.indentLevel--; 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Samples~/REPL/SQLiteREPL.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System; 23 | using System.IO; 24 | using System.Text; 25 | using SQLite; 26 | using UnityEngine; 27 | using UnityEngine.UI; 28 | 29 | namespace Gilzoide.SqliteNet.Samples.REPL 30 | { 31 | public class SQLiteREPL : MonoBehaviour 32 | { 33 | public string DbName = "SQLiteREPL.sqlite"; 34 | public Text OutputText; 35 | 36 | private SQLiteConnection _connection; 37 | 38 | void Start() 39 | { 40 | string path = Path.IsPathRooted(DbName) ? DbName : Path.Join(Application.persistentDataPath, DbName); 41 | _connection = new SQLiteConnection(path); 42 | } 43 | 44 | void OnDestroy() 45 | { 46 | _connection?.Dispose(); 47 | } 48 | 49 | public void OnSubmitSQL(string sql) 50 | { 51 | DateTime timeBefore = DateTime.Now; 52 | try 53 | { 54 | using (var stmt = new SQLitePreparedStatement(_connection, sql)) 55 | { 56 | var sb = new StringBuilder(); 57 | sb.Append(string.Join("|", stmt.EnumerateColumnNames())); 58 | if (sb.Length > 0) 59 | { 60 | sb.Append('\n'); 61 | for (int i = 0, count = sb.Length; i < count; i++) 62 | { 63 | sb.Append('-'); 64 | } 65 | } 66 | while (true) 67 | { 68 | switch (stmt.Step()) 69 | { 70 | case SQLite3.Result.Row: 71 | { 72 | sb.Append('\n'); 73 | sb.Append(string.Join("|", stmt.EnumerateColumnsAsText())); 74 | break; 75 | } 76 | 77 | case SQLite3.Result.Done: 78 | goto breakwhile; 79 | } 80 | } 81 | breakwhile: 82 | OutputText.text = sb.Length > 0 ? sb.ToString() : "OK"; 83 | } 84 | } 85 | catch (SQLiteException ex) 86 | { 87 | OutputText.text = "Error: " + ex.Message; 88 | } 89 | 90 | DateTime timeAfter = DateTime.Now; 91 | TimeSpan timeSpent = timeAfter - timeBefore; 92 | OutputText.text += $"\n\nTook: {timeSpent.TotalMilliseconds}ms"; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Editor/SQLiteAssetBuildProcessor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | #if !UNITY_ANDROID && !UNITY_WEBGL 23 | using System; 24 | using System.Collections.Generic; 25 | using System.IO; 26 | using System.Linq; 27 | using UnityEditor; 28 | using UnityEditor.Build; 29 | using UnityEditor.Build.Reporting; 30 | 31 | namespace SQLite.Editor 32 | { 33 | public class SQLiteAssetBuildProcessor : IPreprocessBuildWithReport, IPostprocessBuildWithReport 34 | { 35 | public int callbackOrder => 0; 36 | 37 | public void OnPreprocessBuild(BuildReport report) 38 | { 39 | foreach (SQLiteAsset sqliteAsset in GetAffectedAssets()) 40 | { 41 | string filePath = $"Assets/StreamingAssets/{sqliteAsset.StreamingAssetsPath}"; 42 | string directoryPath = Path.GetDirectoryName(filePath); 43 | if (!Directory.Exists(directoryPath)) 44 | { 45 | Directory.CreateDirectory(directoryPath); 46 | } 47 | File.WriteAllBytes(filePath, sqliteAsset.Bytes); 48 | sqliteAsset.Bytes = Array.Empty(); 49 | } 50 | } 51 | 52 | public void OnPostprocessBuild(BuildReport report) 53 | { 54 | foreach (SQLiteAsset sqliteAsset in GetAffectedAssets()) 55 | { 56 | string filePath = $"Assets/StreamingAssets/{sqliteAsset.StreamingAssetsPath}"; 57 | if (File.Exists(filePath)) 58 | { 59 | sqliteAsset.Bytes = File.ReadAllBytes(filePath); 60 | FileUtil.DeleteFileOrDirectory(filePath); 61 | FileUtil.DeleteFileOrDirectory(filePath + ".meta"); 62 | DeleteEmptyDirectories(Path.GetDirectoryName(filePath)); 63 | } 64 | } 65 | } 66 | 67 | private static void DeleteEmptyDirectories(string directory) 68 | { 69 | while (!string.IsNullOrWhiteSpace(directory)) 70 | { 71 | if (Directory.EnumerateFileSystemEntries(directory).Any()) 72 | { 73 | return; 74 | } 75 | FileUtil.DeleteFileOrDirectory(directory); 76 | FileUtil.DeleteFileOrDirectory(directory + ".meta"); 77 | directory = Path.GetDirectoryName(directory); 78 | } 79 | } 80 | 81 | private static IEnumerable GetAffectedAssets() 82 | { 83 | return AssetDatabase.FindAssets($"t:{nameof(SQLiteAsset)}") 84 | .Select(AssetDatabase.GUIDToAssetPath) 85 | .Select(AssetDatabase.LoadAssetAtPath) 86 | .Where(sqlite => sqlite.UseStreamingAssets); 87 | } 88 | } 89 | } 90 | #endif 91 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | ## [Unreleased](https://github.com/gilzoide/unity-sqlite-net/compare/1.3.2...HEAD) 3 | 4 | 5 | ## [1.3.2](https://github.com/gilzoide/unity-sqlite-net/tree/1.3.2) 6 | ### Fixed 7 | - Warning about Android libraries not being aligned to 16kb page size 8 | 9 | 10 | ## [1.3.1](https://github.com/gilzoide/unity-sqlite-net/tree/1.3.1) 11 | ### Fixed 12 | - Mark editor asmdef as editor-only 13 | 14 | 15 | ## [1.3.0](https://github.com/gilzoide/unity-sqlite-net/tree/1.3.0) 16 | ### Added 17 | - Support for encrypting / decrypting databases by using [SQLite3 Multiple Ciphers](https://utelle.github.io/SQLite3MultipleCiphers/) implementation 18 | - [SQLiteAsset](Runtime/SQLiteAsset.cs): read-only SQLite database Unity assets. 19 | Files with the extensions ".sqlite", ".sqlite2" and ".sqlite3" will be imported as SQLite database assets. 20 | ".csv" files can be imported as SQLite database assets by changing the importer to `SQLite.Editor.Csv.SQLiteAssetCsvImporter` in the Inspector. 21 | - `SQLiteConnection.SerializeToAsset` extension method for serializing a database to an instance of `SQLiteAsset`. 22 | - `SQLiteConnection.ImportCsvToTable` extension method for importing a CSV text stream as a new table inside the database. 23 | - Support for importing ".sql" files as either a `TextAsset` or a `SQLiteAsset`. 24 | - `SQLiteConnection.ExecuteScript` extension method for executing a SQL script with multiple statements with a single call. 25 | 26 | ### Changed 27 | - Update SQLite to 3.50.1 28 | - Update NDK version used to build Android binaries to r27c 29 | - Specify minimum macOS version to 11.0 when building dylib 30 | - Minimal Unity version required by this package is now 2021.2 31 | 32 | 33 | ## [1.2.4](https://github.com/gilzoide/unity-sqlite-net/tree/1.2.4) 34 | ### Fixed 35 | - Crash when used in the Unity Editor in Linux platform 36 | 37 | 38 | ## [1.2.3](https://github.com/gilzoide/unity-sqlite-net/tree/1.2.3) 39 | ### Fixed 40 | - Support for Android 15 devices using 16KB memory page size (reference: https://developer.android.com/guide/practices/page-sizes) 41 | 42 | 43 | ## [1.2.2](https://github.com/gilzoide/unity-sqlite-net/tree/1.2.2) 44 | ### Changed 45 | - Updated SQLite to 3.49.0 46 | - Compile SQLite from source in WebGL platform 47 | 48 | ### Fixed 49 | - Support for WebGL builds with any native build configuration 50 | - Make all column-related attributes inherit Unity's `PreserveAttribute`, avoiding properties being stripped from builds 51 | 52 | 53 | ## [1.2.1](https://github.com/gilzoide/unity-sqlite-net/tree/1.2.1) 54 | ### Added 55 | - Add support for updating a struct passed to `Insert` with overload accepting `ref T` 56 | 57 | ### Fixed 58 | - Support for struct return types in queries 59 | 60 | 61 | ## [1.2.0](https://github.com/gilzoide/unity-sqlite-net/tree/1.2.0) 62 | ### Added 63 | - GitHub Action that builds all native libraries 64 | - Support for macOS with Intel CPU 65 | 66 | ### Changed 67 | - Updated SQLite to 3.48.0 68 | - Updated SQLite-net to v1.9.172 69 | 70 | 71 | ## [1.1.2](https://github.com/gilzoide/unity-sqlite-net/tree/1.1.2) 72 | ### Fixed 73 | - Support for the async API in WebGL platform 74 | 75 | 76 | ## [1.1.1](https://github.com/gilzoide/unity-sqlite-net/tree/1.1.1) 77 | ### Fixed 78 | - "duplicate column name" errors on `CreateTable` on builds with managed code stripping enabled 79 | 80 | 81 | ## [1.1.0](https://github.com/gilzoide/unity-sqlite-net/tree/1.1.0) 82 | ### Added 83 | - Support for persisting data in WebGL builds using idbvfs 84 | - SQLiteREPL sample 85 | - SQLitePreparedStatement class, a low-level wrapper for `sqlite3_stmt` 86 | - Support for code signing macOS shared library from Makefile 87 | 88 | ### Changed 89 | - Updated SQLite to 3.46.1 90 | - Change version of Emscripten used from latest to 1.40.1, so that the plugin works in Unity versions below 2021.2 91 | 92 | ### Fixed 93 | - Remove usage of `--platform` on Dockerfile to work with newer versions of Docker 94 | 95 | 96 | ## [1.0.1](https://github.com/gilzoide/unity-sqlite-net/tree/1.0.1) 97 | ### Changed 98 | - License first-party code under the MIT license 99 | 100 | 101 | ## [1.0.0](https://github.com/gilzoide/unity-sqlite-net/tree/1.0.0) 102 | ### Added 103 | - SQLite 3.45.2, prebuilt for Windows, Linux, macOS, Android and WebGL, and built from source in iOS, tvOS and visionOS 104 | - SQLite-net v1.8.116, both sync and async APIs 105 | - `SQLiteConnection.Serialize` and `SQLiteConnection.Deserialize` extension methods 106 | -------------------------------------------------------------------------------- /Editor/SQLiteAssetCsvImporter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System.IO; 23 | using SQLite.Csv; 24 | using UnityEditor.AssetImporters; 25 | using UnityEngine; 26 | 27 | namespace SQLite.Editor 28 | { 29 | [ScriptedImporter(0, null, new[] { "csv" })] 30 | public class SQLiteAssetCsvImporter : ScriptedImporter 31 | { 32 | [Header("SQLite asset options")] 33 | [Tooltip("Name of the table that will be created for holding the CSV data inside the database.")] 34 | [SerializeField] private string _tableName = "data"; 35 | 36 | [Tooltip("Flags controlling how the SQLite connection should be opened. 'ReadWrite' and 'Create' flags will be ignored, since SQLite assets are read-only.")] 37 | [SerializeField] private SQLiteOpenFlags _openFlags = SQLiteOpenFlags.ReadOnly; 38 | 39 | [Tooltip("Whether to store DateTime properties as ticks (true) or strings (false).")] 40 | [SerializeField] private bool _storeDateTimeAsTicks = true; 41 | 42 | [Tooltip("Name of the file created for the database inside Streaming Assets folder during builds.\n\n" 43 | + "If empty, the database bytes will be stored in the asset itself.\n\n" 44 | + "Loading databases from Streaming Assets is not supported in Android and WebGL platforms.")] 45 | [SerializeField] private string _streamingAssetsPath; 46 | 47 | 48 | [Header("CSV options")] 49 | [Tooltip("Which separator character will be used when parsing the CSV file.")] 50 | [SerializeField] private CsvReader.SeparatorChar _CSVSeparator = CsvReader.SeparatorChar.Comma; 51 | 52 | [Tooltip("If true, the original CSV file will also be imported as a TextAsset")] 53 | [SerializeField] private bool _importCSVTextAsset = false; 54 | 55 | [Header("Additional SQL")] 56 | [Tooltip("SQL script that will be run before reading CSV data. Use this for configuring the generated database using PRAGMAs like 'page_size'.")] 57 | [SerializeField, Multiline] private string _SQLBeforeReadingCSV = ""; 58 | 59 | [Tooltip("SQL script that will be run after reading CSV data. Use this for changing the table's schema, creating indices, etc.")] 60 | [SerializeField, Multiline] private string _SQLAfterReadingCSV = ""; 61 | 62 | public override void OnImportAsset(AssetImportContext ctx) 63 | { 64 | SQLiteAsset asset; 65 | using (var tempDb = new SQLiteConnection("")) 66 | using (var file = File.OpenRead(assetPath)) 67 | using (var stream = new StreamReader(file)) 68 | { 69 | if (!string.IsNullOrWhiteSpace(_SQLBeforeReadingCSV)) 70 | { 71 | tempDb.Execute(_SQLBeforeReadingCSV); 72 | } 73 | tempDb.ImportCsvToTable(_tableName, stream, _CSVSeparator); 74 | if (!string.IsNullOrWhiteSpace(_SQLAfterReadingCSV)) 75 | { 76 | tempDb.Execute(_SQLAfterReadingCSV); 77 | } 78 | 79 | asset = tempDb.SerializeToAsset(null, _openFlags, _storeDateTimeAsTicks, _streamingAssetsPath); 80 | } 81 | ctx.AddObjectToAsset("sqlite", asset); 82 | ctx.SetMainObject(asset); 83 | 84 | if (_importCSVTextAsset) 85 | { 86 | var textAsset = new TextAsset(File.ReadAllText(assetPath)) 87 | { 88 | name = $"{Path.GetFileNameWithoutExtension(assetPath)}", 89 | }; 90 | ctx.AddObjectToAsset("text", textAsset); 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Editor/Icons/d_solar_database-bold.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 73dc51d7e8228432bad9736cede37eb6 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 2 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 0 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 3 84 | buildTarget: WebGL 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | - serializedVersion: 3 97 | buildTarget: Standalone 98 | maxTextureSize: 2048 99 | resizeAlgorithm: 0 100 | textureFormat: -1 101 | textureCompression: 1 102 | compressionQuality: 50 103 | crunchedCompression: 0 104 | allowsAlphaSplitting: 0 105 | overridden: 0 106 | ignorePlatformSupport: 0 107 | androidETC2FallbackOverride: 0 108 | forceMaximumCompressionQuality_BC6H_BC7: 0 109 | - serializedVersion: 3 110 | buildTarget: iPhone 111 | maxTextureSize: 2048 112 | resizeAlgorithm: 0 113 | textureFormat: -1 114 | textureCompression: 1 115 | compressionQuality: 50 116 | crunchedCompression: 0 117 | allowsAlphaSplitting: 0 118 | overridden: 0 119 | ignorePlatformSupport: 0 120 | androidETC2FallbackOverride: 0 121 | forceMaximumCompressionQuality_BC6H_BC7: 0 122 | - serializedVersion: 3 123 | buildTarget: Android 124 | maxTextureSize: 2048 125 | resizeAlgorithm: 0 126 | textureFormat: -1 127 | textureCompression: 1 128 | compressionQuality: 50 129 | crunchedCompression: 0 130 | allowsAlphaSplitting: 0 131 | overridden: 0 132 | ignorePlatformSupport: 0 133 | androidETC2FallbackOverride: 0 134 | forceMaximumCompressionQuality_BC6H_BC7: 0 135 | - serializedVersion: 3 136 | buildTarget: Server 137 | maxTextureSize: 2048 138 | resizeAlgorithm: 0 139 | textureFormat: -1 140 | textureCompression: 1 141 | compressionQuality: 50 142 | crunchedCompression: 0 143 | allowsAlphaSplitting: 0 144 | overridden: 0 145 | ignorePlatformSupport: 0 146 | androidETC2FallbackOverride: 0 147 | forceMaximumCompressionQuality_BC6H_BC7: 0 148 | - serializedVersion: 3 149 | buildTarget: VisionOS 150 | maxTextureSize: 2048 151 | resizeAlgorithm: 0 152 | textureFormat: -1 153 | textureCompression: 1 154 | compressionQuality: 50 155 | crunchedCompression: 0 156 | allowsAlphaSplitting: 0 157 | overridden: 0 158 | ignorePlatformSupport: 0 159 | androidETC2FallbackOverride: 0 160 | forceMaximumCompressionQuality_BC6H_BC7: 0 161 | - serializedVersion: 3 162 | buildTarget: tvOS 163 | maxTextureSize: 2048 164 | resizeAlgorithm: 0 165 | textureFormat: -1 166 | textureCompression: 1 167 | compressionQuality: 50 168 | crunchedCompression: 0 169 | allowsAlphaSplitting: 0 170 | overridden: 0 171 | ignorePlatformSupport: 0 172 | androidETC2FallbackOverride: 0 173 | forceMaximumCompressionQuality_BC6H_BC7: 0 174 | spriteSheet: 175 | serializedVersion: 2 176 | sprites: [] 177 | outline: [] 178 | physicsShape: [] 179 | bones: [] 180 | spriteID: 5e97eb03825dee720800000000000000 181 | internalID: 0 182 | vertices: [] 183 | indices: 184 | edges: [] 185 | weights: [] 186 | secondaryTextures: [] 187 | nameFileIdTable: {} 188 | mipmapLimitGroupName: 189 | pSDRemoveMatte: 0 190 | userData: 191 | assetBundleName: 192 | assetBundleVariant: 193 | -------------------------------------------------------------------------------- /Editor/Icons/solar_database-bold.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d05789d285ed2446a97f5c3f99ef13b6 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 2 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 0 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 3 84 | buildTarget: WebGL 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | - serializedVersion: 3 97 | buildTarget: Standalone 98 | maxTextureSize: 2048 99 | resizeAlgorithm: 0 100 | textureFormat: -1 101 | textureCompression: 1 102 | compressionQuality: 50 103 | crunchedCompression: 0 104 | allowsAlphaSplitting: 0 105 | overridden: 0 106 | ignorePlatformSupport: 0 107 | androidETC2FallbackOverride: 0 108 | forceMaximumCompressionQuality_BC6H_BC7: 0 109 | - serializedVersion: 3 110 | buildTarget: iPhone 111 | maxTextureSize: 2048 112 | resizeAlgorithm: 0 113 | textureFormat: -1 114 | textureCompression: 1 115 | compressionQuality: 50 116 | crunchedCompression: 0 117 | allowsAlphaSplitting: 0 118 | overridden: 0 119 | ignorePlatformSupport: 0 120 | androidETC2FallbackOverride: 0 121 | forceMaximumCompressionQuality_BC6H_BC7: 0 122 | - serializedVersion: 3 123 | buildTarget: Android 124 | maxTextureSize: 2048 125 | resizeAlgorithm: 0 126 | textureFormat: -1 127 | textureCompression: 1 128 | compressionQuality: 50 129 | crunchedCompression: 0 130 | allowsAlphaSplitting: 0 131 | overridden: 0 132 | ignorePlatformSupport: 0 133 | androidETC2FallbackOverride: 0 134 | forceMaximumCompressionQuality_BC6H_BC7: 0 135 | - serializedVersion: 3 136 | buildTarget: Server 137 | maxTextureSize: 2048 138 | resizeAlgorithm: 0 139 | textureFormat: -1 140 | textureCompression: 1 141 | compressionQuality: 50 142 | crunchedCompression: 0 143 | allowsAlphaSplitting: 0 144 | overridden: 0 145 | ignorePlatformSupport: 0 146 | androidETC2FallbackOverride: 0 147 | forceMaximumCompressionQuality_BC6H_BC7: 0 148 | - serializedVersion: 3 149 | buildTarget: VisionOS 150 | maxTextureSize: 2048 151 | resizeAlgorithm: 0 152 | textureFormat: -1 153 | textureCompression: 1 154 | compressionQuality: 50 155 | crunchedCompression: 0 156 | allowsAlphaSplitting: 0 157 | overridden: 0 158 | ignorePlatformSupport: 0 159 | androidETC2FallbackOverride: 0 160 | forceMaximumCompressionQuality_BC6H_BC7: 0 161 | - serializedVersion: 3 162 | buildTarget: tvOS 163 | maxTextureSize: 2048 164 | resizeAlgorithm: 0 165 | textureFormat: -1 166 | textureCompression: 1 167 | compressionQuality: 50 168 | crunchedCompression: 0 169 | allowsAlphaSplitting: 0 170 | overridden: 0 171 | ignorePlatformSupport: 0 172 | androidETC2FallbackOverride: 0 173 | forceMaximumCompressionQuality_BC6H_BC7: 0 174 | spriteSheet: 175 | serializedVersion: 2 176 | sprites: [] 177 | outline: [] 178 | physicsShape: [] 179 | bones: [] 180 | spriteID: 5e97eb03825dee720800000000000000 181 | internalID: 0 182 | vertices: [] 183 | indices: 184 | edges: [] 185 | weights: [] 186 | secondaryTextures: [] 187 | nameFileIdTable: {} 188 | mipmapLimitGroupName: 189 | pSDRemoveMatte: 0 190 | userData: 191 | assetBundleName: 192 | assetBundleVariant: 193 | -------------------------------------------------------------------------------- /Editor/Icons/solar_database-bold@2x.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f3ac3350a5be4f00917e4fb7aa5a213 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 2 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 0 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 3 84 | buildTarget: WebGL 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | - serializedVersion: 3 97 | buildTarget: Standalone 98 | maxTextureSize: 2048 99 | resizeAlgorithm: 0 100 | textureFormat: -1 101 | textureCompression: 1 102 | compressionQuality: 50 103 | crunchedCompression: 0 104 | allowsAlphaSplitting: 0 105 | overridden: 0 106 | ignorePlatformSupport: 0 107 | androidETC2FallbackOverride: 0 108 | forceMaximumCompressionQuality_BC6H_BC7: 0 109 | - serializedVersion: 3 110 | buildTarget: iPhone 111 | maxTextureSize: 2048 112 | resizeAlgorithm: 0 113 | textureFormat: -1 114 | textureCompression: 1 115 | compressionQuality: 50 116 | crunchedCompression: 0 117 | allowsAlphaSplitting: 0 118 | overridden: 0 119 | ignorePlatformSupport: 0 120 | androidETC2FallbackOverride: 0 121 | forceMaximumCompressionQuality_BC6H_BC7: 0 122 | - serializedVersion: 3 123 | buildTarget: Android 124 | maxTextureSize: 2048 125 | resizeAlgorithm: 0 126 | textureFormat: -1 127 | textureCompression: 1 128 | compressionQuality: 50 129 | crunchedCompression: 0 130 | allowsAlphaSplitting: 0 131 | overridden: 0 132 | ignorePlatformSupport: 0 133 | androidETC2FallbackOverride: 0 134 | forceMaximumCompressionQuality_BC6H_BC7: 0 135 | - serializedVersion: 3 136 | buildTarget: Server 137 | maxTextureSize: 2048 138 | resizeAlgorithm: 0 139 | textureFormat: -1 140 | textureCompression: 1 141 | compressionQuality: 50 142 | crunchedCompression: 0 143 | allowsAlphaSplitting: 0 144 | overridden: 0 145 | ignorePlatformSupport: 0 146 | androidETC2FallbackOverride: 0 147 | forceMaximumCompressionQuality_BC6H_BC7: 0 148 | - serializedVersion: 3 149 | buildTarget: VisionOS 150 | maxTextureSize: 2048 151 | resizeAlgorithm: 0 152 | textureFormat: -1 153 | textureCompression: 1 154 | compressionQuality: 50 155 | crunchedCompression: 0 156 | allowsAlphaSplitting: 0 157 | overridden: 0 158 | ignorePlatformSupport: 0 159 | androidETC2FallbackOverride: 0 160 | forceMaximumCompressionQuality_BC6H_BC7: 0 161 | - serializedVersion: 3 162 | buildTarget: tvOS 163 | maxTextureSize: 2048 164 | resizeAlgorithm: 0 165 | textureFormat: -1 166 | textureCompression: 1 167 | compressionQuality: 50 168 | crunchedCompression: 0 169 | allowsAlphaSplitting: 0 170 | overridden: 0 171 | ignorePlatformSupport: 0 172 | androidETC2FallbackOverride: 0 173 | forceMaximumCompressionQuality_BC6H_BC7: 0 174 | spriteSheet: 175 | serializedVersion: 2 176 | sprites: [] 177 | outline: [] 178 | physicsShape: [] 179 | bones: [] 180 | spriteID: 5e97eb03825dee720800000000000000 181 | internalID: 0 182 | vertices: [] 183 | indices: 184 | edges: [] 185 | weights: [] 186 | secondaryTextures: [] 187 | nameFileIdTable: {} 188 | mipmapLimitGroupName: 189 | pSDRemoveMatte: 0 190 | userData: 191 | assetBundleName: 192 | assetBundleVariant: 193 | -------------------------------------------------------------------------------- /Editor/Icons/d_solar_database-bold@2x.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 319f3bdfbe91a4af8aac8c8710acc4dc 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 2 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 0 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 3 84 | buildTarget: WebGL 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | - serializedVersion: 3 97 | buildTarget: Standalone 98 | maxTextureSize: 2048 99 | resizeAlgorithm: 0 100 | textureFormat: -1 101 | textureCompression: 1 102 | compressionQuality: 50 103 | crunchedCompression: 0 104 | allowsAlphaSplitting: 0 105 | overridden: 0 106 | ignorePlatformSupport: 0 107 | androidETC2FallbackOverride: 0 108 | forceMaximumCompressionQuality_BC6H_BC7: 0 109 | - serializedVersion: 3 110 | buildTarget: iPhone 111 | maxTextureSize: 2048 112 | resizeAlgorithm: 0 113 | textureFormat: -1 114 | textureCompression: 1 115 | compressionQuality: 50 116 | crunchedCompression: 0 117 | allowsAlphaSplitting: 0 118 | overridden: 0 119 | ignorePlatformSupport: 0 120 | androidETC2FallbackOverride: 0 121 | forceMaximumCompressionQuality_BC6H_BC7: 0 122 | - serializedVersion: 3 123 | buildTarget: Android 124 | maxTextureSize: 2048 125 | resizeAlgorithm: 0 126 | textureFormat: -1 127 | textureCompression: 1 128 | compressionQuality: 50 129 | crunchedCompression: 0 130 | allowsAlphaSplitting: 0 131 | overridden: 0 132 | ignorePlatformSupport: 0 133 | androidETC2FallbackOverride: 0 134 | forceMaximumCompressionQuality_BC6H_BC7: 0 135 | - serializedVersion: 3 136 | buildTarget: Server 137 | maxTextureSize: 2048 138 | resizeAlgorithm: 0 139 | textureFormat: -1 140 | textureCompression: 1 141 | compressionQuality: 50 142 | crunchedCompression: 0 143 | allowsAlphaSplitting: 0 144 | overridden: 0 145 | ignorePlatformSupport: 0 146 | androidETC2FallbackOverride: 0 147 | forceMaximumCompressionQuality_BC6H_BC7: 0 148 | - serializedVersion: 3 149 | buildTarget: VisionOS 150 | maxTextureSize: 2048 151 | resizeAlgorithm: 0 152 | textureFormat: -1 153 | textureCompression: 1 154 | compressionQuality: 50 155 | crunchedCompression: 0 156 | allowsAlphaSplitting: 0 157 | overridden: 0 158 | ignorePlatformSupport: 0 159 | androidETC2FallbackOverride: 0 160 | forceMaximumCompressionQuality_BC6H_BC7: 0 161 | - serializedVersion: 3 162 | buildTarget: tvOS 163 | maxTextureSize: 2048 164 | resizeAlgorithm: 0 165 | textureFormat: -1 166 | textureCompression: 1 167 | compressionQuality: 50 168 | crunchedCompression: 0 169 | allowsAlphaSplitting: 0 170 | overridden: 0 171 | ignorePlatformSupport: 0 172 | androidETC2FallbackOverride: 0 173 | forceMaximumCompressionQuality_BC6H_BC7: 0 174 | spriteSheet: 175 | serializedVersion: 2 176 | sprites: [] 177 | outline: [] 178 | physicsShape: [] 179 | bones: [] 180 | spriteID: 5e97eb03825dee720800000000000000 181 | internalID: 0 182 | vertices: [] 183 | indices: 184 | edges: [] 185 | weights: [] 186 | secondaryTextures: [] 187 | nameFileIdTable: {} 188 | mipmapLimitGroupName: 189 | pSDRemoveMatte: 0 190 | userData: 191 | assetBundleName: 192 | assetBundleVariant: 193 | -------------------------------------------------------------------------------- /Runtime/SQLiteAsset.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System; 23 | using UnityEngine; 24 | 25 | namespace SQLite 26 | { 27 | public class SQLiteAsset : ScriptableObject 28 | { 29 | [Tooltip("Flags controlling how the SQLite connection should be opened. 'ReadWrite' and 'Create' flags will be ignored, since SQLite assets are read-only.")] 30 | [SerializeField] private SQLiteOpenFlags _openFlags = SQLiteOpenFlags.ReadOnly; 31 | 32 | [Tooltip("Whether to store DateTime properties as ticks (true) or strings (false).")] 33 | [SerializeField] private bool _storeDateTimeAsTicks = true; 34 | 35 | [Tooltip("Name of the file created for the database inside Streaming Assets folder during builds.\n\n" 36 | + "If empty, the database bytes will be stored in the asset itself.\n\n" 37 | + "Loading databases from Streaming Assets is not supported in Android and WebGL platforms.")] 38 | [SerializeField] private string _streamingAssetsPath; 39 | 40 | [SerializeField, HideInInspector] private byte[] _bytes; 41 | 42 | /// 43 | /// Flags controlling how the SQLite connection should be opened. 44 | /// 45 | /// 46 | /// 'ReadWrite' and 'Create' flags will be ignored, since SQLite assets are read-only. 47 | /// 48 | public SQLiteOpenFlags OpenFlags 49 | { 50 | get => _openFlags; 51 | set => _openFlags = value & ~(SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create); 52 | } 53 | 54 | /// 55 | /// Whether to store DateTime properties as ticks (true) or strings (false). 56 | /// 57 | /// 58 | public bool StoreDateTimeAsTicks 59 | { 60 | get => _storeDateTimeAsTicks; 61 | set => _storeDateTimeAsTicks = value; 62 | } 63 | 64 | /// 65 | /// Bytes that compose the SQLite database file. 66 | /// 67 | public byte[] Bytes 68 | { 69 | get => _bytes; 70 | set => _bytes = value; 71 | } 72 | 73 | /// 74 | /// If true, the database bytes will be read from a file located at the Streaming Assets folder instead of storing all bytes in memory. 75 | /// 76 | public string StreamingAssetsPath 77 | { 78 | get => _streamingAssetsPath; 79 | set => _streamingAssetsPath = value; 80 | } 81 | 82 | /// 83 | /// If true, the database bytes will be read from a file located at the Streaming Assets folder instead of storing all bytes in memory. 84 | /// 85 | public bool UseStreamingAssets => !string.IsNullOrWhiteSpace(_streamingAssetsPath); 86 | 87 | /// 88 | /// Creates a new connection to the read-only SQLite database represented by this asset. 89 | /// 90 | /// 91 | /// If is null. 92 | public SQLiteConnection CreateConnection() 93 | { 94 | #if !UNITY_EDITOR && !UNITY_ANDROID && !UNITY_WEBGL 95 | if (UseStreamingAssets) 96 | { 97 | string path = System.IO.Path.Combine(Application.streamingAssetsPath, _streamingAssetsPath); 98 | return new SQLiteConnection(path); 99 | } 100 | #endif 101 | if (Bytes == null) 102 | { 103 | throw new NullReferenceException(nameof(Bytes)); 104 | } 105 | 106 | return new SQLiteConnection("").Deserialize(Bytes, null, SQLite3.DeserializeFlags.ReadOnly); 107 | } 108 | 109 | #if UNITY_EDITOR 110 | protected void OnValidate() 111 | { 112 | if (_openFlags.HasFlag(SQLiteOpenFlags.ReadWrite)) 113 | { 114 | Debug.LogWarning($"{nameof(SQLiteAsset)} does not support writing to the database. Ignoring \"ReadWrite\" flag.", this); 115 | _openFlags &= ~SQLiteOpenFlags.ReadWrite; 116 | } 117 | if (_openFlags.HasFlag(SQLiteOpenFlags.Create)) 118 | { 119 | Debug.LogWarning($"{nameof(SQLiteAsset)} does not support creating database. Ignoring \"Create\" flag.", this); 120 | _openFlags &= ~SQLiteOpenFlags.Create; 121 | } 122 | } 123 | #endif 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Runtime/SQLiteExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System; 23 | using System.Runtime.InteropServices; 24 | 25 | namespace SQLite 26 | { 27 | public static partial class SQLite3 28 | { 29 | [Flags] 30 | public enum SerializeFlags : uint 31 | { 32 | None, 33 | NoCopy = 0x001, /* Do no memory allocations */ 34 | } 35 | 36 | [Flags] 37 | public enum DeserializeFlags : uint 38 | { 39 | None, 40 | FreeOnClose = 1, /* Call sqlite3_free() on close */ 41 | Resizeable = 2, /* Resize using sqlite3_realloc64() */ 42 | ReadOnly = 4, /* Database is read-only */ 43 | } 44 | 45 | [DllImport(LibraryPath, EntryPoint = "sqlite3_serialize", CallingConvention = CallingConvention.Cdecl)] 46 | public static extern IntPtr Serialize(IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string zSchema, out long piSize, SerializeFlags mFlags); 47 | 48 | [DllImport(LibraryPath, EntryPoint = "sqlite3_deserialize", CallingConvention = CallingConvention.Cdecl)] 49 | public static extern Result Deserialize(IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string zSchema, byte[] pData, long szDb, long szBuf, DeserializeFlags mFlags); 50 | 51 | [DllImport(LibraryPath, EntryPoint = "sqlite3_deserialize", CallingConvention = CallingConvention.Cdecl)] 52 | public static unsafe extern Result Deserialize(IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string zSchema, void* pData, long szDb, long szBuf, DeserializeFlags mFlags); 53 | 54 | [DllImport(LibraryPath, EntryPoint = "sqlite3_malloc", CallingConvention = CallingConvention.Cdecl)] 55 | public static extern IntPtr Malloc(int size); 56 | 57 | [DllImport(LibraryPath, EntryPoint = "sqlite3_malloc64", CallingConvention = CallingConvention.Cdecl)] 58 | public static extern IntPtr Malloc(long size); 59 | 60 | [DllImport(LibraryPath, EntryPoint = "sqlite3_realloc", CallingConvention = CallingConvention.Cdecl)] 61 | public static extern IntPtr Realloc(IntPtr ptr, int size); 62 | 63 | [DllImport(LibraryPath, EntryPoint = "sqlite3_realloc64", CallingConvention = CallingConvention.Cdecl)] 64 | public static extern IntPtr Realloc(IntPtr ptr, long size); 65 | 66 | [DllImport(LibraryPath, EntryPoint = "sqlite3_free", CallingConvention = CallingConvention.Cdecl)] 67 | public static extern void Free(IntPtr ptr); 68 | 69 | [DllImport(LibraryPath, EntryPoint = "sqlite3_column_bytes16", CallingConvention = CallingConvention.Cdecl)] 70 | public static extern int ColumnBytes16(IntPtr stmt, int index); 71 | 72 | [DllImport(LibraryPath, EntryPoint = "sqlite3_exec", CallingConvention = CallingConvention.Cdecl)] 73 | public static extern Result Exec(IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string sql, IntPtr callback, IntPtr userdata, IntPtr errorMessagePtr); 74 | 75 | #if UNITY_WEBGL && !UNITY_EDITOR 76 | [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] 77 | public static extern int idbvfs_register(int makeDefault); 78 | #endif 79 | 80 | static SQLite3() 81 | { 82 | #if UNITY_WEBGL && !UNITY_EDITOR 83 | idbvfs_register(1); 84 | #endif 85 | } 86 | } 87 | 88 | public static class ISQLiteConnectionExtensions 89 | { 90 | public static int Insert(this ISQLiteConnection connection, ref T obj) 91 | { 92 | object boxed = obj; 93 | int result = connection.Insert(boxed); 94 | obj = (T) boxed; 95 | return result; 96 | } 97 | 98 | public static int Insert(this ISQLiteConnection connection, ref T obj, Type objType) 99 | { 100 | object boxed = obj; 101 | int result = connection.Insert(boxed, objType); 102 | obj = (T) boxed; 103 | return result; 104 | } 105 | 106 | public static int Insert(this ISQLiteConnection connection, ref T obj, string extra) 107 | { 108 | object boxed = obj; 109 | int result = connection.Insert(boxed, extra); 110 | obj = (T) boxed; 111 | return result; 112 | } 113 | 114 | public static int Insert(this ISQLiteConnection connection, ref T obj, string extra, Type objType) 115 | { 116 | object boxed = obj; 117 | int result = connection.Insert(boxed, extra, objType); 118 | obj = (T) boxed; 119 | return result; 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Plugins/Makefile: -------------------------------------------------------------------------------- 1 | # Android setup 2 | ANDROID_NDK_ROOT ?= 3 | # macOS code signing setup 4 | CODESIGN ?= codesign 5 | MACOS_CODESIGN_SIGNATURE ?= 6 | MACOS_VERSION_MIN ?= 11.0 7 | # Download GitHub Action releases 8 | GITHUB_CLI_BIN ?= gh 9 | GITHUB_REPO ?= gilzoide/unity-sqlite-net 10 | RUN_ID ?= 11 | 12 | ifeq ($(DEBUG),1) 13 | CFLAGS += -O0 -g -DDEBUG 14 | else 15 | CFLAGS += -O3 -DNDEBUG 16 | endif 17 | 18 | BUILD_DIRS = \ 19 | lib/windows/x86_64 lib/windows/x86 lib/windows/arm64 \ 20 | lib/linux/x86_64 lib/linux/x86 \ 21 | lib/macos \ 22 | lib/android/arm64 lib/android/arm32 lib/android/x86 lib/android/x86_64 23 | 24 | SQLITE_SRC = sqlite-amalgamation/sqlite3.c 25 | SQLITE_NET_SRC = $(wildcard sqlite-net~/src/*.cs) sqlite-net~/LICENSE.txt 26 | SQLITE_NET_DEST = ../Runtime/sqlite-net 27 | SQLITE_NET_SED_SCRIPT = tools~/fix-library-path.sed 28 | 29 | $(BUILD_DIRS): 30 | mkdir -p $@ 31 | 32 | .PRECIOUS: lib/%/sqlite3.o~ 33 | lib/%/sqlite3.o~: $(SQLITE_SRC) | lib/% 34 | $(CC) -c -o $@ $< $(CFLAGS) 35 | 36 | # Windows 37 | lib/windows/%/gilzoide-sqlite-net.dll: LINKFLAGS += -shared 38 | lib/windows/%/gilzoide-sqlite-net.dll: lib/windows/%/sqlite3.o~ | lib/windows/% 39 | $(CC) -o $@ $^ $(LINKFLAGS) 40 | 41 | # Linux 42 | lib/linux/%/libgilzoide-sqlite-net.so: CFLAGS += -fPIC 43 | 44 | # Note: The "-Wl,-Bsymbolic" flags prevent the dynamic linker from interposing the plugin’s calls to its 45 | # own exported symbols with identically-named symbols in other loaded libraries (like /usr/lib/libsqlite3.so.0) 46 | # which can cause a Unity Editor crash otherwise. 47 | lib/linux/%/libgilzoide-sqlite-net.so: LINKFLAGS += -shared -lm -Wl,-Bsymbolic 48 | 49 | lib/linux/%/libgilzoide-sqlite-net.so: lib/linux/%/sqlite3.o~ | lib/linux/% 50 | $(CC) -o $@ $^ $(LINKFLAGS) 51 | 52 | # macOS 53 | lib/macos/libgilzoide-sqlite-net.dylib: CFLAGS += -arch arm64 -arch x86_64 -isysroot $(shell xcrun --show-sdk-path --sdk macosx) -mmacosx-version-min=$(MACOS_VERSION_MIN) 54 | lib/macos/libgilzoide-sqlite-net.dylib: LINKFLAGS += -shared -arch arm64 -arch x86_64 -framework Security -mmacosx-version-min=$(MACOS_VERSION_MIN) 55 | lib/macos/libgilzoide-sqlite-net.dylib: lib/macos/sqlite3.o~ | lib/macos 56 | $(CC) -o $@ $^ $(LINKFLAGS) 57 | ifdef MACOS_CODESIGN_SIGNATURE 58 | $(CODESIGN) -s "$(MACOS_CODESIGN_SIGNATURE)" $@ 59 | endif 60 | 61 | # Android 62 | check-ndk-root: 63 | ifndef ANDROID_NDK_ROOT 64 | $(error ANDROID_NDK_ROOT must be set for Android builds!) 65 | endif 66 | 67 | lib/android/%/libgilzoide-sqlite-net.so: CFLAGS += -fPIC 68 | lib/android/%/libgilzoide-sqlite-net.so: LINKFLAGS += -shared -lm -Wl,-z,max-page-size=16384 69 | lib/android/%/libgilzoide-sqlite-net.so: lib/android/%/sqlite3.o~ check-ndk-root | lib/android/% 70 | $(CC) -o $@ $< $(LINKFLAGS) 71 | 72 | lib/android/arm64/libgilzoide-sqlite-net.so: CC = $(wildcard $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/*/bin/aarch64-linux-android21-clang) 73 | lib/android/arm32/libgilzoide-sqlite-net.so: CC = $(wildcard $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/*/bin/armv7a-linux-androideabi21-clang) 74 | lib/android/x86_64/libgilzoide-sqlite-net.so: CC = $(wildcard $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/*/bin/x86_64-linux-android21-clang) 75 | lib/android/x86/libgilzoide-sqlite-net.so: CC = $(wildcard $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/*/bin/i686-linux-android21-clang) 76 | 77 | 78 | # Source 79 | $(SQLITE_NET_DEST)/%.cs: sqlite-net~/src/%.cs $(SQLITE_NET_SED_SCRIPT) 80 | cat $< | sed -E -f $(SQLITE_NET_SED_SCRIPT) > $@ 81 | 82 | $(SQLITE_NET_DEST)/License.txt: sqlite-net~/License.txt 83 | cp $< $@ 84 | 85 | # Targets 86 | windows-x86_64: lib/windows/x86_64/gilzoide-sqlite-net.dll 87 | windows-x86: lib/windows/x86/gilzoide-sqlite-net.dll 88 | windows-arm64: lib/windows/arm64/gilzoide-sqlite-net.dll 89 | 90 | windows-mingw-x86_64: CC = x86_64-w64-mingw32-gcc 91 | windows-mingw-x86_64: LINKFLAGS += -static-libgcc 92 | windows-mingw-x86_64: lib/windows/x86_64/gilzoide-sqlite-net.dll 93 | 94 | windows-mingw-x86: CC = i686-w64-mingw32-gcc 95 | windows-mingw-x86: LINKFLAGS += -static-libgcc 96 | windows-mingw-x86: lib/windows/x86/gilzoide-sqlite-net.dll 97 | 98 | windows-mingw-arm64: CC = aarch64-w64-mingw32-gcc 99 | windows-mingw-arm64: LINKFLAGS += -static-libgcc 100 | windows-mingw-arm64: lib/windows/arm64/gilzoide-sqlite-net.dll 101 | 102 | linux-x86_64: lib/linux/x86_64/libgilzoide-sqlite-net.so 103 | 104 | macos-universal: lib/macos/libgilzoide-sqlite-net.dylib 105 | 106 | android-arm64: lib/android/arm64/libgilzoide-sqlite-net.so 107 | android-arm32: lib/android/arm32/libgilzoide-sqlite-net.so 108 | android-x86_64: lib/android/x86_64/libgilzoide-sqlite-net.so 109 | android-x86: lib/android/x86/libgilzoide-sqlite-net.so 110 | 111 | source: $(SQLITE_NET_DEST)/License.txt $(SQLITE_NET_DEST)/AssemblyInfo.cs $(SQLITE_NET_DEST)/SQLite.cs $(SQLITE_NET_DEST)/SQLiteAsync.cs 112 | 113 | all-android: android-arm64 android-arm32 android-x86_64 android-x86 114 | all-apple: macos-universal 115 | all-linux: linux-x86_64 116 | all-windows: windows-x86_64 windows-x86 117 | all-windows-mingw: windows-mingw-x86_64 windows-mingw-x86 118 | all-windows-llvm-mingw: windows-mingw-x86_64 windows-mingw-x86 windows-mingw-arm64 119 | 120 | # Dockerized builds 121 | docker-all-android: 122 | docker build -f tools~/Dockerfile.build.android --platform=linux/amd64 -t gilzoide-sqlite-net-build-android:latest $(DOCKER_BUILD_ARGS) . 123 | docker run --rm -v "$(CURDIR)":/src -w /src --platform=linux/amd64 gilzoide-sqlite-net-build-android:latest make all-android 124 | docker-all-linux: 125 | docker build -f tools~/Dockerfile.build.linux --platform=linux/amd64 -t gilzoide-sqlite-net-build-linux:latest $(DOCKER_BUILD_ARGS) . 126 | docker run --rm -v "$(CURDIR)":/src -w /src --platform=linux/amd64 gilzoide-sqlite-net-build-linux:latest make all-linux 127 | docker-all-windows: 128 | docker build -f tools~/Dockerfile.build.windows -t gilzoide-sqlite-net-build-windows:latest $(DOCKER_BUILD_ARGS) . 129 | docker run --rm -v "$(CURDIR)":/src -w /src gilzoide-sqlite-net-build-windows:latest make all-windows-mingw 130 | docker-all-windows-llvm: 131 | docker run --rm -v "$(CURDIR)":/src -w /src mstorsjo/llvm-mingw:latest make all-windows-llvm-mingw 132 | 133 | # Download builds from GitHub Actions 134 | download-latest-build: 135 | $(eval TMPDIR := $(shell mktemp -d)) 136 | $(GITHUB_CLI_BIN) run download $(RUN_ID) --repo $(GITHUB_REPO) -p gilzoide-sqlite-net-* -D $(TMPDIR) 137 | rsync -r $(TMPDIR)/gilzoide-sqlite-net-windows/* lib/windows/ 138 | rsync -r $(TMPDIR)/gilzoide-sqlite-net-linux/* lib/linux/ 139 | rsync -r $(TMPDIR)/gilzoide-sqlite-net-android/* lib/android/ 140 | rsync -r $(TMPDIR)/gilzoide-sqlite-net-macos/* lib/macos/ 141 | $(RM) -r $(TMPDIR) 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SQLite-net for Unity 2 | [![openupm](https://img.shields.io/npm/v/com.gilzoide.sqlite-net?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/com.gilzoide.sqlite-net/) 3 | 4 | This package provides the excelent [SQLite-net](https://github.com/praeclarum/sqlite-net) library for accessing [SQLite](https://sqlite.org/) databases in Unity. 5 | 6 | 7 | ## Features 8 | - [SQLite-net v1.9.172](https://github.com/praeclarum/sqlite-net/tree/v1.9.172) 9 | + Both synchronous and asynchronous APIs are available 10 | + `SQLiteConnection.Serialize` extension method for serializing a database to `byte[]` (reference: [SQLite Serialization](https://www.sqlite.org/c3ref/serialize.html)). 11 | + `SQLiteConnection.Deserialize` extension method for deserializing memory (`byte[]`, `NativeArray` or `ReadOnlySpan`) into an open database (reference: [SQLite Deserialization](https://www.sqlite.org/c3ref/deserialize.html)). 12 | + `SQLiteConnection.ImportCsvToTable` extension method for importing a CSV text stream as a new table inside the database. 13 | - [SQLite3 Multiple Ciphers 2.1.3](https://github.com/utelle/SQLite3MultipleCiphers/releases/tag/v2.1.3) (based on [SQLite 3.50.1](https://sqlite.org/releaselog/3_50_1.html)) 14 | + Supports encrypted databases 15 | + 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) 16 | + Supports Windows, Linux, macOS, WebGL, Android, iOS, tvOS and visionOS platforms 17 | + Supports persisting data in WebGL builds by using a [custom VFS backed by Indexed DB](https://github.com/gilzoide/idbvfs). 18 | - [SQLiteAsset](Runtime/SQLiteAsset.cs): read-only SQLite database Unity assets. 19 | + Files with the extensions ".sqlite", ".sqlite2" and ".sqlite3" will be imported as SQLite database assets. 20 | + ".csv" files can be imported as SQLite database assets by changing the importer to `SQLite.Editor.SQLiteAssetCsvImporter` in the Inspector. 21 | + ".sql" files are imported as Text assets by default, but can be imported as SQLite database assets by changing the importer to `SQLite.Editor.SQLScriptDatabaseImporter`. 22 | + Use the `CreateConnection()` method for connecting to the database provided by the asset. 23 | Make sure to `Dispose()` of any connections you create. 24 | + SQLite assets may be loaded from Streaming Assets folder or from memory, depending on the value of their "Streaming Assets Path" property. 25 | + **Note**: Android and WebGL platforms don't support loading SQLite databases from Streaming Assets and will always load them in memory. 26 | + `SQLiteConnection.SerializeToAsset` extension method for serializing a database to an instance of `SQLiteAsset`. 27 | 28 | ## How to install 29 | Either: 30 | - Use the [openupm registry](https://openupm.com/) and install this package using the [openupm-cli](https://github.com/openupm/openupm-cli): 31 | ``` 32 | openupm add com.gilzoide.sqlite-net 33 | ``` 34 | - Install using the [Unity Package Manager](https://docs.unity3d.com/Manual/upm-ui-giturl.html) with the following URL: 35 | ``` 36 | https://github.com/gilzoide/unity-sqlite-net.git#1.3.2 37 | ``` 38 | - Clone this repository or download a snapshot of it directly inside your project's `Assets` or `Packages` folder. 39 | 40 | 41 | ## Usage example 42 | The following code demonstrates some of SQLite-net's core functionality. 43 | Check out [SQLite-net's Wiki](https://github.com/praeclarum/sqlite-net/wiki) for more complete documentation on how to use the library. 44 | ```cs 45 | using SQLite; 46 | using UnityEngine; 47 | 48 | // The library contains simple attributes that you can use 49 | // to control the construction of tables, ORM style 50 | public class Player 51 | { 52 | [PrimaryKey, AutoIncrement] 53 | public int Id { get; set; } 54 | public string Name { get; set; } 55 | } 56 | 57 | public class TestSQLite : MonoBehaviour 58 | { 59 | void Start() 60 | { 61 | // 1. Create a connection to the database. 62 | // The special ":memory:" in-memory database and 63 | // URIs like "file:///somefile" are also supported 64 | var db = new SQLiteConnection($"{Application.persistentDataPath}/MyDb.db"); 65 | 66 | // 2. Once you have defined your entity, you can automatically 67 | // generate tables in your database by calling CreateTable 68 | db.CreateTable(); 69 | 70 | // 3. You can insert rows in the database using Insert 71 | // The Insert call fills Id, which is marked with [AutoIncremented] 72 | var newPlayer = new Player 73 | { 74 | Name = "gilzoide", 75 | }; 76 | db.Insert(newPlayer); 77 | Debug.Log($"Player new ID: {newPlayer.Id}"); 78 | // Similar methods exist for Update and Delete. 79 | 80 | // 4.a The most straightforward way to query for data 81 | // is using the Table method. This can take predicates 82 | // for constraining via WHERE clauses and/or adding ORDER BY clauses 83 | var query = db.Table().Where(p => p.Name.StartsWith("g")); 84 | foreach (Player player in query) 85 | { 86 | Debug.Log($"Found player named {player.Name} with ID {player.Id}"); 87 | } 88 | 89 | // 4.b You can also make queries at a low-level using the Query method 90 | var players = db.Query("SELECT * FROM Player WHERE Id = ?", 1); 91 | foreach (Player player in players) 92 | { 93 | Debug.Log($"Player with ID 1 is called {player.Name}"); 94 | } 95 | 96 | // 5. You can perform low-level updates to the database using the Execute 97 | // method, for example for running PRAGMAs or VACUUM 98 | db.Execute("VACUUM"); 99 | } 100 | } 101 | ``` 102 | 103 | 104 | ## License 105 | SQLite-net for Unity first-party code is licensed under the [MIT license](LICENSE.txt). 106 | 107 | Third-party code: 108 | - SQLite-net: [MIT license](Runtime/sqlite-net/LICENSE.txt) 109 | - SQLite3 Multiple Ciphers: [MIT license](https://github.com/utelle/SQLite3MultipleCiphers/blob/main/LICENSE) 110 | 111 | Database icons from [Solar Icons Set](https://www.figma.com/community/file/1166831539721848736/solar-icons-set), licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 112 | 113 | 114 | ## Modifications made to SQLite-net source code 115 | - The value of `LibraryPath` was changed from `sqlite3` to `__Internal` in WebGL/iOS/tvOS/visionOS builds and `gilzoide-sqlite-net` for other platforms. 116 | This makes sure the prebuilt libraries are used instead of the ones provided by the system. 117 | - `LibraryPath` is made public. 118 | This is useful for libraries that want to bind additional native SQLite functions via P/Invoke. 119 | - `SQLiteConnection.Quote` is made public. 120 | This is useful for libraries making raw queries. 121 | - `SQLite3.SetDirectory` is only defined in Windows platforms. 122 | - Makes all column related attributes inherit `PreserveAttribute`, fixing errors on columns when managed code stripping is enabled. 123 | - Changes the `TaskScheduler` used by the async API on WebGL to one that executes tasks on Unity's main thread. 124 | - Fix support for struct return types in queries 125 | -------------------------------------------------------------------------------- /Runtime/Csv/CsvReader.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System; 23 | using System.Collections.Generic; 24 | using System.IO; 25 | using System.Text; 26 | 27 | namespace SQLite.Csv 28 | { 29 | public static class CsvReader 30 | { 31 | public enum SeparatorChar 32 | { 33 | Comma, 34 | Semicolon, 35 | Tabs, 36 | } 37 | 38 | /// 39 | /// Parse a stream of CSV-formatted data. 40 | /// 41 | /// Stream of CSV-formatted data. 42 | /// Character used for separating fields. 43 | /// Maximum field size allowed. 44 | /// 45 | /// The enumeration returns each field's contents, even if it is empty. 46 | /// is returned at the end of the lines, meaning a new row will start next. 47 | /// Empty lines are ignored and will not be enumerated. 48 | /// 49 | /// Thrown if is null. 50 | /// Thrown if any field size is greater than . 51 | public static IEnumerable ParseStream(TextReader stream, SeparatorChar separator = SeparatorChar.Comma, int maxFieldSize = int.MaxValue) 52 | { 53 | if (stream == null) 54 | { 55 | throw new ArgumentNullException(nameof(stream)); 56 | } 57 | 58 | SkipEmptyLines(stream); 59 | if (stream.Peek() < 0) 60 | { 61 | yield break; 62 | } 63 | 64 | bool insideQuotes = false; 65 | var stringBuilder = new StringBuilder(); 66 | while (true) 67 | { 68 | int c = stream.Read(); 69 | switch (c) 70 | { 71 | case '\r': 72 | if (!insideQuotes && stream.Peek() == '\n') 73 | { 74 | stream.Read(); 75 | goto case '\n'; 76 | } 77 | else 78 | { 79 | goto default; 80 | } 81 | 82 | case '\n': 83 | if (!insideQuotes) 84 | { 85 | yield return stringBuilder.ToString(); 86 | stringBuilder.Clear(); 87 | yield return null; 88 | 89 | SkipEmptyLines(stream); 90 | if (stream.Peek() < 0) 91 | { 92 | yield break; 93 | } 94 | } 95 | else 96 | { 97 | goto default; 98 | } 99 | break; 100 | 101 | case ',': 102 | if (!insideQuotes && separator == SeparatorChar.Comma) 103 | { 104 | yield return stringBuilder.ToString(); 105 | stringBuilder.Clear(); 106 | } 107 | else 108 | { 109 | goto default; 110 | } 111 | break; 112 | 113 | case ';': 114 | if (!insideQuotes && separator == SeparatorChar.Semicolon) 115 | { 116 | yield return stringBuilder.ToString(); 117 | stringBuilder.Clear(); 118 | } 119 | else 120 | { 121 | goto default; 122 | } 123 | break; 124 | 125 | case '\t': 126 | if (!insideQuotes && separator == SeparatorChar.Tabs) 127 | { 128 | yield return stringBuilder.ToString(); 129 | stringBuilder.Clear(); 130 | } 131 | else 132 | { 133 | goto default; 134 | } 135 | break; 136 | 137 | case '"': 138 | if (insideQuotes && stream.Peek() == '"') 139 | { 140 | stream.Read(); 141 | goto default; 142 | } 143 | else 144 | { 145 | insideQuotes = !insideQuotes; 146 | } 147 | break; 148 | 149 | case < 0: 150 | yield return stringBuilder.ToString(); 151 | yield return null; 152 | yield break; 153 | 154 | default: 155 | if (stringBuilder.Length >= maxFieldSize) 156 | { 157 | throw new CsvException("Field size is greater than maximum allowed size."); 158 | } 159 | stringBuilder.Append((char) c); 160 | break; 161 | } 162 | } 163 | } 164 | 165 | private static void SkipEmptyLines(TextReader streamReader) 166 | { 167 | while (true) 168 | { 169 | int c = streamReader.Peek(); 170 | switch (c) 171 | { 172 | case '\n': 173 | case '\r': 174 | streamReader.Read(); 175 | continue; 176 | 177 | default: 178 | return; 179 | } 180 | } 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /Samples~/Readme/ReadmeScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 0 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 3 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | buildHeightMesh: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &1915051410 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 1915051411} 135 | - component: {fileID: 1915051412} 136 | m_Layer: 0 137 | m_Name: TestSqlite 138 | m_TagString: Untagged 139 | m_Icon: {fileID: 0} 140 | m_NavMeshLayer: 0 141 | m_StaticEditorFlags: 0 142 | m_IsActive: 1 143 | --- !u!4 &1915051411 144 | Transform: 145 | m_ObjectHideFlags: 0 146 | m_CorrespondingSourceObject: {fileID: 0} 147 | m_PrefabInstance: {fileID: 0} 148 | m_PrefabAsset: {fileID: 0} 149 | m_GameObject: {fileID: 1915051410} 150 | serializedVersion: 2 151 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 152 | m_LocalPosition: {x: 0, y: 0, z: 0} 153 | m_LocalScale: {x: 1, y: 1, z: 1} 154 | m_ConstrainProportionsScale: 0 155 | m_Children: [] 156 | m_Father: {fileID: 0} 157 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 158 | --- !u!114 &1915051412 159 | MonoBehaviour: 160 | m_ObjectHideFlags: 0 161 | m_CorrespondingSourceObject: {fileID: 0} 162 | m_PrefabInstance: {fileID: 0} 163 | m_PrefabAsset: {fileID: 0} 164 | m_GameObject: {fileID: 1915051410} 165 | m_Enabled: 1 166 | m_EditorHideFlags: 0 167 | m_Script: {fileID: 11500000, guid: 6adceb403221c46bfa7c0060aaff46f1, type: 3} 168 | m_Name: 169 | m_EditorClassIdentifier: 170 | --- !u!1 &2060423183 171 | GameObject: 172 | m_ObjectHideFlags: 0 173 | m_CorrespondingSourceObject: {fileID: 0} 174 | m_PrefabInstance: {fileID: 0} 175 | m_PrefabAsset: {fileID: 0} 176 | serializedVersion: 6 177 | m_Component: 178 | - component: {fileID: 2060423186} 179 | - component: {fileID: 2060423185} 180 | - component: {fileID: 2060423184} 181 | m_Layer: 0 182 | m_Name: Main Camera 183 | m_TagString: MainCamera 184 | m_Icon: {fileID: 0} 185 | m_NavMeshLayer: 0 186 | m_StaticEditorFlags: 0 187 | m_IsActive: 1 188 | --- !u!81 &2060423184 189 | AudioListener: 190 | m_ObjectHideFlags: 0 191 | m_CorrespondingSourceObject: {fileID: 0} 192 | m_PrefabInstance: {fileID: 0} 193 | m_PrefabAsset: {fileID: 0} 194 | m_GameObject: {fileID: 2060423183} 195 | m_Enabled: 1 196 | --- !u!20 &2060423185 197 | Camera: 198 | m_ObjectHideFlags: 0 199 | m_CorrespondingSourceObject: {fileID: 0} 200 | m_PrefabInstance: {fileID: 0} 201 | m_PrefabAsset: {fileID: 0} 202 | m_GameObject: {fileID: 2060423183} 203 | m_Enabled: 1 204 | serializedVersion: 2 205 | m_ClearFlags: 1 206 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 207 | m_projectionMatrixMode: 1 208 | m_GateFitMode: 2 209 | m_FOVAxisMode: 0 210 | m_Iso: 200 211 | m_ShutterSpeed: 0.005 212 | m_Aperture: 16 213 | m_FocusDistance: 10 214 | m_FocalLength: 50 215 | m_BladeCount: 5 216 | m_Curvature: {x: 2, y: 11} 217 | m_BarrelClipping: 0.25 218 | m_Anamorphism: 0 219 | m_SensorSize: {x: 36, y: 24} 220 | m_LensShift: {x: 0, y: 0} 221 | m_NormalizedViewPortRect: 222 | serializedVersion: 2 223 | x: 0 224 | y: 0 225 | width: 1 226 | height: 1 227 | near clip plane: 0.3 228 | far clip plane: 1000 229 | field of view: 60 230 | orthographic: 1 231 | orthographic size: 5 232 | m_Depth: -1 233 | m_CullingMask: 234 | serializedVersion: 2 235 | m_Bits: 4294967295 236 | m_RenderingPath: -1 237 | m_TargetTexture: {fileID: 0} 238 | m_TargetDisplay: 0 239 | m_TargetEye: 3 240 | m_HDR: 1 241 | m_AllowMSAA: 1 242 | m_AllowDynamicResolution: 0 243 | m_ForceIntoRT: 0 244 | m_OcclusionCulling: 1 245 | m_StereoConvergence: 10 246 | m_StereoSeparation: 0.022 247 | --- !u!4 &2060423186 248 | Transform: 249 | m_ObjectHideFlags: 0 250 | m_CorrespondingSourceObject: {fileID: 0} 251 | m_PrefabInstance: {fileID: 0} 252 | m_PrefabAsset: {fileID: 0} 253 | m_GameObject: {fileID: 2060423183} 254 | serializedVersion: 2 255 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 256 | m_LocalPosition: {x: 0, y: 0, z: -10} 257 | m_LocalScale: {x: 1, y: 1, z: 1} 258 | m_ConstrainProportionsScale: 0 259 | m_Children: [] 260 | m_Father: {fileID: 0} 261 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 262 | --- !u!1660057539 &9223372036854775807 263 | SceneRoots: 264 | m_ObjectHideFlags: 0 265 | m_Roots: 266 | - {fileID: 2060423186} 267 | - {fileID: 1915051411} 268 | -------------------------------------------------------------------------------- /Runtime/SQLiteConnectionExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System; 23 | using System.Collections.Generic; 24 | using System.IO; 25 | using System.Runtime.InteropServices; 26 | using SQLite.Csv; 27 | using Unity.Collections; 28 | using Unity.Collections.LowLevel.Unsafe; 29 | using UnityEngine; 30 | 31 | namespace SQLite 32 | { 33 | public static class SQLiteConnectionExtensions 34 | { 35 | public static byte[] Serialize(this SQLiteConnection db, string schema = null) 36 | { 37 | IntPtr buffer = SQLite3.Serialize(db.Handle, schema, out long size, SQLite3.SerializeFlags.None); 38 | if (buffer == IntPtr.Zero) 39 | { 40 | return null; 41 | } 42 | try 43 | { 44 | var bytes = new byte[size]; 45 | Marshal.Copy(buffer, bytes, 0, (int)size); 46 | return bytes; 47 | } 48 | finally 49 | { 50 | SQLite3.Free(buffer); 51 | } 52 | } 53 | 54 | public static SQLiteAsset SerializeToAsset(this SQLiteConnection db, string schema = null, SQLiteOpenFlags openFlags = SQLiteOpenFlags.ReadOnly, bool storeDateTimeAsTicks = true, string streamingAssetsPath = null) 55 | { 56 | SQLiteAsset asset = ScriptableObject.CreateInstance(); 57 | asset.Bytes = db.Serialize(schema); 58 | asset.OpenFlags = openFlags; 59 | asset.StoreDateTimeAsTicks = storeDateTimeAsTicks; 60 | asset.StreamingAssetsPath = streamingAssetsPath; 61 | return asset; 62 | } 63 | 64 | public static SQLiteConnection Deserialize(this SQLiteConnection db, byte[] buffer, string schema = null, SQLite3.DeserializeFlags flags = SQLite3.DeserializeFlags.None) 65 | { 66 | return Deserialize(db, buffer, buffer.LongLength, schema, flags); 67 | } 68 | 69 | public static SQLiteConnection Deserialize(this SQLiteConnection db, byte[] buffer, long usedSize, string schema = null, SQLite3.DeserializeFlags flags = SQLite3.DeserializeFlags.None) 70 | { 71 | SQLite3.Result result = SQLite3.Deserialize(db.Handle, schema, buffer, usedSize, buffer.LongLength, flags); 72 | if (result != SQLite3.Result.OK) 73 | { 74 | throw SQLiteException.New(result, SQLite3.GetErrmsg(db.Handle)); 75 | } 76 | return db; 77 | } 78 | 79 | public static SQLiteConnection Deserialize(this SQLiteConnection db, NativeArray buffer, string schema = null, SQLite3.DeserializeFlags flags = SQLite3.DeserializeFlags.None) 80 | { 81 | return Deserialize(db, buffer, buffer.Length, schema, flags); 82 | } 83 | 84 | public static SQLiteConnection Deserialize(this SQLiteConnection db, NativeArray buffer, long usedSize, string schema = null, SQLite3.DeserializeFlags flags = SQLite3.DeserializeFlags.None) 85 | { 86 | SQLite3.Result result; 87 | unsafe 88 | { 89 | result = SQLite3.Deserialize(db.Handle, schema, buffer.GetUnsafePtr(), usedSize, buffer.Length, flags); 90 | } 91 | if (result != SQLite3.Result.OK) 92 | { 93 | throw SQLiteException.New(result, SQLite3.GetErrmsg(db.Handle)); 94 | } 95 | return db; 96 | } 97 | 98 | public static SQLiteConnection Deserialize(this SQLiteConnection db, ReadOnlySpan buffer, string schema = null, SQLite3.DeserializeFlags flags = SQLite3.DeserializeFlags.None) 99 | { 100 | return Deserialize(db, buffer, buffer.Length, schema, flags); 101 | } 102 | 103 | public static SQLiteConnection Deserialize(this SQLiteConnection db, ReadOnlySpan buffer, long usedSize, string schema = null, SQLite3.DeserializeFlags flags = SQLite3.DeserializeFlags.None) 104 | { 105 | SQLite3.Result result; 106 | unsafe 107 | { 108 | fixed (void* ptr = buffer) 109 | { 110 | result = SQLite3.Deserialize(db.Handle, schema, ptr, usedSize, buffer.Length, flags); 111 | } 112 | } 113 | if (result != SQLite3.Result.OK) 114 | { 115 | throw SQLiteException.New(result, SQLite3.GetErrmsg(db.Handle)); 116 | } 117 | return db; 118 | } 119 | 120 | public static void ExecuteScript(this SQLiteConnection db, string sql) 121 | { 122 | SQLite3.Result result = SQLite3.Exec(db.Handle, sql, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); 123 | if (result != SQLite3.Result.OK) 124 | { 125 | throw SQLiteException.New(result, SQLite3.GetErrmsg(db.Handle)); 126 | } 127 | } 128 | 129 | /// 130 | /// Import a CSV data stream into the table named inside the database. 131 | /// The table will be created if it doesn't exist yet. 132 | /// 133 | /// Open database connection 134 | /// Name of the table that should be filled with data from the CSV data stream. 135 | /// Data stream with CSV-formatted contents. 136 | /// Separator used for parsing the CSV. Defaults to comma. 137 | /// Maximum field size allowed. 138 | /// Thrown if any of , and are null. 139 | /// Thrown if an error is found while parsing the CSV data. 140 | public static void ImportCsvToTable(this SQLiteConnection db, string tableName, TextReader csvStream, CsvReader.SeparatorChar separator = CsvReader.SeparatorChar.Comma, int maxFieldSize = int.MaxValue) 141 | { 142 | if (db == null) 143 | { 144 | throw new ArgumentNullException(nameof(db)); 145 | } 146 | if (string.IsNullOrWhiteSpace(tableName)) 147 | { 148 | throw new ArgumentNullException(nameof(tableName)); 149 | } 150 | if (csvStream == null) 151 | { 152 | throw new ArgumentNullException(nameof(csvStream)); 153 | } 154 | 155 | var columns = new List(); 156 | bool parsingHeader = true; 157 | db.RunInTransaction(() => 158 | { 159 | foreach (string field in CsvReader.ParseStream(csvStream, separator, maxFieldSize)) 160 | { 161 | if (field == null) // newline 162 | { 163 | string joinedColumns = string.Join(", ", columns); 164 | if (parsingHeader) 165 | { 166 | db.Execute($"CREATE TABLE IF NOT EXISTS {tableName} ({joinedColumns})"); 167 | parsingHeader = false; 168 | } 169 | else 170 | { 171 | db.Execute($"INSERT INTO {tableName} VALUES ({joinedColumns})"); 172 | } 173 | columns.Clear(); 174 | } 175 | else 176 | { 177 | if (parsingHeader && string.IsNullOrWhiteSpace(field)) 178 | { 179 | throw new CsvException("Header cannot have empty column name."); 180 | } 181 | 182 | columns.Add(SQLiteConnection.Quote(field)); 183 | } 184 | } 185 | }); 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /Runtime/SQLitePreparedStatement.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Gil Barbosa Reis 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Runtime.InteropServices; 25 | 26 | namespace SQLite 27 | { 28 | /// 29 | /// Low level SQLite prepared statement object. 30 | /// 31 | /// 32 | /// Using this is the same as using prepared statments in the SQLite C API. 33 | /// You need to bind all arguments to the statement, manually step for each row and until done, get values from the 34 | /// returned columns, manually reset for subsequent executions, then dispose when not needed anymore. 35 | /// 36 | public class SQLitePreparedStatement : IDisposable 37 | { 38 | private static readonly IntPtr SQLITE_STATIC = IntPtr.Zero; 39 | 40 | private SQLiteConnection _db; 41 | private IntPtr _preparedStatement; 42 | 43 | public SQLitePreparedStatement(SQLiteConnection db, string statement) 44 | { 45 | if (db == null) 46 | { 47 | throw new ArgumentNullException(nameof(db)); 48 | } 49 | 50 | _db = db; 51 | _preparedStatement = SQLite3.Prepare2(db.Handle, statement); 52 | } 53 | 54 | ~SQLitePreparedStatement() 55 | { 56 | Dispose(); 57 | } 58 | 59 | public SQLite3.Result Reset() 60 | { 61 | ThrowIfDisposed(); 62 | return SQLite3.Reset(_preparedStatement); 63 | } 64 | 65 | public SQLite3.Result Bind(int index, bool value) 66 | { 67 | ThrowIfDisposed(); 68 | return (SQLite3.Result) SQLite3.BindInt(_preparedStatement, index, value ? 1 : 0); 69 | } 70 | public SQLite3.Result Bind(string name, bool value) 71 | { 72 | ThrowIfDisposed(); 73 | int index = SQLite3.BindParameterIndex(_preparedStatement, name); 74 | return Bind(index, value); 75 | } 76 | 77 | public SQLite3.Result Bind(int index, int value) 78 | { 79 | ThrowIfDisposed(); 80 | return (SQLite3.Result) SQLite3.BindInt(_preparedStatement, index, value); 81 | } 82 | public SQLite3.Result Bind(string name, int value) 83 | { 84 | ThrowIfDisposed(); 85 | int index = SQLite3.BindParameterIndex(_preparedStatement, name); 86 | return Bind(index, value); 87 | } 88 | 89 | public SQLite3.Result Bind(int index, long value) 90 | { 91 | ThrowIfDisposed(); 92 | return (SQLite3.Result) SQLite3.BindInt64(_preparedStatement, index, value); 93 | } 94 | public SQLite3.Result Bind(string name, long value) 95 | { 96 | ThrowIfDisposed(); 97 | int index = SQLite3.BindParameterIndex(_preparedStatement, name); 98 | return Bind(index, value); 99 | } 100 | 101 | public SQLite3.Result Bind(int index, float value) 102 | { 103 | ThrowIfDisposed(); 104 | return (SQLite3.Result) SQLite3.BindDouble(_preparedStatement, index, value); 105 | } 106 | public SQLite3.Result Bind(string name, float value) 107 | { 108 | ThrowIfDisposed(); 109 | int index = SQLite3.BindParameterIndex(_preparedStatement, name); 110 | return Bind(index, value); 111 | } 112 | 113 | public SQLite3.Result Bind(int index, double value) 114 | { 115 | ThrowIfDisposed(); 116 | return (SQLite3.Result) SQLite3.BindDouble(_preparedStatement, index, value); 117 | } 118 | public SQLite3.Result Bind(string name, double value) 119 | { 120 | ThrowIfDisposed(); 121 | int index = SQLite3.BindParameterIndex(_preparedStatement, name); 122 | return Bind(index, value); 123 | } 124 | 125 | public SQLite3.Result Bind(int index, string value) 126 | { 127 | ThrowIfDisposed(); 128 | return (SQLite3.Result) SQLite3.BindText(_preparedStatement, index, value, value.Length * sizeof(char), SQLITE_STATIC); 129 | } 130 | public SQLite3.Result Bind(string name, string value) 131 | { 132 | ThrowIfDisposed(); 133 | int index = SQLite3.BindParameterIndex(_preparedStatement, name); 134 | return Bind(index, value); 135 | } 136 | 137 | public SQLite3.Result Bind(int index, byte[] value) 138 | { 139 | ThrowIfDisposed(); 140 | return (SQLite3.Result) SQLite3.BindBlob(_preparedStatement, index, value, value.Length, SQLITE_STATIC); 141 | } 142 | public SQLite3.Result Bind(string name, byte[] value) 143 | { 144 | ThrowIfDisposed(); 145 | int index = SQLite3.BindParameterIndex(_preparedStatement, name); 146 | return Bind(index, value); 147 | } 148 | 149 | public int BindParameterIndex(string name) 150 | { 151 | ThrowIfDisposed(); 152 | return SQLite3.BindParameterIndex(_preparedStatement, name); 153 | } 154 | 155 | public SQLite3.Result Step() 156 | { 157 | ThrowIfDisposed(); 158 | var result = SQLite3.Step(_preparedStatement); 159 | if (result > SQLite3.Result.OK && result < SQLite3.Result.Row) 160 | { 161 | throw SQLiteException.New(result, SQLite3.GetErrmsg(_db.Handle)); 162 | } 163 | return result; 164 | } 165 | 166 | public int GetColumnCount() 167 | { 168 | ThrowIfDisposed(); 169 | return SQLite3.ColumnCount(_preparedStatement); 170 | } 171 | 172 | public string GetColumnName(int column) 173 | { 174 | ThrowIfDisposed(); 175 | return SQLite3.ColumnName16(_preparedStatement, column); 176 | } 177 | 178 | public IEnumerable EnumerateColumnNames() 179 | { 180 | for (int i = 0, columnCount = GetColumnCount(); i < columnCount; i++) 181 | { 182 | yield return GetColumnName(i); 183 | } 184 | } 185 | 186 | public IEnumerable EnumerateColumnsAsText() 187 | { 188 | for (int i = 0, columnCount = GetColumnCount(); i < columnCount; i++) 189 | { 190 | yield return GetString(i); 191 | } 192 | } 193 | 194 | public bool GetBool(int column) 195 | { 196 | ThrowIfDisposed(); 197 | return SQLite3.ColumnInt(_preparedStatement, column) != 0; 198 | } 199 | 200 | public int GetInt(int column) 201 | { 202 | ThrowIfDisposed(); 203 | return SQLite3.ColumnInt(_preparedStatement, column); 204 | } 205 | 206 | public long GetLong(int column) 207 | { 208 | ThrowIfDisposed(); 209 | return SQLite3.ColumnInt64(_preparedStatement, column); 210 | } 211 | 212 | public float GetFloat(int column) 213 | { 214 | ThrowIfDisposed(); 215 | return (float) SQLite3.ColumnDouble(_preparedStatement, column); 216 | } 217 | 218 | public double GetDouble(int column) 219 | { 220 | ThrowIfDisposed(); 221 | return SQLite3.ColumnDouble(_preparedStatement, column); 222 | } 223 | 224 | public string GetString(int column) 225 | { 226 | ThrowIfDisposed(); 227 | IntPtr ptr = SQLite3.ColumnText16(_preparedStatement, column); 228 | if (ptr == IntPtr.Zero) 229 | { 230 | return null; 231 | } 232 | int sizeInBytes = SQLite3.ColumnBytes16(_preparedStatement, column); 233 | return Marshal.PtrToStringUni(ptr, sizeInBytes / sizeof(char)); 234 | } 235 | 236 | public byte[] GetBytes(int column) 237 | { 238 | ThrowIfDisposed(); 239 | IntPtr blob = SQLite3.ColumnBlob(_preparedStatement, column); 240 | if (blob == IntPtr.Zero) 241 | { 242 | return null; 243 | } 244 | int sizeInBytes = SQLite3.ColumnBytes(_preparedStatement, column); 245 | var value = new byte[sizeInBytes]; 246 | Marshal.Copy(blob, value, 0, sizeInBytes); 247 | return value; 248 | } 249 | 250 | public void Dispose() 251 | { 252 | SQLite3.Finalize(_preparedStatement); 253 | _preparedStatement = IntPtr.Zero; 254 | _db = null; 255 | } 256 | 257 | private void ThrowIfDisposed() 258 | { 259 | if (_preparedStatement == IntPtr.Zero) 260 | { 261 | throw new ObjectDisposedException(nameof(_preparedStatement)); 262 | } 263 | } 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /Plugins/idbvfs/idbvfs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This is free and unencumbered software released into the public domain. 3 | * 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or 5 | * distribute this software, either in source code form or as a compiled 6 | * binary, for any purpose, commercial or non-commercial, and by any 7 | * means. 8 | * 9 | * In jurisdictions that recognize copyright laws, the author or authors 10 | * of this software dedicate any and all copyright interest in the 11 | * software to the public domain. We make this dedication for the benefit 12 | * of the public at large and to the detriment of our heirs and 13 | * successors. We intend this dedication to be an overt act of 14 | * relinquishment in perpetuity of all present and future rights to this 15 | * software under copyright law. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * For more information, please refer to 26 | */ 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "SQLiteVfs.h" 36 | 37 | #include "idbvfs.h" 38 | 39 | /// Used size for Indexed DB "disk sectors" 40 | #ifndef DISK_SECTOR_SIZE 41 | #define DISK_SECTOR_SIZE 32 42 | #endif 43 | 44 | /// Indexed DB key used to store idbvfs file sizes 45 | #define IDBVFS_SIZE_KEY "file_size" 46 | 47 | 48 | #ifdef __EMSCRIPTEN__ 49 | #include 50 | #define INLINE_JS(...) EM_ASM(__VA_ARGS__) 51 | #else 52 | #define INLINE_JS(...) 53 | #endif 54 | 55 | 56 | #ifdef TRACE 57 | static void TRACE_LOG(const char *fmt, ...) { 58 | va_list args; 59 | va_start(args, fmt); 60 | static char _idbvfs_trace_log_buffer[1024]; 61 | vsnprintf(_idbvfs_trace_log_buffer, sizeof(_idbvfs_trace_log_buffer), fmt, args); 62 | #ifdef __EMSCRIPTEN__ 63 | EM_ASM({ console.log(UTF8ToString($0)) }, _idbvfs_trace_log_buffer); 64 | #else 65 | printf("%s\n", _idbvfs_trace_log_buffer); 66 | #endif 67 | va_end(args); 68 | } 69 | #else 70 | #define TRACE_LOG(...) 71 | #endif 72 | 73 | using namespace sqlitevfs; 74 | 75 | class IdbPage { 76 | public: 77 | IdbPage() {} 78 | 79 | IdbPage(const char *dbname, const char *subfilename) 80 | : dbname(dbname) 81 | , filename(dbname) 82 | { 83 | filename.append("/"); 84 | filename.append(subfilename); 85 | } 86 | 87 | IdbPage(const char *dbname, int page_number) 88 | : IdbPage(dbname, std::to_string(page_number).c_str()) 89 | { 90 | } 91 | 92 | bool exists() const { 93 | if (FILE *f = fopen(filename.c_str(), "r")) { 94 | fclose(f); 95 | return true; 96 | } 97 | else { 98 | return false; 99 | } 100 | } 101 | 102 | int load_into(void *data, size_t data_size, sqlite3_int64 offset_in_page = 0) const { 103 | if (FILE *f = fopen(filename.c_str(), "r")) { 104 | if (offset_in_page > 0) { 105 | fseek(f, offset_in_page, SEEK_SET); 106 | } 107 | size_t read_bytes = fread(data, 1, data_size, f); 108 | fclose(f); 109 | return read_bytes; 110 | } 111 | else { 112 | return 0; 113 | } 114 | } 115 | 116 | int load_into(std::vector& out_buffer, size_t data_size) const { 117 | out_buffer.resize(data_size); 118 | return load_into(out_buffer.data(), data_size); 119 | } 120 | 121 | int scan_into(const char *fmt, ...) const { 122 | if (FILE *f = fopen(filename.c_str(), "r")) { 123 | va_list args; 124 | va_start(args, fmt); 125 | int assigned_items = vfscanf(f, fmt, args); 126 | va_end(args); 127 | fclose(f); 128 | return assigned_items; 129 | } 130 | else { 131 | return 0; 132 | } 133 | } 134 | 135 | int store(const void *data, size_t data_size) const { 136 | mkdir(dbname, 0777); 137 | 138 | if (FILE *f = fopen(filename.c_str(), "w")) { 139 | size_t written_bytes = fwrite(data, 1, data_size, f); 140 | fclose(f); 141 | return written_bytes; 142 | } 143 | else { 144 | return 0; 145 | } 146 | } 147 | 148 | int store(const std::vector& data) const { 149 | return store(data.data(), data.size()); 150 | } 151 | 152 | int store(const std::string& data) const { 153 | return store(data.c_str(), data.size()); 154 | } 155 | 156 | bool remove() const { 157 | return unlink(filename.c_str()) == 0; 158 | } 159 | 160 | private: 161 | const char *dbname; 162 | std::string filename; 163 | }; 164 | 165 | struct IdbFileSize : public IdbPage { 166 | IdbFileSize() : IdbPage() {} 167 | IdbFileSize(sqlite3_filename file_name, bool autoload = true) : IdbPage(file_name, IDBVFS_SIZE_KEY) { 168 | if (autoload) { 169 | load(); 170 | } 171 | } 172 | 173 | void load() { 174 | scan_into("%lu", &file_size); 175 | is_dirty = false; 176 | } 177 | 178 | size_t get() const { 179 | return file_size; 180 | } 181 | 182 | void set(size_t new_file_size) { 183 | if (new_file_size != file_size) { 184 | file_size = new_file_size; 185 | is_dirty = true; 186 | } 187 | } 188 | 189 | void update_if_greater(size_t new_file_size) { 190 | if (new_file_size > file_size) { 191 | set(new_file_size); 192 | } 193 | } 194 | 195 | bool sync() const { 196 | if (is_dirty) { 197 | return store(std::to_string(file_size)) > 0; 198 | } 199 | else { 200 | return true; 201 | } 202 | } 203 | 204 | private: 205 | size_t file_size = 0; 206 | bool is_dirty = false; 207 | }; 208 | 209 | struct IdbFile : public SQLiteFileImpl { 210 | sqlite3_filename file_name; 211 | IdbFileSize file_size; 212 | std::vector journal_data; 213 | bool is_db; 214 | 215 | IdbFile() {} 216 | IdbFile(sqlite3_filename file_name, bool is_db) : file_name(file_name), file_size(file_name), is_db(is_db) {} 217 | 218 | int iVersion() const override { 219 | return 1; 220 | } 221 | 222 | int xClose() override { 223 | return SQLITE_OK; 224 | } 225 | 226 | int xRead(void *p, int iAmt, sqlite3_int64 iOfst) override { 227 | TRACE_LOG("READ %s %d @ %ld", file_name, iAmt, iOfst); 228 | if (iAmt + iOfst > file_size.get()) { 229 | TRACE_LOG(" > %d", false); 230 | return SQLITE_IOERR_SHORT_READ; 231 | } 232 | 233 | int result; 234 | if (is_db) { 235 | result = readDb(p, iAmt, iOfst); 236 | } 237 | else { 238 | result = readJournal(p, iAmt, iOfst); 239 | } 240 | TRACE_LOG(" > %d", result); 241 | return result; 242 | } 243 | 244 | int xWrite(const void *p, int iAmt, sqlite3_int64 iOfst) override { 245 | TRACE_LOG("WRITE %s %d @ %ld", file_name, iAmt, iOfst); 246 | int result; 247 | if (is_db) { 248 | result = writeDb(p, iAmt, iOfst); 249 | } 250 | else { 251 | result = writeJournal(p, iAmt, iOfst); 252 | } 253 | TRACE_LOG(" > %d", result); 254 | return result; 255 | } 256 | 257 | int xTruncate(sqlite3_int64 size) override { 258 | TRACE_LOG("TRUNCATE %s to %ld", file_name, size); 259 | file_size.set(size); 260 | TRACE_LOG(" > %d", true); 261 | return SQLITE_OK; 262 | } 263 | 264 | int xSync(int flags) override { 265 | TRACE_LOG("SYNC %s %d", file_name, flags); 266 | // journal data is stored in-memory and synced all at once 267 | if (!journal_data.empty()) { 268 | IdbPage file(file_name, 0); 269 | file.store(journal_data); 270 | file_size.set(journal_data.size()); 271 | } 272 | bool success = file_size.sync(); 273 | INLINE_JS({ 274 | Module.idbvfsSyncfs(); 275 | }); 276 | TRACE_LOG(" > %d", success); 277 | return success ? SQLITE_OK : SQLITE_IOERR_FSYNC; 278 | } 279 | 280 | int xFileSize(sqlite3_int64 *pSize) override { 281 | TRACE_LOG("FILE SIZE %s", file_name); 282 | if (!journal_data.empty()) { 283 | *pSize = journal_data.size(); 284 | } 285 | else { 286 | *pSize = file_size.get(); 287 | } 288 | TRACE_LOG(" > %d", *pSize); 289 | return SQLITE_OK; 290 | } 291 | 292 | int xLock(int flags) override { 293 | return SQLITE_OK; 294 | } 295 | 296 | int xUnlock(int flags) override { 297 | return SQLITE_OK; 298 | } 299 | 300 | int xCheckReservedLock(int *pResOut) override { 301 | *pResOut = 0; 302 | return SQLITE_OK; 303 | } 304 | 305 | int xFileControl(int op, void *pArg) override { 306 | switch (op) { 307 | case SQLITE_FCNTL_VFSNAME: 308 | *(char **) pArg = sqlite3_mprintf("%z", IDBVFS_NAME); 309 | return SQLITE_OK; 310 | } 311 | return SQLITE_NOTFOUND; 312 | } 313 | 314 | int xSectorSize() override { 315 | return DISK_SECTOR_SIZE; 316 | } 317 | 318 | int xDeviceCharacteristics() override { 319 | return 0; 320 | } 321 | 322 | private: 323 | int readDb(void *p, int iAmt, sqlite3_int64 iOfst) { 324 | int page_number; 325 | sqlite3_int64 offset_in_page; 326 | if (iOfst + iAmt >= 512) { 327 | if (iOfst % iAmt != 0) { 328 | return SQLITE_IOERR_READ; 329 | } 330 | page_number = iOfst / iAmt; 331 | offset_in_page = 0; 332 | } else { 333 | page_number = 0; 334 | offset_in_page = iOfst; 335 | } 336 | 337 | IdbPage page(file_name, page_number); 338 | int loaded_bytes = page.load_into((uint8_t*) p, iAmt, offset_in_page); 339 | if (loaded_bytes < iAmt) { 340 | return SQLITE_IOERR_SHORT_READ; 341 | } 342 | else { 343 | return SQLITE_OK; 344 | } 345 | } 346 | 347 | int readJournal(void *p, int iAmt, sqlite3_int64 iOfst) { 348 | if (journal_data.empty()) { 349 | size_t journal_size = file_size.get(); 350 | if (journal_size > 0) { 351 | IdbPage page(file_name, 0); 352 | page.load_into(journal_data, journal_size); 353 | } 354 | } 355 | if (iAmt + iOfst > journal_data.size()) { 356 | return SQLITE_IOERR_SHORT_READ; 357 | } 358 | memcpy(p, journal_data.data() + iOfst, iAmt); 359 | return SQLITE_OK; 360 | } 361 | 362 | int writeDb(const void *p, int iAmt, sqlite3_int64 iOfst) { 363 | int page_number = iOfst ? iOfst / iAmt : 0; 364 | 365 | IdbPage page(file_name, page_number); 366 | int stored_bytes = page.store(p, iAmt); 367 | if (stored_bytes < iAmt) { 368 | return SQLITE_IOERR_WRITE; 369 | } 370 | 371 | file_size.update_if_greater(iAmt + iOfst); 372 | return SQLITE_OK; 373 | } 374 | 375 | int writeJournal(const void *p, int iAmt, sqlite3_int64 iOfst) { 376 | if (iAmt + iOfst > journal_data.size()) { 377 | journal_data.resize(iAmt + iOfst); 378 | } 379 | memcpy(journal_data.data() + iOfst, p, iAmt); 380 | return SQLITE_OK; 381 | } 382 | }; 383 | 384 | struct IdbVfs : public SQLiteVfsImpl { 385 | int xOpen(sqlite3_filename zName, SQLiteFile *file, int flags, int *pOutFlags) override { 386 | TRACE_LOG("OPEN %s", zName); 387 | bool is_db = (flags & SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_TEMP_DB); 388 | file->implementation = IdbFile(zName, is_db); 389 | return SQLITE_OK; 390 | } 391 | 392 | int xDelete(const char *zName, int syncDir) override { 393 | TRACE_LOG("DELETE %s", zName); 394 | IdbFileSize file_size(zName, false); 395 | if (!file_size.remove()) { 396 | return SQLITE_IOERR_DELETE; 397 | } 398 | 399 | for (int i = 0; ; i++) { 400 | IdbPage page(zName, i); 401 | if (!page.remove()) { 402 | break; 403 | } 404 | } 405 | rmdir(zName); 406 | return SQLITE_OK; 407 | } 408 | 409 | int xAccess(const char *zName, int flags, int *pResOut) override { 410 | TRACE_LOG("ACCESS %s %d", zName, flags); 411 | switch (flags) { 412 | case SQLITE_ACCESS_EXISTS: 413 | case SQLITE_ACCESS_READWRITE: 414 | case SQLITE_ACCESS_READ: 415 | IdbFileSize file_size(zName, false); 416 | *pResOut = file_size.exists(); 417 | TRACE_LOG(" > %d", *pResOut); 418 | return SQLITE_OK; 419 | } 420 | return SQLITE_NOTFOUND; 421 | } 422 | 423 | #ifdef __EMSCRIPTEN__ 424 | int xFullPathname(const char *zName, int nOut, char *zOut) override { 425 | TRACE_LOG("FULL PATH %s", zName); 426 | if (zName[0] == '/') { 427 | strncpy(zOut, zName, nOut); 428 | } 429 | else { 430 | snprintf(zOut, nOut, "/idbfs/%s", zName); 431 | } 432 | TRACE_LOG(" > %s", zOut); 433 | return SQLITE_OK; 434 | } 435 | #endif 436 | }; 437 | 438 | extern "C" { 439 | const char *IDBVFS_NAME = "idbvfs"; 440 | 441 | int idbvfs_register(int makeDefault) { 442 | static SQLiteVfs idbvfs(IDBVFS_NAME); 443 | INLINE_JS({ 444 | if (!Module.idbvfsSyncfs) { 445 | // Run FS.syncfs in a queue, to avoid concurrent execution errors 446 | var syncQueue = 0; 447 | function doSync() { 448 | FS.syncfs(false, function() { 449 | syncQueue--; 450 | if (syncQueue > 0) { 451 | doSync(); 452 | } 453 | }); 454 | } 455 | Module.idbvfsSyncfs = function() { 456 | syncQueue++; 457 | if (syncQueue == 1) { 458 | doSync(); 459 | } 460 | }; 461 | } 462 | }); 463 | return idbvfs.register_vfs(makeDefault); 464 | } 465 | } 466 | --------------------------------------------------------------------------------