Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tkdeng/gosql
GoSQL is an SQL ORM for the Go programming language. It is intended to add type safety and ease of use to SQL.
https://github.com/tkdeng/gosql
database go golang mysql orm sql sql-orm sqlite sqlite3 sqlorm
Last synced: 7 days ago
JSON representation
GoSQL is an SQL ORM for the Go programming language. It is intended to add type safety and ease of use to SQL.
- Host: GitHub
- URL: https://github.com/tkdeng/gosql
- Owner: tkdeng
- License: mit
- Created: 2024-08-05T14:28:30.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2024-08-29T20:55:49.000Z (3 months ago)
- Last Synced: 2024-08-30T22:05:11.472Z (3 months ago)
- Topics: database, go, golang, mysql, orm, sql, sql-orm, sqlite, sqlite3, sqlorm
- Language: Go
- Homepage:
- Size: 653 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- License: LICENSE
Awesome Lists containing this project
README
# GoSQL
[](./assets/icon.png)
GoSQL is an SQL ORM for the Go programming language.
It is intended to add type safety and ease of use to SQL.## Installation
```shell
go get github.com/tkdeng/gosql# Any SQL Driver
# SQLite
go get github.com/mattn/go-sqlite3# MySQL
go get github.com/go-sql-driver/mysql
```## Usage
```go
import (
"github.com/tkdeng/gosql"// SQLite
_ "github.com/mattn/go-sqlite3"// MySQL
_ "github.com/go-sql-driver/mysql"
)func main(){
// Local File
db, err := gosql.Open("sqlite3", "/path/to/db.sqlite")
// Memory/RAM
db, err := gosql.Open("sqlite3", "")// Server
db, err := gosql.Open("mysql", gosql.Server{
username: "user",
password: "p@ssw0rd!",
host: "localhost",
port: 1433,
protocol: "tcp", // or udp
database: "db",
})// close database
defer db.Close()
}```
### Adding data to a table
```go
// Create or Select a Table
// note: this method will automatically create a table if it doesn't exist
table := db.Table("users",
INT("id").Primary().Unique().Default(0), // note: `.AutoInc()` is not supported by sqlite
TEXT("username"),
TEXT("password"),
)// INSERT new row
err := table.Set(map[string]any{
"username": "user",
"password": "p@ssw0rd!",
})// INSERT or UPDATE row
err := table.Set(map[string]any{
"username": "user",
"password": "NewPassword!",
}, "username") // optional: specify unique keys// UPDATE row
err := table.Where("id").Equal(0).Set(map[string]any{
"username": "user",
"password": "NewerPassword!",
})// In the above example, if the database finds that
// "username" = "user" already exists, it will update the
// "password" of the existing user, instead of creating
// a new user. If not found, a new user will be created.
```### Getting data from a table
```go
// SELECT data from database
err := table.Get([]string{"id", "username", "password"}, func(scan func(dest ...any) error) bool {
var id int
var username string
var password stringscan(&id, &username, &password) // runs rows.Scan from core sql module
// return true to continue rows.Next()
// return false to break the loop and close the query
return true
})// check if table has a row WHERE key = value
if table.Has(map[string]any{"username": "admin"}) {
// admin user exists
}
```### adding WHERE query
```go
err := table.Where("username") // WHERE username
.Equal("user") // = 'user'
.AND("password") // AND password
.EQUAL("p@ssw0rd!") // = 'p@ssw0rd!'
.Get(nil, func(scan func(dest ...any) error) bool { // SELECT * FROM table
// do stuff
})query := table.Where("username", false).Equal("admin") // WHERE NOT username = 'admin'
query := table.Where("username").NotEqual("admin") // WHERE username <> 'admin'
// note: `<>` is equivalent to `!=` in sqlquery := table.Where("id").GreaterThan(0) // WHERE id > 0
query := table.OrderBy("id") // ORDER BY id
query := table.OrderBy("id", true) // ORDER BY id DESC// note: the Where method returns a new instance of the query
table.Where("id").Equal(0)err := table.Delete() // will not register the above where query
err == gosql.Error_UnsafeQuery
// For safety, the Delete method will actually return an error if
// the WHERE query is empty by default.
// This prevents you from accidently deleting the entire table.
// (more info about safety checks below)
```### Removing data from a table
```go
// delete row from database
err := table.Where("password").Equal("p@ssw0rd!").Delete()// note: the above example will delete any user with the password "p@ssw0rd!"
// If you plan on removing insucure passwords, I would recommend locking the account
// by updating it with a random password, and let the user change it via email or the
// 'forgot password' button. Your users will likely be mad if you randomly delete their account.// running Delete, without a Where query will return an error
err := table.Delete()
err == gosql.Error_UnsafeQuery// to override this (set @force = true)
err := table.Delete(true)
err == nil
// note: the above method will only delete all rows, and keeps the empty table// to Drop the table
table.Drop(true) // note: you must pass 'true' to confirm dropping the table
```### Query safety checks
```go
// to run raw sql queries
db.Query() || db.Exec() || db.Prepare()
// these are a 1 to 1 of the core sql params, but with an additional safety check on the query
// note: this module uses the above methods when running sql queries (eccept for the Drop method)// this method gets run by default, but you can also call it manually
if db.SafeQuery("SELECT * FROM users") {
// this passed safety checks
}if db.SafeQuery("SELECT * FROM users WHERE username = 'admin' OR 1=1") {
// this will fail the safety check by default// common sql injection includes escaping an input and adding `OR 1=1`,
// if any WHERE query checks if something is equal to itself,
// it will fail the default safety check.
}if db.SafeQuery("SELECT * FROM users WHERE username = 'admin'; DROP *") {
// this will fail the safety check by default// common sql injection loves to abuse the `;` character.
// this feature is not frequently needed, and can simply
// be replaced by running another query function.
}if db.SafeQuery("DROP *") {
// this will fail the safety check by default// this is not only to protect against sql injection,
// but to also prevent developers from accidently deleting
// an entire database.// note: the `table.Drop(true)` method will override safety checks.
}// adding your own safety checks
// this method will add another callback to a list
// that will be called whenever a query safety check is ran.
gosql.AddSafetyCheck(func(query string) bool {
if safe {
return true // return true to continue the safety check list
} else {
return false // return false to report an unsafe query string
}
})// for a simple regex match, this method will check if the
// query matched a regular expression (RE2).
// if the query matches this regex, it will repoort the query as unsafe
gosql.AddSafetyCheckRE(`(?i)(WHERE|AND|OR)\s+NOT`) // this example prevents any `WHERE NOT` queries// pass @where: true, to only check after the WHERE query
gosql.AddSafetyCheckRE(`(?i)NOT`, true)// overriding safety checks (Not Recommended)
db = db.Unsafe("I Know What Im Doing!") // returns a new database instance that allows unsafe queries// note: the raw database object from the core sql module will also bypass query safety checks
var rawDB *sql.DB = db.SQL
```