{"id":25413690,"url":"https://github.com/visiperf/visisql","last_synced_at":"2026-04-29T01:32:24.657Z","repository":{"id":49209425,"uuid":"234330285","full_name":"visiperf/visisql","owner":"visiperf","description":"A wonderful Go package to make PostgreSQL requests easier :)","archived":false,"fork":false,"pushed_at":"2021-06-23T13:55:32.000Z","size":79,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-22T12:01:44.978Z","etag":null,"topics":["package","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/visiperf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-16T13:49:00.000Z","updated_at":"2021-06-23T13:55:05.000Z","dependencies_parsed_at":"2022-09-26T18:21:39.205Z","dependency_job_id":null,"html_url":"https://github.com/visiperf/visisql","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/visiperf/visisql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visiperf%2Fvisisql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visiperf%2Fvisisql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visiperf%2Fvisisql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visiperf%2Fvisisql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/visiperf","download_url":"https://codeload.github.com/visiperf/visisql/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visiperf%2Fvisisql/sbom","scorecard":{"id":923689,"data":{"date":"2025-08-04","repo":{"name":"github.com/visiperf/visisql","commit":"472ce3b3018be0249eec27a86ede7a9605552c06"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":2.7,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Code-Review","score":1,"reason":"Found 3/18 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 21 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-25T08:14:46.077Z","repository_id":49209425,"created_at":"2025-08-25T08:14:46.077Z","updated_at":"2025-08-25T08:14:46.077Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32407164,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T19:38:08.556Z","status":"ssl_error","status_checked_at":"2026-04-28T19:37:55.688Z","response_time":56,"last_error":"SSL_read: 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":["package","postgresql"],"created_at":"2025-02-16T14:21:35.642Z","updated_at":"2026-04-29T01:32:24.638Z","avatar_url":"https://github.com/visiperf.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostgreSQL services for Golang #\n\nPackage `visisql` provide two services `Select` and `Transaction` to help making PostgreSQL requests. `Select` service will assist you to build and scan queries, while `Transaction` will help you to insert, update and delete rows in your databases with SQL transactions (rollback, commit ...).\n\nVisisql use `github.com/huandu/go-sqlbuilder` to build SQL queries and use `github.com/jmoiron/sqlx` to map result with structs. For more informations, see documentations of each package.\n\nTable of contents\n=================\n\n  * [Install](#install)\n  * [Usage](#usage)\n    * [Select one row](#select-one-row)\n    * [Select multiple rows](#select-multiple-rows)\n    * [Insert](#insert)\n    * [Insert multiple](#insert-multiple)\n    * [Update](#update)\n    * [Delete](#delete)\n  * [FAQ](#faq)\n  * [References](#references)\n\n## Install ##\n\nUse `go get` to install this package.\n\n    go get github.com/visiperf/visisql/v3\n\n\n## Usage ##\n\nThe following examples will be based on this PostgreSQL table named `company` :\n\n|  id  |  name  |\n|------|--------|\n| 1 | Company 1 |\n| 2 | Company 2 |\n| 3 | Company 3 |\n\nand this structure :\n\n```go\ntype Company struct {\n    Id   int64  `db:\"id\"`\n    Name string `db:\"name\"`\n}\n```\n\n### Select one row ###\n\nHere is an example to demonstrate how to select the company with `id = 1` :\n\n```go\ndb, err := sqlx.Connect(...)\n\nvar fields = []string{\"c.id\", \"c.name\"}\n\nvar from = \"company c\"\n\nvar joins = []*visisql.Join{\n    visisql.NewJoin(visisql.InnerJoin, \"user u\", \"u.company_id = c.id\"),\n}\n\nvar where = [][]*visisql.Predicate{{\n    visisql.NewPredicate(\"c.id\", visisql.OperatorEqual, []interface{}{1}),\n}}\n\nvar groupBy = []string{\"c.id\"}\n\n/*\n\nSQL equivalent :\n\nselect c.id, c.name\nfrom company c\n    inner join user u on u.company_id = c.id\nwhere c.id = 1\ngroup by c.id\n\n*/\n\nvar company Company\n\nerr := visisql.NewSelectService(db).Get(fields, from, joins, where, groupBy, \u0026company)\n\n// company.Id -\u003e 1\n// company.Name -\u003e \"Company 1\"\n```\n\n### Select multiple rows ###\n\nHere is an example to demonstrate how to select the 2 first companies starting with `Company` :\n\n```go\ndb, err := sqlx.Connect(...)\n\nvar fields = []string{\"c.id\", \"c.name\"}\n\nvar from = \"company c\"\n\nvar joins = []*visisql.Join{\n    visisql.NewJoin(visisql.InnerJoin, \"user u\", \"u.company_id = c.id\"),\n}\n\nvar where = [][]*visisql.Predicate{{\n    visisql.NewPredicate(\"c.name\", visisql.OperatorLike, []interface{}{\"Company%\"}),\n}}\n\nvar groupBy = []string{\"c.id\"}\n\nvar orderBy = []*visisql.OrderBy{\n  \tvisisql.NewOrderBy(\"c.id\", visisql.OrderAsc),\n}\n\nvar pagination = visisql.NewPagination(0, 2)\n\n/*\n\nSQL equivalent :\n\nselect c.id, c.name\nfrom company c\n    inner join user u on u.company_id = c.id\nwhere c.name like 'Company%'\ngroup by c.id\norder by c.id ASC\nlimit 2\n\n*/\n\nvar companies []*Company\n\nc, tc, pc, err := visisql.NewSelectService(db).Search(fields, from, joins, where, groupBy, orderBy, pagination, \u0026companies)\n\n/*\n\ncompanies -\u003e [{\n\tcompany.Id -\u003e 1\n\tcompany.Name -\u003e \"Company 1\"\n}, {\n\tcompany.Id -\u003e 2\n\tcompany.Name -\u003e \"Company 2\"\n}]\n\nc (count) -\u003e 2 (number of rows including limit)\ntc (total count) -\u003e 3 (number of rows if limit was 0)\npc (page count) -\u003e 2 (number of pages, with c elements per page)\n\n*/\n```\n\n### Insert ###\n\nHere is an example to demonstrate how to insert a company in database :\n\n```go\ndb, err := sqlx.Connect(...)\n\nvar into = \"company\"\n\nvar values = map[string]interface{}{\"name\": \"Company 4\"}\n\nvar returning = \"id\"\n\n/*\n\nSQL equivalent :\n\ninsert into company (name) \nvalues ('Company 4')\nreturning id\n\n*/\n\nts, err := visisql.NewTransactionService(db)\n\ncId, err := ts.Insert(into, values, returning)\n// company is not saved in database yet (see sql transaction for more informations)\n// if an error is occured, rollback is automatically applied to transaction\n\nerr = ts.Commit() // all requests made with ts are executed now, Company 4 is now in database\n\n// cId -\u003e 4 because `returning` params is set to `id`. You can set what you want, including `nil` if you don't need returned value.\n```\n\n### Insert multiple\n\nHere is an example to demonstrate how to insert multiple companies in database :\n\n```go\ndb, err := sqlx.Connect(...)\n\nvar into = \"company\"\n\nvar fields = []string{\"name\"}\n\n// values must be in same order as fields\nvar values = [][]interface{}{{\"Company 4\"}, {\"Company 5\"}}\n\nvar returning = \"id\"\n\n/*\n\nSQL equivalent (using prepared statement) :\n\ninsert into company (name) \nvalues ('Company 4')\nreturning id\n\ninsert into company (name) \nvalues ('Company 5')\nreturning id\n\n*/\n\nts, err := visisql.NewTransactionService(db)\n\nids, err := ts.InsertMultiple(into, fields, values, returning)\n// companies are not saved in database yet (see sql transaction for more informations)\n// if an error is occured, rollback is automatically applied to transaction\n\nerr = ts.Commit() // all requests made with ts are executed now, Companies 4 \u0026 5 are now in database\n\n// ids -\u003e [4, 5] because `returning` params is set to `id`. You can set what you want, including `nil` if you don't need returned value.\n```\n\n### Update ###\n\nHere is an example to demonstrate how to update the company with `id = 3` :\n\n```go\ndb, err := sqlx.Connect(...)\n\nvar table = \"company\"\n\nvar set = map[string]interface{}{\"name\": \"Company 4\"}\n\nvar where = [][]*visisql.Predicate{{\n    visisql.NewPredicate(\"id\", visisql.OperatorEqual, []interface{}{3}),\n}}\n\n/*\n\nSQL equivalent :\n\nupdate company\nset name = 'Company 4'\nwhere id = 3\n\n*/\n\nts, err := visisql.NewTransactionService(db)\n\nerr = ts.Update(table, set, where)\n// company is not updated in database yet (see sql transaction for more informations)\n// if an error is occured, rollback is automatically applied to transaction\n\nerr = ts.Commit() // all requests made with ts are executed now, Company 3 is now updated to Company 4\n```\n\n### Delete ###\n\nHere is an example to demonstrate how to delete the company with `id = 3` :\n\n```go\ndb, err := sqlx.Connect(...)\n\nvar from = \"company\"\n\nvar where = [][]*visisql.Predicate{{\n    visisql.NewPredicate(\"id\", visisql.OperatorEqual, []interface{}{3}),\n}}\n\n/*\n\nSQL equivalent :\n\ndelete from company\nwhere id = 3\n\n*/\n\nts, err := visisql.NewTransactionService(db)\n\nerr = ts.Delete(from, where)\n// company is not deleted in database yet (see sql transaction for more informations)\n// if an error is occured, rollback is automatically applied to transaction\n\nerr = ts.Commit() // all requests made with ts are executed now, Company 3 is now deleted\n```\n\n## FAQ\n\n- Why `predicates` params is always typed as `[][]*visisql.Predicate` ?\n\n\u003e `predicates` params is two dimentional slice to be able to make request with AND / OR operators.\n\u003e\n\u003e The first dimension will join predicates with `AND` operator, while second dimension will join predicates with `OR` operator.\n\u003e\n\u003e \u003cbr/\u003e\n\u003e\n\u003e example with `AND` :\n\u003e\n\u003e ```go\n\u003e [][]*visisql.Predicate{{\n\u003e   visisql.NewPredicate(\"c.name\", visisql.OperatorLike, []interface{}{\"%@visiperf.io\"})\n\u003e }, {\n\u003e   visisql.NewPredicate(\"u.id\", visisql.OperatorEqual, []interface{}{1})\n\u003e }}\n\u003e ```\n\u003e\n\u003e SQL equivalent :\n\u003e\n\u003e ```sql\n\u003e where c.name like '%@visiperf.io' and u.id = 1\n\u003e ```\n\u003e\n\u003e \u003cbr/\u003e\n\u003e\n\u003e example with `OR` :\n\u003e\n\u003e ```go\n\u003e [][]*visisql.Predicate{{\n\u003e   visisql.NewPredicate(\"c.id\", visisql.OperatorEqual, []interface{}{1}),\n\u003e   visisql.NewPredicate(\"c.name\", visisql.OperatorEqual, []interface{}{\"Visiperf\"}),\n\u003e }}\n\u003e ```\n\u003e\n\u003e SQL equivalent :\n\u003e\n\u003e ```sql\n\u003e where c.id = 1 or c.name = 'Visiperf'\n\u003e ```\n\u003e\n\u003e \u003cbr/\u003e\n\u003e\n\u003e Of course, you can mix `AND` and `OR` operators in same request.\n\u003e\n\u003e example :\n\u003e\n\u003e ```go\n\u003e [][]*visisql.Predicate{{\n\u003e   visisql.NewPredicate(\"c.id\", visisql.OperatorEqual, []interface{}{1}),\n\u003e   visisql.NewPredicate(\"c.name\", visisql.OperatorEqual, []interface{}{\"Visiperf\"}),\n\u003e }, {\n\u003e   visisql.NewPredicate(\"u.id\", visisql.OperatorEqual, []interface{}{1})\n\u003e }}\n\u003e ```\n\u003e\n\u003e SQL equivalent :\n\u003e\n\u003e ```sql\n\u003e where (c.id = 1 or c.name = 'Visiperf') and u.id = 1\n\u003e ```\n\n## References ###\n\n* SQL builder for Go : [github.com/huandu/go-sqlbuilder](https://github.com/huandu/go-sqlbuilder)\n* SQLX library : [github.com/jmoiron/sqlx](https://github.com/jmoiron/sqlx)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvisiperf%2Fvisisql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvisiperf%2Fvisisql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvisiperf%2Fvisisql/lists"}