{"id":20416997,"url":"https://github.com/smourier/sqlnado","last_synced_at":"2025-04-12T17:14:41.080Z","repository":{"id":65371592,"uuid":"106116880","full_name":"smourier/SQLNado","owner":"smourier","description":"SQLNado (SQLite Not ADO) is a .NET lightweight bloat free wrapper and object persistence framework based on SQLite.","archived":false,"fork":false,"pushed_at":"2025-01-04T13:59:45.000Z","size":47589,"stargazers_count":31,"open_issues_count":0,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-12T17:14:35.819Z","etag":null,"topics":["csharp","netcore","netframework","netstandard20","sqlite"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smourier.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-07T17:27:44.000Z","updated_at":"2025-02-01T18:55:20.000Z","dependencies_parsed_at":"2024-01-02T11:30:34.514Z","dependency_job_id":"e204f3e5-deff-4ac4-b39a-c20384d72da2","html_url":"https://github.com/smourier/SQLNado","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smourier%2FSQLNado","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smourier%2FSQLNado/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smourier%2FSQLNado/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smourier%2FSQLNado/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smourier","download_url":"https://codeload.github.com/smourier/SQLNado/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248602313,"owners_count":21131616,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","netcore","netframework","netstandard20","sqlite"],"created_at":"2024-11-15T06:24:03.715Z","updated_at":"2025-04-12T17:14:41.053Z","avatar_url":"https://github.com/smourier.png","language":"C#","readme":"# SQLNado\nSQLNado (SQLite Not ADO) is a .NET lightweight bloat free object persistence framework based on SQLite.\n\nSQLNado supports all of SQLite features when using SQL commands, and also supports most of SQLite features through .NET:\n\n* Automatic class-to-table mapping (Save, Delete, Load, LoadAll, LoadByPrimaryKey, LoadByForeignKey, etc.)\n* Automatic synchronization of schema (tables, columns) between classes and existing table\n* Designed for thread-safe operations\n* Where and OrderBy LINQ/IQueryable .NET expressions are supported (work is still in progress in this area), also with collation support\n* SQLite database schema (tables, columns, etc.) exposed to .NET\n* SQLite custom functions can be written in .NET\n* SQLite incremental BLOB I/O is exposed as a .NET Stream to avoid high memory consumption\n* SQLite  collation support, including the possibility to add custom collations using .NET code\n* SQLite Full Text Search engine (FTS3/4) support, including the possibility to add custom FTS3 tokenizers using .NET code\n* Automatic support for Windows 'winsqlite3.dll' to avoid shipping any binary file.\n\n## Cross-Platform\nSince version 2, the whole of SQLNado is now cross-platform enabled. It currently supports Linux, Windows and Android, but more will follow (iOS, MacOS, etc.). Obviously, you need a platform with C# support.\n\n*Note: the Nuget is still currently on the old version as the version 2 is still being tested*.\n\n## Requirements\nOn **Windows**, the only requirement is netstandard 2.0 or .NET Framework 4.6, so it works fine with .NET Core to .NET 7+ too. It's 100% dependency free! Well, of course it requires an SQLite native dlls corresponding to the bitness (x86 vs x64) of the executing app.\n\nOn **Linux**, the only requirement, beside .NET Core, is to have libsqlite3.so (or similar) available to the project you're working on.\n\nOn **Android** (Xamarin/MAUI), the only requirement is to have some version of the sqlite shared library available to the project you're working on.\n\nYou can use the library proposed by sqlite.org itself, ie:\n\n    * download library from https://www.sqlite.org/download.html (\"Precompiled Binaries for Android\")\n    * unzip it and copy \"sqlite-android-[some version like 3410000]\\jni\" directory into your \"Platform\\Android\" directory or somewhere suitable\n    * set \"Build Action\" of all .so to \"AndroidNativeLibrary\"\n\nBut you can also used other libraries (like the one from built by https://github.com/ericsink/SQLitePCL.raw).\n\n## Installation on Windows\nIf you're running on a recent Windows 10 or Windows Server 2016+, there is a good chance that there's already a `winsqlite3.dll` file present in `\\Windows\\System32`. If this is the case, you won't need to install any native dll, whatever the bitness (x86 vs x64) of your app is!\n\nNote this is also true on Azure Web Apps, you don't need to add anything to be able to work with SQLite if you use SQLNado.\n\nOtherwise, you can use the sqlite dll files from https://www.sqlite.org/download.html. We usually recommend to rename the original sqlite.dll for 32 *and* 64-bit to `sqlite.x86.dll` and `sqlite.x64.dll` respectively so you can distribute both in the same directory.\n\nOr you can get them from here already renamed: https://github.com/smourier/SQLNado/tree/master/SqlNado.\n\nOnce you have these files, you can copy them aside your running executable (or *bin* directory for a web site).\nSQLNado source code expects that and this way your program will be able to run as 32-bit or as 64-bit without having to change the native sqlite .dll. You won't have to build two setups either. \n\nIf you don't like all this and want to keep the original SQLite dll untouched, or even bring your own SQLite dll, you can just copy the corresponding .dll aside your running executable also, but make sure you use the proper 32 or 64-bit version.\n\n## Installation on Linux\nWe recommend to use SQLNado amalgamation (one unique .cs file). In this mode you just need to to make sure *libsqlite3-0* or *libsqlite3-dev* is installed and accessible to the .NET project you're working on, there's nothing specific to do beside include `sqlnado.cs`.\n\n## Installation on Android\nWe recommend to use SQLNado amalgamation (one unique .cs file). In this mode you just need to to make sure the SQLite Android shared library is packaged with the .NET project you're working on, there's nothing specific to do beside include `sqlnado.cs`.\nSee here for more on this subject: https://learn.microsoft.com/en-us/xamarin/android/platform/native-libraries\n\n## Amalgamation\nAlthough SQLNado can be used as a Nuget, we also provide it as a single, 100% independent, C# file located here https://github.com/smourier/SQLNado/tree/master/Amalgamation\n\nThe amalgamation contains everything an application needs to embed SQLNado. Combining all the code for SQLNado into one big file makes it easier to deploy — there is just one file to keep track of (yeah, I borrowed that phrase from SQLite's site https://www.sqlite.org/amalgamation.html page because it's cool)\n\n## Nuget\nDue to popular request, SQLNado is now also provided as a Nuget. You can download here from https://www.nuget.org/packages/SqlNado/\n*Note: the Nuget is still currently on the old version as the version 2 is being tested*\n\n## Get Started\nHere is a simple Console App that should get you started:\n\n```csharp\n// this will create the my.db file if it does not exists\nusing (var db = new SQLiteDatabase(\"my.db\"))\n{\n    var customer = new Customer();\n    customer.Email = \"killroy@example.com\";\n    customer.Name = \"Killroy\";\n\n    // updates or Insert (choice is made if there is already a primary key on the object).\n    // by default, the Save operation synchronize the table schema.\n    // if this is run for the first time, it will create the table using Customer type definition (properties).\n    db.Save(customer);\n\n    // dumps the customer list to the console\n    db.LoadAll\u003cCustomer\u003e().ToTableString(Console.Out);\n\n    // dumps the sql query result to the console (should be the same as previous)\n    db.LoadRows(\"SELECT * FROM Customer\").ToTableString(Console.Out);\n\n    // dumps the Customer table schema to the console\n    TableStringExtensions.ToTableString(db.GetTable\u003cCustomer\u003e(), Console.Out);\n\n    // dumps the Customer table columns definitions to the console\n    db.GetTable\u003cCustomer\u003e().Columns.ToTableString(Console.Out);\n}\n\npublic class Customer\n{\n    [SQLiteColumn(IsPrimaryKey = true)]\n    public string Email { get; set; }\n    public string Name { get; set; }\n}\n```\nWhen you run it, you should see this on the console.\n![Console Output](/Doc/Images/TableString1.png?raw=true)\n\nThese nice table outputs are created automatically by the [TableString](/SqlNado/Utilities/TableString.cs) utility that's part of SQLNado (but the file can be copied in any other C# project as it's self-sufficient).\n\n`TableString` computes tables from any `IEnumerable` instance. It works also for any object, like the Customer table schema example, but for object that are not IEnumerable there's not extension method, you have to use TableString or TableStringExtensions). What's cool is it computes columns widths so can fit within the console bounds. When working with tables from a database, it's *very* useful.\n\n## FTS custom tokenizer support\nSQLNado offers the possibility to use a custom FTS3 tokenizer to SQLite FTS engine. This allows you to code a stop word tokenizer for example. Here is a sample code:\n\n```csharp\nusing (var db = new SQLiteDatabase(\":memory:\"))\n{\n    // we must enable custom tokenizers\n    db.Configure(SQLiteDatabaseConfiguration.SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1);\n    var tok = new StopWordTokenizer(db);\n    db.SetTokenizer(tok);\n\n    // insert data as in SQLite exemple\n    db.Save(new Mail { docid = 1, Subject = \"software feedback\", Body = \"found it too slow\" });\n    db.Save(new Mail { docid = 2, Subject = \"software feedback\", Body = \"no feedback\" });\n    db.Save(new Mail { docid = 3, Subject = \"slow lunch order\", Body = \"was a software problem\" });\n\n    // check result\n    db.LoadAll\u003cMail\u003e().ToTableString(Console.Out);\n\n    // this shall report the same as in SQLite example\n    db.Load\u003cMail\u003e(\"WHERE Subject MATCH 'software'\").ToTableString(Console.Out);\n    db.Load\u003cMail\u003e(\"WHERE body MATCH 'feedback'\").ToTableString(Console.Out);\n    db.Load\u003cMail\u003e(\"WHERE mail MATCH 'software'\").ToTableString(Console.Out);\n    db.Load\u003cMail\u003e(\"WHERE mail MATCH 'slow'\").ToTableString(Console.Out);\n\n    // this should display nothing as 'no' is a stop word\n    db.Load\u003cMail\u003e(\"WHERE mail MATCH 'no'\").ToTableString(Console.Out);\n}\n\n[SQLiteTable(Module = \"fts3\", ModuleArguments = nameof(Subject) + \", \" + nameof(Body) + \", tokenize=\" + StopWordTokenizer.TokenizerName)]\npublic class Mail\n{\n    public long docid { get; set; }\n    public string Subject { get; set; }\n    public string Body { get; set; }\n\n    public override string ToString() =\u003e Subject + \":\" + Body;\n}\n\npublic class StopWordTokenizer : SQLiteTokenizer\n{\n    public const string TokenizerName = \"unicode_stopwords\";\n\n    private static readonly HashSet\u003cstring\u003e _words;\n    private readonly SQLiteTokenizer _unicode;\n    private int _disposed;\n\n    static StopWordTokenizer()\n    {\n        // define some stop words here\n        _words = new HashSet\u003cstring\u003e {\n            \"a\",\n            \"it\",\n            \"no\",\n            \"too\",\n            \"was\",\n            };\n    }\n\n    public StopWordTokenizer(SQLiteDatabase database, params string[] arguments)\n        : base(database, TokenizerName)\n    {\n        // we reuse SQLite's unicode61 tokenize\n        _unicode = database.GetUnicodeTokenizer(arguments);\n    }\n\n    public override IEnumerable\u003cSQLiteToken\u003e Tokenize(string input)\n    {\n        foreach (var token in _unicode.Tokenize(input))\n        {\n            if (!_words.Contains(token.Text))\n                yield return token;\n        }\n    }\n\n    // we need this because SQLite's unicode61 tokenizer aggregates unmanaged resources\n    protected override void Dispose(bool disposing)\n    {\n        var disposed = Interlocked.Exchange(ref _disposed, 1);\n        if (disposed != 0)\n            return;\n\n        if (disposing)\n        {\n            _unicode.Dispose();\n        }\n\n        base.Dispose(disposing);\n    }\n}\n```\nWhen you run it, you should see this on the console.\n![Console Output](/Doc/Images/Fts.png?raw=true)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmourier%2Fsqlnado","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmourier%2Fsqlnado","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmourier%2Fsqlnado/lists"}