{"id":28254635,"url":"https://github.com/pharosnet/dalc","last_synced_at":"2025-09-09T23:48:11.770Z","repository":{"id":57534134,"uuid":"151978098","full_name":"pharosnet/dalc","owner":"pharosnet","description":"database access common layer for go.","archived":false,"fork":false,"pushed_at":"2020-08-05T07:54:39.000Z","size":212,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-05-19T19:23:17.587Z","etag":null,"topics":["asynchronous-programming","dal","database-access-library"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pharosnet.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}},"created_at":"2018-10-07T19:36:28.000Z","updated_at":"2020-08-05T07:54:11.000Z","dependencies_parsed_at":"2022-09-26T18:21:27.981Z","dependency_job_id":null,"html_url":"https://github.com/pharosnet/dalc","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/pharosnet/dalc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharosnet%2Fdalc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharosnet%2Fdalc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharosnet%2Fdalc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharosnet%2Fdalc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pharosnet","download_url":"https://codeload.github.com/pharosnet/dalc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharosnet%2Fdalc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269693594,"owners_count":24460248,"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","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["asynchronous-programming","dal","database-access-library"],"created_at":"2025-05-19T19:22:54.052Z","updated_at":"2025-08-10T08:14:53.442Z","avatar_url":"https://github.com/pharosnet.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DALC\nDatabase access layer for go.\n\n## Feature\n\n- Simple.\n- No-reflect cost.\n- Using callback function to decrease range times.\n- Expandability.\n- It is more convenient to use with dalc command.\n\n## Usage\n\n`go get -u github.com/pharosnet/dalc/v2`\n\n\n```go\n// ************* UserListByJoinTime *************\n\nconst userListByJoinTimeSQL = \"SELECT `users`.`id`, `users`.`name`, `users`.`age`, `users`.`has_friends`, `users`.`join_time` FROM `ddd_test`.`users` WHERE `id` = ?\"\n\ntype UserListByJoinTimeRequest struct {\n\tId int64\n}\n\ntype UserListByJoinTimeResult struct {\n\tId         int64\n\tName       string\n\tAge        int\n\tHasFriends bool\n\tJoinTime   time.Time\n}\n\ntype UserListByJoinTimeResultIterator func(ctx context.Context, result *UserListByJoinTimeResult) (err error)\n\nfunc UserListByJoinTime(ctx dalc.PreparedContext, request *UserListByJoinTimeRequest, iterator UserListByJoinTimeResultIterator) (err error) {\n\n\targs := dalc.NewArgs()\n\targs.Arg(request.Id)\n\n\terr = dalc.Query(ctx, userListByJoinTimeSQL, args, func(ctx context.Context, rows *sql.Rows, rowErr error) (err error) {\n\n\t\tif rowErr != nil {\n\t\t\terr = rowErr\n\t\t\treturn\n\t\t}\n\t\tresult := \u0026UserListByJoinTimeResult{}\n\n\t\tscanErr := rows.Scan(\n\t\t\t\u0026result.Id,\n\t\t\t\u0026result.Name,\n\t\t\t\u0026result.Age,\n\t\t\t\u0026result.HasFriends,\n\t\t\t\u0026result.JoinTime,\n\t\t)\n\n\t\tif scanErr != nil {\n\t\t\terr = scanErr\n\t\t\treturn\n\t\t}\n\n\t\terr = iterator(ctx, result)\n\n\t\treturn\n\t})\n\n\treturn\n}\n\n// ************* UserUpdateName *************\nconst userUpdateNameSQL = \"UPDATE `ddd_test`.`users` SET `join_time` = ? WHERE `id` = ?\"\n\ntype UserUpdateNameRequest struct {\n\tId       int64\n\tJoinTime time.Time\n}\n\nfunc UserUpdateName(ctx dalc.PreparedContext, request *UserUpdateNameRequest) (affected int64, err error) {\n\n\targs := dalc.NewArgs()\n\targs.Arg(request.JoinTime)\n\targs.Arg(request.Id)\n\n\taffected, err = dalc.Execute(ctx, userUpdateNameSQL, args)\n\n\treturn\n}\n\n```\nPreparedStatement\n```go\n// select\nvar db *sql.DB\nctx := dalc.WithPreparedStatement(context.TODO(), db)\nerr := UserListByJoinTime(ctx, \u0026UserListByJoinTimeRequest{Id: 1}, func(ctx context.Context, result *UserListByJoinTimeResult) (err error) {\n    // handle result\n    return\n})\n```\n```go\n// exec with tx\ntx, _ := db.Begin()\nctx := dalc.WithPreparedStatement(context.TODO(), tx)\n_, err := UserUpdateName(ctx, \u0026UserUpdateNameRequest{Id: 1, JoinTime: time.Now()})\n\ntx.Commit()\n```\n## Code Generates\n### Install dalg\n`go get -u github.com/pharosnet/dalg`\n### Write sql schema files\nWrite sql schema files in some folder, such as schema/, and foo.sql in this folder.\n```sql\nUSE `ddd_test`;\n\n-- name: users_domain_events\nCREATE TABLE `users_domain_events`\n(\n    `id`             bigint       NOT NULL AUTO_INCREMENT,\n    `aggregate_name` varchar(255) NOT NULL, -- name: AggName ref: github.com/foo/bar.SQLString\n    `aggregate_id`   varchar(255) NOT NULL,\n    `event_name`     varchar(255) NOT NULL,\n    `event_id`       varchar(63)  NOT NULL,\n    `event_time`     datetime(6) DEFAULT NULL,\n    `event_data`     text,\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `users_ix_event_id` (`event_id`),\n    KEY `users_ix_aggname` (`aggregate_name`),\n    KEY `users_ix_aggid` (`aggregate_id`),\n    KEY `users_ix_event_name` (`event_name`),\n    KEY `users_ix_event_time` (`event_time` DESC)\n) ENGINE = InnoDB\n  DEFAULT CHARSET = utf8mb4\n  COLLATE = utf8mb4_0900_ai_ci;\n```\n* first comment line is to define one name to replace table name, use `name: ` mark. \n* In columns, can use `name: ` define a new name and use `ref: ` define the go type.\n### Write sql query files\nWrite sql query files in some folder, such as query/, and bar.sql in this folder.\n```sql\n-- name: users_domain_events_list\nSELECT `ee`.`id` as `xxxx`,\n       `ee`.`aggregate_name`,\n       `users_domain_events`.`aggregate_id`,\n       `ee`.`event_name`,\n       `ee`.`event_id`\nFROM `ddd_test`.`users_domain_events` as `ee`\nWHERE `ee`.`aggregate_id` = ?\n  AND `ee`.`aggregate_name` = 'DD'\n  AND `ee`.`event_id` IN ('#xxxx#')\n  and `ee`.`event_name` between ? and ?\nORDER BY `ee`.`id` DESC LIMIT ? OFFSET ?;\n\n-- name: users_domain_snapshot_list\nSELECT `users_domain_snapshot`.`id`,\n       `users_domain_snapshot`.`aggregate_name`, /* dd */\n       `users_domain_snapshot`.`aggregate_id`,\n       `users_domain_snapshot`.`last_event_id`,\n       `users_domain_snapshot`.`snapshot_data`,\n       (`users_domain_snapshot`.`id` \u003e 1)                                                          as `over`,\n       (select count(`id`)\n        from `ddd_test`.`users_domain_events`\n        where `users_domain_events`.`aggregate_id` = `users_domain_snapshot`.`aggregate_id`)       as `count`,\n       (select sum(`id`)\n        from `ddd_test`.`users_domain_events`\n        where `users_domain_events`.`aggregate_id` = `users_domain_snapshot`.`aggregate_id`)       as `sum`,\n       exists(select `id`\n              from `ddd_test`.`users_domain_events`\n              where `users_domain_events`.`aggregate_id` = `users_domain_snapshot`.`aggregate_id`) as `x`\nFROM `ddd_test`.`users_domain_snapshot`\nwhere `id` = ?;\n\n```\n* first comment line is to define the query name, use `name: ` mark. \n* also supports insert, update and delete, but they are generated by sql schema file.\n### Generate\n```bash\ndalc --dialect=mysql \\\n     --out=example/generated/dal \\\n     --schema=example/generated/sqls/schema \\\n     --query=example/generated/sqls/query \\\n     --json_tags=true \\\n     --verbose=true\n```\nCommand Args:\n* dialect: sql dialect, can by mysql or postgres\n* schema: sql schema file path or dir path\n* query: sql query file path or dir path\n* json_tags: enable to add json tag in table row struct and query result struct\n* verbose: show verbose log\n# Todo\n[ ] postgres\n## License\n\nGNU GENERAL PUBLIC LICENSE ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpharosnet%2Fdalc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpharosnet%2Fdalc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpharosnet%2Fdalc/lists"}