{"id":13393607,"url":"https://github.com/Fs02/grimoire","last_synced_at":"2025-03-13T19:31:42.745Z","repository":{"id":46793602,"uuid":"123949959","full_name":"Fs02/grimoire","owner":"Fs02","description":"Database access layer for golang","archived":false,"fork":false,"pushed_at":"2021-10-25T23:52:11.000Z","size":917,"stargazers_count":165,"open_issues_count":0,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-12T04:13:50.845Z","etag":null,"topics":["changeset","database","golang","mysql","orm","postgres","sqlite3","validation"],"latest_commit_sha":null,"homepage":"https://fs02.github.io/grimoire","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/Fs02.png","metadata":{"files":{"readme":"README.md","changelog":"changeset/add_error.go","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"Fs02"}},"created_at":"2018-03-05T16:52:20.000Z","updated_at":"2025-02-26T03:34:06.000Z","dependencies_parsed_at":"2022-09-16T00:21:17.975Z","dependency_job_id":null,"html_url":"https://github.com/Fs02/grimoire","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Fs02%2Fgrimoire","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Fs02%2Fgrimoire/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Fs02%2Fgrimoire/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Fs02%2Fgrimoire/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Fs02","download_url":"https://codeload.github.com/Fs02/grimoire/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243469188,"owners_count":20295704,"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":["changeset","database","golang","mysql","orm","postgres","sqlite3","validation"],"created_at":"2024-07-30T17:00:56.865Z","updated_at":"2025-03-13T19:31:42.167Z","avatar_url":"https://github.com/Fs02.png","language":"Go","readme":"# grimoire\n[![GoDoc](https://godoc.org/github.com/Fs02/grimoire?status.svg)](https://godoc.org/github.com/Fs02/grimoire) [![Build Status](https://travis-ci.org/Fs02/grimoire.svg?branch=master)](https://travis-ci.org/Fs02/grimoire) [![Go Report Card](https://goreportcard.com/badge/github.com/Fs02/grimoire)](https://goreportcard.com/report/github.com/Fs02/grimoire) [![Maintainability](https://api.codeclimate.com/v1/badges/d487e2be0ed7b0b1fed1/maintainability)](https://codeclimate.com/github/Fs02/grimoire/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/d487e2be0ed7b0b1fed1/test_coverage)](https://codeclimate.com/github/Fs02/grimoire/test_coverage)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FFs02%2Fgrimoire.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FFs02%2Fgrimoire?ref=badge_shield)\n\n\u003e :warning: Grimoire V2 is available as [REL](https://github.com/go-rel/rel) and [Changeset](https://github.com/Fs02/changeset) package.\n\nGrimoire is a database access layer inspired by Ecto. It features a flexible query API and built-in validation. It currently supports MySQL, PostgreSQL, and SQLite3 but a custom adapter can be implemented easily using the Adapter interface.\n\nFeatures:\n\n- Query Builder\n- Association Preloading\n- Struct style create and update\n- Changeset Style create and update\n- Builtin validation using changeset\n- Multi adapter support\n- Logger\n\n## Motivation\n\nCommon go ORM accepts struct as a value for modifying records which has a problem of unable to differentiate between an empty, nil, or undefined value. It's a tricky problem especially when you want to have an endpoint that supports partial updates. Grimoire attempts to solve that problem by integrating Changeset system inspired from Elixir's Ecto. Changeset is a form like entity which allows us to not only solve that problem but also help us with casting, validations, and constraints check.\n\n## Install\n\n```bash\ngo get github.com/Fs02/grimoire\n```\n\n## Quick Start\n\n```golang\npackage main\n\nimport (\n\t\"time\"\n\n\t\"github.com/Fs02/grimoire\"\n\t\"github.com/Fs02/grimoire/adapter/mysql\"\n\t\"github.com/Fs02/grimoire/changeset\"\n\t\"github.com/Fs02/grimoire/params\"\n)\n\ntype Product struct {\n\tID        int\n\tName      string\n\tPrice     int\n\tCreatedAt time.Time\n\tUpdatedAt time.Time\n}\n\n// ChangeProduct prepares data before database operation.\n// Such as casting value to appropriate types and perform validations.\nfunc ChangeProduct(product interface{}, params params.Params) *changeset.Changeset {\n\tch := changeset.Cast(product, params, []string{\"name\", \"price\"})\n\tchangeset.ValidateRequired(ch, []string{\"name\", \"price\"})\n\tchangeset.ValidateMin(ch, \"price\", 100)\n\treturn ch\n}\n\nfunc main() {\n\t// initialize mysql adapter.\n\tadapter, err := mysql.Open(\"root@(127.0.0.1:3306)/db?charset=utf8\u0026parseTime=True\u0026loc=Local\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer adapter.Close()\n\n\t// initialize grimoire's repo.\n\trepo := grimoire.New(adapter)\n\n\tvar product Product\n\n\t// Inserting Products.\n\t// Changeset is used when creating or updating your data.\n\tch := ChangeProduct(product, params.Map{\n\t\t\"name\":  \"shampoo\",\n\t\t\"price\": 1000,\n\t})\n\n\tif ch.Error() != nil {\n\t\t// handle error\n\t}\n\n\t// Changeset can also be created directly from json string.\n\tjsonch := ChangeProduct(product, params.ParseJSON(`{\n\t\t\"name\":  \"soap\",\n\t\t\"price\": 2000,\n\t}`))\n\n\t// Create products with changeset and return the result to \u0026product,\n\tif err = repo.From(\"products\").Insert(\u0026product, ch); err != nil {\n\t\t// handle error\n\t}\n\n\t// or panic when insertion failed\n\trepo.From(\"products\").MustInsert(\u0026product, jsonch)\n\n\t// Querying Products.\n\t// Find a product with id 1.\n\trepo.From(\"products\").Find(1).MustOne(\u0026product)\n\n\t// Updating Products.\n\t// Update products with id=1.\n\trepo.From(\"products\").Find(1).MustUpdate(\u0026product, ch)\n\n\t// Deleting Products.\n\t// Delete Product with id=1.\n\trepo.From(\"products\").Find(1).MustDelete()\n}\n```\n\n## Examples\n\n- [Todo API](https://github.com/Fs02/grimoire-todo-example)\n\n## Documentation\n\nGuides: [https://fs02.github.io/grimoire](https://fs02.github.io/grimoire)\n\nAPI Documentation: [https://godoc.org/github.com/Fs02/grimoire](https://godoc.org/github.com/Fs02/grimoire)\n\n## License\n\nReleased under the [MIT License](https://github.com/Fs02/grimoire/blob/master/LICENSE)\n\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FFs02%2Fgrimoire.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FFs02%2Fgrimoire?ref=badge_large)\n","funding_links":["https://github.com/sponsors/Fs02"],"categories":["ORM","Database","Relational Databases","Go","网络相关库"],"sub_categories":["Advanced Console UIs","HTTP Clients","HTTP客户端","ORM","OpenGL","交流"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FFs02%2Fgrimoire","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FFs02%2Fgrimoire","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FFs02%2Fgrimoire/lists"}