{"id":19167512,"url":"https://github.com/tkdeng/gosql","last_synced_at":"2026-05-06T03:33:18.883Z","repository":{"id":251933408,"uuid":"838384205","full_name":"tkdeng/gosql","owner":"tkdeng","description":"GoSQL is an SQL ORM for the Go programming language. It is intended to add type safety and ease of use to SQL.","archived":false,"fork":false,"pushed_at":"2025-06-15T17:06:29.000Z","size":676,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-25T14:54:04.777Z","etag":null,"topics":["database","go","golang","mysql","orm","sql","sql-orm","sqlite","sqlite3","sqlorm"],"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/tkdeng.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":"2024-08-05T14:28:30.000Z","updated_at":"2025-06-15T17:05:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"44725f98-85fb-42b1-9376-a208f63701e6","html_url":"https://github.com/tkdeng/gosql","commit_stats":null,"previous_names":["tkdeng/gosql"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/tkdeng/gosql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkdeng%2Fgosql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkdeng%2Fgosql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkdeng%2Fgosql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkdeng%2Fgosql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tkdeng","download_url":"https://codeload.github.com/tkdeng/gosql/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkdeng%2Fgosql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32677928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T02:33:58.958Z","status":"ssl_error","status_checked_at":"2026-05-06T02:33:39.611Z","response_time":117,"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":["database","go","golang","mysql","orm","sql","sql-orm","sqlite","sqlite3","sqlorm"],"created_at":"2024-11-09T09:37:57.849Z","updated_at":"2026-05-06T03:33:18.854Z","avatar_url":"https://github.com/tkdeng.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoSQL\n\n[\u003cimg src=\"./assets/icon.png\" alt=\"icon\" height=\"100\"/\u003e](./assets/icon.png)\n\nGoSQL is an SQL ORM for the Go programming language.\nIt is intended to add type safety and ease of use to SQL.\n\n## Installation\n\n```shell\ngo get github.com/tkdeng/gosql\n\n# Any SQL Driver\n\n# SQLite\ngo get github.com/mattn/go-sqlite3\n\n# MySQL\ngo get github.com/go-sql-driver/mysql\n```\n\n## Usage\n\n```go\n\nimport (\n  \"github.com/tkdeng/gosql\"\n\n  // SQLite\n  _ \"github.com/mattn/go-sqlite3\"\n\n  // MySQL\n  _ \"github.com/go-sql-driver/mysql\"\n)\n\nfunc main(){\n  // Local File\n  db, err := gosql.Open(\"sqlite3\", \"/path/to/db.sqlite\")\n  \n  // Memory/RAM\n  db, err := gosql.Open(\"sqlite3\", \"\")\n\n  // Server\n  db, err := gosql.Open(\"mysql\", gosql.Server{\n    username: \"user\",\n    password: \"p@ssw0rd!\",\n    host: \"localhost\",\n    port: 1433,\n    protocol: \"tcp\", // or udp\n    database: \"db\",\n  })\n\n  // close database\n  defer db.Close()\n}\n\n```\n\n### Adding data to a table\n\n```go\n// Create or Select a Table\n// note: this method will automatically create a table if it doesn't exist\ntable := db.Table(\"users\",\n  INT(\"id\").Primary().Unique().Default(0), // note: `.AutoInc()` is not supported by sqlite\n  TEXT(\"username\"),\n  TEXT(\"password\"),\n)\n\n// INSERT new row\nerr := table.Set(map[string]any{\n  \"username\": \"user\",\n  \"password\": \"p@ssw0rd!\",\n})\n\n// INSERT or UPDATE row\nerr := table.Set(map[string]any{\n  \"username\": \"user\",\n  \"password\": \"NewPassword!\",\n}, \"username\") // optional: specify unique keys\n\n// UPDATE row\nerr := table.Where(\"id\").Equal(0).Set(map[string]any{\n  \"username\": \"user\",\n  \"password\": \"NewerPassword!\",\n})\n\n// In the above example, if the database finds that\n// \"username\" = \"user\" already exists, it will update the\n// \"password\" of the existing user, instead of creating\n// a new user. If not found, a new user will be created.\n```\n\n### Getting data from a table\n\n```go\n// SELECT data from database\nerr := table.Get([]string{\"id\", \"username\", \"password\"}, func(scan func(dest ...any) error) bool {\n  var id int\n  var username string\n  var password string\n\n  scan(\u0026id, \u0026username, \u0026password) // runs rows.Scan from core sql module\n\n  // return true to continue rows.Next()\n  // return false to break the loop and close the query\n  return true\n})\n\n// check if table has a row WHERE key = value\nif table.Has(map[string]any{\"username\": \"admin\"}) {\n  // admin user exists\n}\n```\n\n### adding WHERE query\n\n```go\nerr := table.Where(\"username\") // WHERE username\n  .Equal(\"user\") // = 'user'\n  .AND(\"password\") // AND password\n  .EQUAL(\"p@ssw0rd!\") // = 'p@ssw0rd!'\n  .Get(nil, func(scan func(dest ...any) error) bool { // SELECT * FROM table\n    // do stuff\n  })\n\nquery := table.Where(\"username\", false).Equal(\"admin\") // WHERE NOT username = 'admin'\n\nquery := table.Where(\"username\").NotEqual(\"admin\") // WHERE username \u003c\u003e 'admin'\n// note: `\u003c\u003e` is equivalent to `!=` in sql\n\nquery := table.Where(\"id\").GreaterThan(0) // WHERE id \u003e 0\n\nquery := table.OrderBy(\"id\") // ORDER BY id\nquery := table.OrderBy(\"id\", true) // ORDER BY id DESC\n\n// note: the Where method returns a new instance of the query\ntable.Where(\"id\").Equal(0)\n\nerr := table.Delete() // will not register the above where query\nerr == gosql.Error_UnsafeQuery\n// For safety, the Delete method will actually return an error if\n// the WHERE query is empty by default.\n// This prevents you from accidently deleting the entire table.\n// (more info about safety checks below)\n```\n\n### Removing data from a table\n\n```go\n// delete row from database\nerr := table.Where(\"password\").Equal(\"p@ssw0rd!\").Delete()\n\n// note: the above example will delete any user with the password \"p@ssw0rd!\"\n\n// If you plan on removing insucure passwords, I would recommend locking the account\n// by updating it with a random password, and let the user change it via email or the\n// 'forgot password' button. Your users will likely be mad if you randomly delete their account.\n\n\n// running Delete, without a Where query will return an error\nerr := table.Delete()\nerr == gosql.Error_UnsafeQuery\n\n// to override this (set @force = true)\nerr := table.Delete(true)\nerr == nil\n// note: the above method will only delete all rows, and keeps the empty table\n\n// to Drop the table\ntable.Drop(true) // note: you must pass 'true' to confirm dropping the table\n```\n\n### Query safety checks\n\n```go\n// to run raw sql queries\ndb.Query() || db.Exec() || db.Prepare()\n// these are a 1 to 1 of the core sql params, but with an additional safety check on the query\n// note: this module uses the above methods when running sql queries (eccept for the Drop method)\n\n\n// this method gets run by default, but you can also call it manually\nif db.SafeQuery(\"SELECT * FROM users\") {\n  // this passed safety checks\n}\n\nif db.SafeQuery(\"SELECT * FROM users WHERE username = 'admin' OR 1=1\") {\n  // this will fail the safety check by default\n\n  // common sql injection includes escaping an input and adding `OR 1=1`,\n  // if any WHERE query checks if something is equal to itself,\n  // it will fail the default safety check.\n}\n\nif db.SafeQuery(\"SELECT * FROM users WHERE username = 'admin'; DROP *\") {\n  // this will fail the safety check by default\n\n  // common sql injection loves to abuse the `;` character.\n  // this feature is not frequently needed, and can simply\n  // be replaced by running another query function.\n}\n\nif db.SafeQuery(\"DROP *\") {\n  // this will fail the safety check by default\n\n  // this is not only to protect against sql injection,\n  // but to also prevent developers from accidently deleting\n  // an entire database.\n\n  // note: the `table.Drop(true)` method will override safety checks.\n}\n\n\n// adding your own safety checks\n\n// this method will add another callback to a list\n// that will be called whenever a query safety check is ran.\ngosql.AddSafetyCheck(func(query string) bool {\n  if safe {\n    return true // return true to continue the safety check list\n  } else {\n    return false // return false to report an unsafe query string\n  }\n})\n\n// for a simple regex match, this method will check if the\n// query matched a regular expression (RE2).\n// if the query matches this regex, it will repoort the query as unsafe\ngosql.AddSafetyCheckRE(`(?i)(WHERE|AND|OR)\\s+NOT`) // this example prevents any `WHERE NOT` queries\n\n// pass @where: true, to only check after the WHERE query\ngosql.AddSafetyCheckRE(`(?i)NOT`, true)\n\n\n// overriding safety checks (Not Recommended)\ndb = db.Unsafe(\"I Know What Im Doing!\") // returns a new database instance that allows unsafe queries\n\n// note: the raw database object from the core sql module will also bypass query safety checks\nvar rawDB *sql.DB = db.SQL\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftkdeng%2Fgosql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftkdeng%2Fgosql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftkdeng%2Fgosql/lists"}