{"id":19993070,"url":"https://github.com/jchristn/DatabaseWrapper","last_synced_at":"2025-05-04T12:30:46.124Z","repository":{"id":37548340,"uuid":"64442554","full_name":"jchristn/DatabaseWrapper","owner":"jchristn","description":"Simple database wrapper for Microsoft SQL Server, MySQL, PostgreSQL, and Sqlite written in C# supporting dynamic query building and nesting using expressions.","archived":false,"fork":false,"pushed_at":"2025-01-23T18:11:33.000Z","size":15981,"stargazers_count":100,"open_issues_count":2,"forks_count":27,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-14T16:01:25.670Z","etag":null,"topics":["database","databasewrapper","db","microsoft-sql-server","mssql","mysql","nuget","orm","postgresql"],"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/jchristn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","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},"funding":{"github":["jchristn"],"custom":["https://paypal.me/joelchristner"]}},"created_at":"2016-07-29T02:07:23.000Z","updated_at":"2025-04-05T16:22:21.000Z","dependencies_parsed_at":"2024-09-20T18:16:13.288Z","dependency_job_id":"8c656d03-6575-4577-a36b-63a45a39778b","html_url":"https://github.com/jchristn/DatabaseWrapper","commit_stats":{"total_commits":124,"total_committers":2,"mean_commits":62.0,"dds":"0.024193548387096753","last_synced_commit":"f93176a89653fd39c29cd243d8ffcd25606db811"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FDatabaseWrapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FDatabaseWrapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FDatabaseWrapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FDatabaseWrapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jchristn","download_url":"https://codeload.github.com/jchristn/DatabaseWrapper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252334098,"owners_count":21731335,"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":["database","databasewrapper","db","microsoft-sql-server","mssql","mysql","nuget","orm","postgresql"],"created_at":"2024-11-13T04:52:26.908Z","updated_at":"2025-05-04T12:30:41.114Z","avatar_url":"https://github.com/jchristn.png","language":"C#","funding_links":["https://github.com/sponsors/jchristn","https://paypal.me/joelchristner"],"categories":["C\\#"],"sub_categories":[],"readme":"# DatabaseWrapper\n\n| Library | Version | Downloads |\n|---|---|---|\n| DatabaseWrapper (all supported database types) | [![NuGet Version](https://img.shields.io/nuget/v/DatabaseWrapper.svg?style=flat)](https://www.nuget.org/packages/DatabaseWrapper/)  | [![NuGet](https://img.shields.io/nuget/dt/DatabaseWrapper.svg)](https://www.nuget.org/packages/DatabaseWrapper) |\n| DatabaseWrapper.Mysql | [![NuGet Version](https://img.shields.io/nuget/v/DatabaseWrapper.Mysql.svg?style=flat)](https://www.nuget.org/packages/DatabaseWrapper.Mysql/)  | [![NuGet](https://img.shields.io/nuget/dt/DatabaseWrapper.Mysql.svg)](https://www.nuget.org/packages/DatabaseWrapper.Mysql) |\n| DatabaseWrapper.Postgresql | [![NuGet Version](https://img.shields.io/nuget/v/DatabaseWrapper.Postgresql.svg?style=flat)](https://www.nuget.org/packages/DatabaseWrapper.Postgresql/)  | [![NuGet](https://img.shields.io/nuget/dt/DatabaseWrapper.Postgresql.svg)](https://www.nuget.org/packages/DatabaseWrapper.Postgresql) |\n| DatabaseWrapper.Sqlite | [![NuGet Version](https://img.shields.io/nuget/v/DatabaseWrapper.Sqlite.svg?style=flat)](https://www.nuget.org/packages/DatabaseWrapper.Sqlite/)  | [![NuGet](https://img.shields.io/nuget/dt/DatabaseWrapper.Sqlite.svg)](https://www.nuget.org/packages/DatabaseWrapper.Sqlite) |\n| DatabaseWrapper.SqlServer | [![NuGet Version](https://img.shields.io/nuget/v/DatabaseWrapper.SqlServer.svg?style=flat)](https://www.nuget.org/packages/DatabaseWrapper.SqlServer/)  | [![NuGet](https://img.shields.io/nuget/dt/DatabaseWrapper.SqlServer.svg)](https://www.nuget.org/packages/DatabaseWrapper.SqlServer) |\n| DatabaseWrapper.Core | [![NuGet Version](https://img.shields.io/nuget/v/DatabaseWrapper.Core.svg?style=flat)](https://www.nuget.org/packages/DatabaseWrapper.Core/)  | [![NuGet](https://img.shields.io/nuget/dt/DatabaseWrapper.Core.svg)](https://www.nuget.org/packages/DatabaseWrapper.Core) |\n| ExpressionTree | [![NuGet Version](https://img.shields.io/nuget/v/ExpressionTree.svg?style=flat)](https://www.nuget.org/packages/ExpressionTree/)  | [![NuGet](https://img.shields.io/nuget/dt/ExpressionTree.svg)](https://www.nuget.org/packages/ExpressionTree) |\n\nDatabaseWrapper is the EASIEST and FASTEST way to get a data-driven application up and running using SQL Server, MySQL, PostgreSQL, or Sqlite.\n\nFor a sample app exercising this library, refer to the numerous ```Test``` projects contained within the solution.\n\nCore features:\n\n- Dynamic query building\n- Hierarchical Boolean logic using Expression objects\n- Support for SQL server native vs Windows authentication\n- Support for SELECT, INSERT, UPDATE, DELETE, TRUNCATE, CREATE, DROP or raw queries\n- Programmatic table creation and removal (drop)\n- Built-in sanitization\n- Support for .NET Standard, .NET Core, and .NET Framework\n- Support for SQL Server, Sqlite, PostgreSQL, MySQL, MariaDB, Oracle, both on-premises and in the cloud\n- Both synchronous and asynchronous APIs\n\n## New in v6.x\n\n- Oracle support (thank you @Skimmenthal13)\n- Asynchronous APIs\n- Updated dependencies\n- Bugfixes\n- Minor breaking changes (API name changes)\n\n## Special Thanks\n\nSpecial thanks to those who have helped contribute or otherwise improve the library!  \n\n@shawty @constantinje @thedarklort @l-404-l @igrgurina @Vaelek @treyhay31 @daoye @twobytescy @rinkusahu1 @Skimmenthal13\n\n## A Note on Sanitization\n\nUse of parameterized queries vs building queries dynamically is a sensitive subject.  Proponents of parameterized queries have data on their side - that parameterization does the right thing to prevent SQL injection and other issues.  *I do not disagree with them*.  However, it is worth noting that with proper care, you CAN build systems that allow you to dynamically build queries, and you SHOULD do so as long as you build in the appropriate safeguards.\n\nIf you find an injection attack that will defeat the sanitization layer built into this project, please let me know!\n\n## Simple Example\n\nRefer to the test project for a more complete example with sample table setup scripts.\n```csharp\nusing DatabaseWrapper;\nusing DatabaseWrapper.Core;\nusing ExpressionTree;\n\nDatabaseClient client = null;\n\n// Sqlite\nclient = new DatabaseClient(\"[databasefilename]\");\n\n// SQL Server, MySQL, or PostgreSQL\nclient = new DatabaseClient(DbTypes.SqlServer,  \"[hostname]\", [port], \"[user]\", \"[password]\", \"[databasename]\");\nclient = new DatabaseClient(DbTypes.Mysql,      \"[hostname]\", [port], \"[user]\", \"[password]\", \"[databasename]\");\nclient = new DatabaseClient(DbTypes.Postgresql, \"[hostname]\", [port], \"[user]\", \"[password]\", \"[databasename]\");\n\n// SQL Express\nclient = new DatabaseClient(DbTypes.SqlServer,  \"[hostname]\", [port], \"[user]\", \"[password]\", \"[instance]\", \"[databasename]\");\n\n// some variables we'll be using\nDictionary\u003cstring, object\u003e d;\nExpr e;\nList\u003cstring\u003e fields;\nDataTable result;\n\n// add a record\nd = new Dictionary\u003cstring, object\u003e();\nd.Add(\"firstName\", \"Joel\");\nd.Add(\"lastName\", \"Christner\");\nd.Add(\"notes\", \"Author\");\nresult = client.Insert(\"person\", d);\nresult = await client.InsertAsync(\"person\", d);\n\n// update a record\nd = new Dictionary\u003cstring, object\u003e();\nd.Add(\"notes\", \"The author :)\");\ne = new Expr(\"firstName\", OperatorEnum.Equals, \"Joel\"); \nclient.Update(\"person\", d, e);\nawait client.UpdateAsync(\"person\", d, e);\n\n// retrieve 10 records\nfields = new List\u003cstring\u003e { \"firstName\", \"lastName\" }; // leave null for *\ne = new Expr(\"lastName\", OperatorEnum.Equals, \"Christner\"); \nResultOrder[] order = new ResultOrder[1];\norder = new ResultOrder(\"firstName\", OrderDirectionEnum.Ascending)\nresult = client.Select(\"person\", 0, 10, fields, e, order);\nresult = await client.SelectAsync(\"person\", 0, 10, fields, e, order);\n\n// delete a record\ne = new Expr(\"firstName\", Operators.Equals, \"Joel\"); \nclient.Delete(\"person\", e);\nawait client.DeleteAsync(\"person\", e);\n\n// execute a raw query\nresult = client.Query(\"SELECT customer_id FROM customer WHERE customer_id \u003e 10\");\nresult = await client.QueryAsync(\"SELECT customer_id FROM customer WHERE customer_id \u003e 10\");\n```\n\n## Sample Compound Expression\n\nExpressions, i.e. the ```Expr``` class from ```ExpressionTree```, can be nested in either the ```Left``` or ```Right``` properties.  Conversion from ```Expr``` to a WHERE clause uses recursion, so you have a good degree of flexibility in building your expressions in terms of depth.\n\n```csharp\nExpr e = new Expr {\n\tLeft = new Expr(\"age\", OperatorEnum.GreaterThan, 30),\n\tOperator = Operators.And,\n\tRight = new Expr(\"height\", OperatorEnum.LessThan, 74)\n};\n```\n\n## Select with Pagination\n\nUse ```IndexStart```, ```MaxResults```, and ```ResultOrder[]``` to retrieve paginated results.  The query will retrieve maxResults records starting at row number indexStart using an ordering based on orderByClause.  See the example in the DatabaseWrapperTest project.\n\nIMPORTANT: When doing pagination with SQL Server, you MUST specify an ```ResultOrder[]```.\n\n```csharp\nResultOrder[] order = new ResultOrder[1];\norder = new ResultOrder(\"firstName\", OrderDirectionEnum.Ascending);\nDataTable result = client.Select(\"person\", 5, 10, null, e, order);\n```\n\n## Need a Timestamp?\n\nWe added a simple static method for this which you can use when building expressions (or elsewhere).  An object method exists as well.\n\n```csharp\nstring ts = client.Timestamp(DateTime.Now);\n// 08/23/2016 05:34:32.4349034 PM\n\nstring tso = client.Timestamp(DateTime.Now);\n// 2016-08-23 17:34:32.446913 \n```\n\n## Other Notes\n\n### General\n\nWhen using database-specific classes ```DatabaseWrapper.Mysql```, ```DatabaseWrapper.Postgresql```, ```DatabaseWrapper.SqlServer```, or ```DatabaseWrapper.Sqlite```, the constructor is simplified from what is shown above.\n\nFor Sqlite:\n\n```csharp\nDatabaseClient client = new DatabaseClient(\"[databasefilename]\");\n```\n\nFor SQL Server, MySQL, or PostgreSQL:\n\n```csharp\nDatabaseClient client = new DatabaseClient(DbTypes.SqlServer,  \"[hostname]\", [port], \"[user]\", \"[password]\", \"[databasename]\");\nDatabaseClient client = new DatabaseClient(DbTypes.Mysql,      \"[hostname]\", [port], \"[user]\", \"[password]\", \"[databasename]\");\nDatabaseClient client = new DatabaseClient(DbTypes.Postgresql, \"[hostname]\", [port], \"[user]\", \"[password]\", \"[databasename]\");\n```\n\nFor SQL Server Express:\n\n```csharp\nDatabaseClient client = new DatabaseClient(DbTypes.SqlServer, \"[hostname]\", [port], \"[user]\", \"[password]\", \"[instance]\", \"[databasename]\");\n```\n\n### MySQL\n\n- MySQL does not like to return updated rows.  I thought about making the UPDATE clause require that you supply the ID field and the ID value so that I could retrieve it after the fact, but that approach is just too limiting.\n\n### MariaDB\n\n- Use the MySQL constructor.  MySQL constraints remain.\n\n### PostgreSQL\n\n- Cleansing of strings in PostgreSQL uses the dollar-quote style.  Fieldnames are always encapsulated in double-quotes for PostgreSQL.\n\n### SQL Server\n\n- Pagination where ```IndexStart``` and ```MaxResults``` are supplied demands use of ```ResultOrder[]```.\n\n### Sqlite\n\n- Sqlite may not work out of the box with .NET Framework.  In order to use Sqlite with .NET Framework, you'll need to manually copy the ```runtimes``` folder into your project output directory.  This directory is automatically created when building for .NET Core.  To get this folder, build the ```Test.Sqlite``` project and navigate to the ```bin/debug/netcoreapp*``` directory.  Then copy the ```runtimes``` folder into the project output directory of your .NET Framework application. \n\n## Version history\n\nRefer to CHANGELOG.md.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristn%2FDatabaseWrapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjchristn%2FDatabaseWrapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristn%2FDatabaseWrapper/lists"}