{"id":13850354,"url":"https://github.com/maxzerbini/dingo","last_synced_at":"2026-01-17T18:26:03.470Z","repository":{"id":102317521,"uuid":"52306428","full_name":"maxzerbini/dingo","owner":"maxzerbini","description":"Data access in Go - Code Generator","archived":false,"fork":false,"pushed_at":"2017-07-13T15:42:10.000Z","size":3554,"stargazers_count":106,"open_issues_count":2,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-14T11:59:41.583Z","etag":null,"topics":["code-generation","database-schema","microservices"],"latest_commit_sha":null,"homepage":"","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/maxzerbini.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":"2016-02-22T21:16:15.000Z","updated_at":"2023-08-18T14:22:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"501c24d5-c71e-404a-b11c-f54ad458f326","html_url":"https://github.com/maxzerbini/dingo","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/maxzerbini/dingo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxzerbini%2Fdingo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxzerbini%2Fdingo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxzerbini%2Fdingo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxzerbini%2Fdingo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maxzerbini","download_url":"https://codeload.github.com/maxzerbini/dingo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxzerbini%2Fdingo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28515463,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T17:57:59.192Z","status":"ssl_error","status_checked_at":"2026-01-17T17:57:52.527Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["code-generation","database-schema","microservices"],"created_at":"2024-08-04T20:01:08.167Z","updated_at":"2026-01-17T18:26:03.446Z","avatar_url":"https://github.com/maxzerbini.png","language":"Go","readme":"# DinGo\nData access in Go (DinGo). From database schema to RESTful API: all the code is generated for you in few seconds. \n\n![Dingo](doc/img/dingo_small.png)\n\n## Build status\n[![Build Status](https://drone.io/github.com/maxzerbini/dingo/status.png)](https://drone.io/github.com/maxzerbini/dingo/latest) [![Build Status](https://travis-ci.org/maxzerbini/dingo.svg?branch=master)](https://travis-ci.org/maxzerbini/dingo)\n\n## Main features\n\nDinGo creates a Microservice application starting from your database schema. \nSupported databases are MySQL and PostgreSQL (currently in beta).\n\nThese are the main steps followed by Dingo:\n- Data Model generation\n- Data Access Object (DAO) generation\n- Business Object (Biz) generation\n- View-Model generation\n- Service Object generation\n- Host Server creation\n- JSON configuration file creation\n\nThe result you get is a Web API application that you just compile and run.\n\n## Model Generation\nDinGo generates Model Data Transfer Object (DTO) reading the database schema.\nAll the generated strutcs are written in the *model.go* file inside the *model* package's directory.\n\nThis is an example of generated DTO for MySql:\n```Go\n// Data transfer object for Customer\ntype Customer struct {\n\tId int64 `sql:\"type:int(10) unsigned;not null;AUTO_INCREMENT\"`\n\tName string `sql:\"type:varchar(60);not null\"`\n\tState string `sql:\"type:varchar(12);not null\"`\n\tCreationDate time.Time `sql:\"type:datetime;not null\"`\n\tUpdateDate time.Time `sql:\"type:datetime;not null\"`\n\t\n}\n```\nEvery field has a *GORM style* metadata.\n\n## DAO Generation\nDinGo generates DAO structs reading the database schema and the Model.\nEvery DAO defines these methods to perform CRUD operations on entities:\n- Insert(conn *sql.DB, dto *model.ModelStruct)(lastInsertId int64, err error)\n- Update(conn *sql.DB, dto *model.ModelStruct)(rowsAffected int64, err error)\n- Delete(conn *sql.DB, dto *model.ModelStruct)(rowsAffected int64, err error)\n- FindByPrimaryKey(conn *sql.DB, pk1 pk1Type, pk2 pk2Type, ...) (dto *model.ModelStruct, err error)\n- List(conn *sql.DB, take int32, skip int32) (list []*model.ModelStruct, err error)\n- Count(conn *sql.DB)\n\nGenerated DAO supports table's primary keys and auto-increment columns.\nAll the DAO generated structs are written in the *dao.go* file inside the *dao* package's directory.\n\nThis is an example of generated DAO struct for MySql:\n```Go\n// Data access object for Customer entities.\ntype CustomerDao struct {\n\t\n}\n// Insert a new Customer entity and returns the last insert Id.\nfunc (dao *CustomerDao) Insert(conn *sql.DB, dto *model.Customer)(lastInsertId int64, err error){\n\tq := \"INSERT INTO customer VALUES (?, ?, ?, ?, ?)\"\n\tres, err := conn.Exec(q, sql.NullInt64{}, dto.Name, dto.State, dto.CreationDate, dto.UpdateDate)\n    if err != nil {\n\t\treturn -1, err\n\t}\n\tlastInsertId, err = res.LastInsertId()\n\treturn lastInsertId, err\n}\n// Update a Customer entity and returns the number of affected rows.\nfunc (dao *CustomerDao) Update(conn *sql.DB, dto *model.Customer)(rowsAffected int64, err error){\n\tq := \"UPDATE customer SET Name=?, State=?, CreationDate=?, UpdateDate=?\"\n\tq += \" WHERE Id = ?\"\n\tres, err := conn.Exec(q, dto.Name, dto.State, dto.CreationDate, dto.UpdateDate, dto.Id)\n    if err != nil {\n\t\treturn -1, err\n\t}\n\trowsAffected, err = res.RowsAffected()\n\treturn rowsAffected, err\n}\n// Delete a Customer entity and returns the number of affected rows.\nfunc (dao *CustomerDao) Delete(conn *sql.DB, dto *model.Customer)(rowsAffected int64, err error){\n\t...\n}\n// Find the Customer entity by primary keys, returns nil if not found.\nfunc (dao *CustomerDao) FindByPrimaryKey(conn *sql.DB, Id int64) (dto *model.Customer, err error){\n\t...\n}\n// List the Customer entities.\nfunc (dao *CustomerDao) List(conn *sql.DB, take int32, skip int32) (list []*model.Customer, err error){\n\t...\n}\n// Count the Customer entities.\nfunc (dao *CustomerDao) Count(conn *sql.DB) (count int64, err error){\n\t...\n}\n```\nThe last two methods are available also for Views of the database.\n\n## View-Model Generation\nThe View-Model objects are produced in a similar manner to those of the Model. \nThe difference between these structures is that the former do not depend on the sql package and are designed to be serialized in JSON.\n\n## Business Object Generation\nThese objects are wrapper around DAO objects. Their interface differ from the DAO interface because of View-Model types present on the method signatures.\nThis is an example of generated Biz object:\n```Go\n// Business object for Customer entities.\ntype CustomerBiz struct {\n\tDao *dao.CustomerDao\t\n}\n// Create a CustomerBiz\nfunc NewCustomerBiz() *CustomerBiz {\n\treturn \u0026CustomerBiz{ Dao:\u0026dao.CustomerDao{} }\n}\n// Convert an model entity in a view-model\nfunc (b *CustomerBiz) ToViewModel(m *model.Customer) *viewmodel.Customer{\n\tv := \u0026viewmodel.Customer{}\n\tv.Id = m.Id\n\t...\n\treturn v\n}\n// Convert a view-model in a model entity\nfunc (b *CustomerBiz) ToModel(v *viewmodel.Customer) *model.Customer{\n\tm := \u0026model.Customer{}\n\tm.Id = v.Id\n\t...\n\treturn m\n}\n// Insert a new Customer entity and returns the last insert Id.\nfunc (b *CustomerBiz) Insert(v *viewmodel.Customer) (lastInsertId int64, err error) {\n\treturn b.Dao.Insert(dao.Connection, b.ToModel(v))\n}\n// Update a Customer entity and returns the number of affected rows.\nfunc (b *CustomerBiz) Update(v *viewmodel.Customer) (rowsAffected int64, err error) {\n\treturn b.Dao.Update(dao.Connection, b.ToModel(v))\n}\n// Delete a Customer entity and returns the number of affected rows.\nfunc (b *CustomerBiz) Delete(v *viewmodel.Customer) (rowsAffected int64, err error) {\n\treturn b.Dao.Delete(dao.Connection, b.ToModel(v))\n}\n// Find the Customer entity by primary keys, returns nil if not found.\nfunc (b *CustomerBiz) Find(mv *viewmodel.Customer) (v *viewmodel.Customer, err error){\n\t...\n}\n// List the Customer entities.\nfunc (b *CustomerBiz) List(take int32, skip int32) (list []*viewmodel.Customer, err error) {\n\t...\n}\n// Count the Customer entities.\nfunc (b *CustomerBiz) Count() (count int64, err error){\n\treturn b.Dao.Count(dao.Connection)\n}\n```\n## Service Object Generation\nThese objects offer a set of methods used to construct and expose RESTful API.\n\n## REST API Generation\nDinGo can generate the set of RESTful API endpoints needed to perform CRUD operations on entities. Each entity corresponds to a resource, and each resource has the necessary endpoints to be managed. \nIf the resource has a simple identifier (the corresponding entity has one-column PK) then Dingo generates these endpoints:\n- *GET [basehost]/resourcename?skip=[value]\u0026take=[value]\u0026count=all* lists the elements\n- *POST [basehost]/resourcename* creates a new element\n- *PUT [basehost]/resourcename/:id* updates the element has PK = id\n- *DELETE [basehost]/resourcename/:id* deletes an element\n- *GET [basehost]/resourcename/:id* finds an element by primary key\n\nIf the resource has a complex identifier and the corresponding entity has a PK made of more columns, the generated endpoints are these:\n- *GET [basehost]/resourcename?skip=[value]\u0026take=[value]* lists the elements\n- *POST [basehost]/resourcename* creates a new element\n- *PUT [basehost]/resourcename* updates an element\n- *POST [basehost]/resourcename/delete* deletes an element\n- *POST [basehost]/resourcename/find* finds an element by primary keys\n- *GET [basehost]/resourcename/count* counts the etities\n\n\n## Building DinGo\n```bash\n$ go get github.com/maxzerbini/dingo\n$ go build -i github.com/maxzerbini/dingo\n```\n\n## Running DinGo\nMake sure to properly set the *config.json* file with your connection parameters and run\n```bash\n$ dingo \n```\nIf you rename or move the configuration file then run\n```bash\n$ dingo -conf=/mypath/myconfig.json\n```\n\n## DinGo Configuration\nThe MySQL connection and other configuration parameters are defined in the *config.json* file.\nHere is a configuration example:\n```JSON\n{\n\t\"Hostname\": \"localhost\", \n\t\"Port\": \"3306\", \n\t\"DatabaseType\": \"MySQL\",\n\t\"DatabaseName\": \"Customers\", \n\t\"Username\": \"zerbo\", \n\t\"Password\": \"Mysql.2016\",\n\t\"BasePackage\": \"github.com/maxzerbini/prjtest\",\n\t\"OutputPath\": \"$GOPATH/src/github.com/maxzerbini/prjtest\",\n\t\"ExcludedEntities\": [],\n\t\"Entities\": [],\n\t\"SkipDaoGeneration\": false,\n\t\"SkipBizGeneration\": false,\n\t\"SkipServiceGeneration\": false,\n\t\"ForcePluralResourceName\": true,\n\t\"PostgresSchema\": \"public\"\n}\n```\nThe _DatabaseType_ can assume one of these values\n- \"MySQL\"\n- \"Postgres\"\n\nOptional configuration parameters\n- _ExcludedEntities_ is an optional list of enity names that will be exluded\n- _Entities_ is a list of included entities, if it's void all the entities are considered\n- _SkipDaoGeneration_ skip DAO generation step and the following steps\n- _SkipBizGeneration_ skip Biz generation step and the following steps\n- _SkipServiceGeneration_ skip Service Object generation step and the following steps\n- _ForcePluralResourceName_ force english plural names for resource endpoints\n- _PostgresSchema_ is the PostgreSQL Schema name (usually \"public\")\n\n## Using generated DAO and Biz code\nIt's very easy using generated code. Here an example:\n```Go\n// open the connection\nconn, err := sql.Open(\"mysql\",\"myuser:password@tcp(localhost:3306)/myDatabase?parseTime=true\")\nif err != nil {\n\tpanic(err)\n} else {\n\t// set the connection\n\tdao.Connection = conn\n}\nb := biz.NewCustomerBiz()\ncust := \u0026viewmodel.Customer{Name: \"Max\", State: \"PENDING\", CreationDate: time.Now(), UpdateDate: time.Now()}\n// insert a new customer\nid, err := b.Insert(cust)\n// get the list of customers\nresult, err := b.List(100, 0)\n// find entity by primary key\ncust2 := \u0026viewmodel.Customer{Id: 7}\ncust2, err = b.Find(cust2)\n```\n\n## Extension points\nAll generated structs can be extended creating custom methods. \nFor example if you want add a custom method to a *CustomerBiz*, you just create a file *bitext.go* in the *biz* directory and put in the new method\n```Go\npackage biz\n\nimport \"github.com/myuser/myproject/model\"\nimport \"github.com/myuser/myproject/dao\"\nimport \"github.com/myuser/myproject/viewmodel\"\n\nfunc (b *CustomerBiz) InsertCustomerAndProduct(v *viewmodel.Customer, idProduct int64)(lastInsertId int64, err error) {\n\tlastInsertId, err = b.Dao.Insert(dao.Connection, b.ToModel(v))\n\tcpdao := \u0026dao.CustomerprodutcDao{}\n\tcp := \u0026model.Customerproduct{IdCustomer:lastInsertId, IdProduct:idProduct, UpdateDate:time.Now()}\n\tid, err := cpdao.Insert(dao.Connection, cp)\n\treturn lastInsertId, err\n}\n```\nYou can do this with all the objects generated by DinGo such as Model, Dao, Biz, ViewModel and Service Objects.\nIf you need to add endpoints to the API then you can register new endpoints in the file *customresources.go* inside the method *registerCustomResources*\n```Go\npackage main\n\nimport \"github.com/gin-gonic/gin\"\n\n// Register custom resource endpoints here.\nfunc registerCustomResources(conf Configuration, router *gin.Engine) {\n\t// TODO add your custom endpoints\n\t// so := service.NewMyService()\n\t// router.GET(conf.WebBaseHost+\"/myresources\", so.MyMethod)\n}\n```\nThe file *customresources.go* is generated only once then is no longer rewritten so that it can be modified without the risk of losing changes.\n\n## Known issues\n- The DAO components are produced correctly if the tables have a PK\n- The Update method is not implemented if the entity does not have at least one column not PK\n- Some columns types that are not recognized (such as JSON) are mapped to string fields\n- PostgreSQL array types are not supported (these columns are all mapped as string)\n- DinGo maps DATE, TIME, DATETIME and TIMESTAMP column types to *time.Time* assuming that the connection has opened using the DSN parameter *parseTime=true*\n- If you have a lot of entities in your database, you could produce a *\"SOA Monolith\"*, but using the configuration parameters _ExcludedEntities_ or _Entities_ and changing the _BasePackage_ you can limit the number of endpoints and you can produce many small applications, obtaining a set of indipendent Microservices\n- Some HTTP verbs such as DELETE are not used defining the service endpoints of the resources that have complex primary keys\n\n## Warning\nIt's recommended to test the generated code before using it in production. \nIf you find a problem feel free to submit an issue.\n\n## Roadmap\n### Supported Databases\n- [x] MySQL \n- [x] PostgreSQL (beta)\n- [ ] SQLite\n- [ ] MS SQL Server\n","funding_links":[],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxzerbini%2Fdingo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxzerbini%2Fdingo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxzerbini%2Fdingo/lists"}