{"id":13464067,"url":"https://github.com/azer/crud","last_synced_at":"2025-04-09T08:10:38.106Z","repository":{"id":55107848,"uuid":"48868199","full_name":"azer/crud","owner":"azer","description":"Relational database library for SQL databases \u0026 Go.","archived":false,"fork":false,"pushed_at":"2021-11-29T23:28:01.000Z","size":183,"stargazers_count":314,"open_issues_count":1,"forks_count":16,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-02T05:09:38.959Z","etag":null,"topics":["database","golang","mysql","orm","sql"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/azer/crud/v2","language":"Go","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/azer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-01T03:08:16.000Z","updated_at":"2024-10-23T01:17:26.000Z","dependencies_parsed_at":"2022-08-14T12:10:47.423Z","dependency_job_id":null,"html_url":"https://github.com/azer/crud","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azer%2Fcrud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azer%2Fcrud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azer%2Fcrud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azer%2Fcrud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/azer","download_url":"https://codeload.github.com/azer/crud/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247999861,"owners_count":21031046,"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","golang","mysql","orm","sql"],"created_at":"2024-07-31T14:00:33.517Z","updated_at":"2025-04-09T08:10:38.088Z","avatar_url":"https://github.com/azer.png","language":"Go","readme":"## CRUD\n\nA minimalistic relational database library for Go.\n\n\u003c!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc --\u003e\n**Table of Contents**\n\n- [Install](#install)\n- [Initialize](#initialize)\n- [Define](#define)\n- [Create](#create)\n- [CreateAndRead](#createandread)\n- [Read](#read)\n    - [Reading multiple rows:](#reading-multiple-rows)\n    - [Scanning to custom values:](#scanning-to-custom-values)\n- [Update](#update)\n- [Delete](#delete)\n- [Contexts](#contexts)\n- [Transactions](#transactions)\n- [Logs](#logs)\n- [Custom Queries](#custom-queries)\n- [What's Missing?](#whats-missing)\n- [LICENSE](#license)\n\n\u003c!-- markdown-toc end --\u003e\n\n## Install\n\n```bash\n$ go get github.com/azer/crud/v2\n```\n\n## Initialize\n\n```go\nimport (\n  \"github.com/azer/crud/v2\"\n  _ \"github.com/go-sql-driver/mysql\"\n)\n\nvar DB *crud.DB\n\nfunc init () {\n  var err error\n  DB, err = crud.Connect(\"mysql\", os.Getenv(\"DATABASE_URL\"))\n  err = DB.Ping()\n}\n```\n\n## Define\n\n```go\ntype User struct {\n  Id int `sql:\"auto-increment primary-key\"`\n  FirstName string\n  LastName string\n  ProfileId int\n}\n\ntype Profile struct {\n  Id int `sql:\"auto-increment primary-key\"`\n  Bio string `sql:\"text\"`\n}\n```\n\nCRUD will automatically convert column names from \"FirstName\" (CamelCase) to \"first_name\" (snake_case) for you. You can still choose custom names though;\n\n```go\ntype Post struct {\n  Slug string `sql:\"name=slug_id varchar(255) primary-key required\"`\n}\n```\n\nIf no primary key is specified, CRUD will look for a field named \"Id\" with int type, and set it as auto-incrementing primary-key field.\n\n##### Create \u0026 Drop Tables\n\n`CreateTables` takes list of structs and makes sure they exist in the database.\n\n```go\nerr := DB.CreateTables(User{}, Profile{})\n\nerr := DB.DropTables(User{}, Profile{})\n```\n\n##### Reset Tables\n\nShortcut for dropping and creating tables.\n\n```go\nerr := DB.ResetTables(User{}, Profile{})\n```\n\n##### SQL Options\n\nCRUD tries to be smart about figuring out the best SQL options for your structs, and lets you choose manually, too. For example;\n\n```go\ntype Tweet struct {\n Text string `sql:\"varchar(140) required name=tweet\"`\n}\n```\n\nAbove example sets the type of the `Text` column as `varchar(140)`, makes it required (`NOT NULL`) and changes the column name as `tweet`.\n\nHere is the list of the options that you can pass;\n\n* Types: `int`, `bigint`, `varchar`, `text`, `date`, `time`, `timestamp`\n* `auto-increment` / `autoincrement` / `auto_increment`\n* `primary-key` / `primarykey` / `primary_key`\n* `required`\n* `default='?'`\n* `name=?`\n* `table-name=?`\n\nIf you'd like a struct field to be ignored by CRUD, choose `-` as options:\n\n```go\ntype Foo struct {\n IgnoreMe string `sql:\"-\"`\n}\n```\n\n## Create\n\nSimply pass a struct. It can be pointer or not.\n\n```go\nuser := \u0026User{1, \"Foo\", \"Bar\", 1}\nerr := DB.Create(user)\n```\n\n## CreateAndRead\n\nCreate a row, and read it back from the DB. The values of the struct you passed get resetted to whatever the corresponding DB row has. In the other words, `CreateAndRead` creates, and reads. So you got fields generated by the DB scanned to your struct, like ID.\n\nMake sure passing a pointer.\n\n```go\nuser := User{\n  FirstName:\"Foo\"\n}\n\nerr := DB.CreateAndRead(\u0026user)\n\nuser.Id\n// =\u003e 123\n```\n\n## Read\n\nYou can read single/multiple rows, or custom values, with the `Read` method.\n\n##### Reading a single row:\n\nPass your struct's pointer, and a query;\n\n```go\nuser := \u0026User{}\nerr := DB.Read(user, \"SELECT * FROM users WHERE id = ?\", 1)\n// =\u003e SELECT * FROM users WHERE id = 1\n\nfmt.Println(user.Name)\n// =\u003e Foo\n```\n\n##### Reading multiple rows:\n\n```go\nusers := []*User{}\n\nerr := DB.Read(\u0026users, \"SELECT * FROM users\")\n// =\u003e SELECT * FROM users\n\nfmt.Println(len(users))\n// =\u003e 10\n```\n\n##### Scanning to custom values:\n\n```go\nnames := []string{}\nerr := DB.Read(\u0026names, \"SELECT name FROM users\")\n```\n\n```\nname := \"\"\nerr := DB.Read(\u0026name, \"SELECT name FROM users WHERE id=1\")\n```\n\n```go\ntotalUsers := 0\nerr := DB.Read(\u0026totalUsers, \"SELECT COUNT(id) FROM users\"\n```\n\n## Update\n\nUpdates matching row in database, returns `sql.ErrNoRows` nothing matched.\n\n```go\nuser := \u0026User{}\nerr := DB.Read(user, \"SELECT * FROM users WHERE id = ?\", 1)\n\nuser.Name = \"Yolo\"\nerr := DB.Update(user)\n```\n\n## Delete\n\nDeletes matching row in database, returns `sql.ErrNoRows` nothing matched.\n\n```go\nerr := DB.Delete(\u0026User{\n  Id: 1\n})\n```\n\n## Contexts\n\nUse `WithContext` method to get a DB client with context. Here is an example;\n\n```go\ndb := DB.WithContext(context.Background())\n```\n\n## Transactions\n\nUse `Begin` method of a `crud.DB` instance to create a new transaction. Each transaction will provide you following methods;\n\n* Commit\n* Rollback\n* Exec\n* Query\n* Create\n* CreateAndRead\n* Read\n* Update\n* Delete\n\n```go\ntx, err := DB.Begin(context.Background())\n\nerr := tx.Create(\u0026User{\n  Name: \"yolo\"\n})\n\nerr := tx.Delete(\u0026User{\n  Id: 123\n})\n\nerr := tx.Commit()\n```\n\nCRUD generates an ID for each transaction, and uses that for logging queries and the state of the transactions. You can override transaction IDs in some use cases such as having same IDs and ID field keys with your Rest framework generating request IDs;\n\n```go\ntx.Id = requestId\ntx.IdKey = \"requestId\"\n```\n\n## Logs\n\nIf you want to see crud's internal logs, specify `crud` in the `LOG` environment variable when you run your app. For example;\n\n```\n$ LOG=crud go run myapp.go\n```\n\n## Custom Queries\n\n````go\nresult, err := DB.Query(\"DROP DATABASE yolo\") // or .Exec\n````\n\n## Running Tests\n\n```bash\nDATABASE_URL=\"?\" go test ./...\n```\n\n## What's Missing?\n\n* **Hooks:** I'm not sure if this is needed, but worths to consider.\n* **Foreign Keys:** [*](https://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html)\n* **Make UTF-8 Default:** Looks like the default charset is not UTF8.\n\n## LICENSE\n\n[MIT License](https://github.com/azer/crud/blob/master/COPYING)\n","funding_links":[],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazer%2Fcrud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazer%2Fcrud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazer%2Fcrud/lists"}