mirror of https://github.com/aldy505/bob.git
docs: add proper information and introductions
This commit is contained in:
parent
63c353537e
commit
19b92b7f3f
71
README.md
71
README.md
|
@ -1,18 +1,51 @@
|
|||
# Bob - SQL Query Builder
|
||||
|
||||
[![Go Reference](https://pkg.go.dev/badge/github.com/aldy505/bob.svg)](https://pkg.go.dev/github.com/aldy505/bob) [![Go Report Card](https://goreportcard.com/badge/github.com/aldy505/bob)](https://goreportcard.com/report/github.com/aldy505/bob) ![GitHub](https://img.shields.io/github/license/aldy505/bob) [![CodeFactor](https://www.codefactor.io/repository/github/aldy505/bob/badge)](https://www.codefactor.io/repository/github/aldy505/bob) [![codecov](https://codecov.io/gh/aldy505/bob/branch/master/graph/badge.svg?token=Noeexg5xEJ)](https://codecov.io/gh/aldy505/bob) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/9b78970127c74c1a923533e05f65848d)](https://www.codacy.com/gh/aldy505/bob/dashboard?utm_source=github.com&utm_medium=referral&utm_content=aldy505/bob&utm_campaign=Badge_Grade) [![Build test](https://github.com/aldy505/bob/actions/workflows/build.yml/badge.svg)](https://github.com/aldy505/bob/actions/workflows/build.yml) [![Test and coverage](https://github.com/aldy505/bob/actions/workflows/coverage.yml/badge.svg)](https://github.com/aldy505/bob/actions/workflows/coverage.yml)
|
||||
[![Go Reference](pkg-go-dev-badge)](pkg-go-dev-link)
|
||||
[![Go Report Card](go-report-badge)](go-report-link)
|
||||
![GitHub](license-badge)
|
||||
[![CodeFactor](codefactor-badge)](codefactor-link)
|
||||
[![codecov](codecov-badge)](codecov-link)
|
||||
[![Codacy Badge](codacy-badge)](codacy-link)
|
||||
[![Test and coverage](actions-badge)](actions-link)
|
||||
|
||||
Think of this as an extension of [Squirrel](https://github.com/Masterminds/squirrel) with functionability like [Knex](https://knexjs.org/). I still use Squirrel for other types of queries (insert, select, and all that), but I needed some SQL builder for create table and some other stuffs. Including database creation & upsert.
|
||||
Bob is an SQL builder library initially made as an extension for [Squirrel](squirrel-url)
|
||||
with functionality like [Knex](knex-url) (from the Node.js world). Squirrel itself
|
||||
doesn't provide other types of queries for creating a table, upsert,
|
||||
and some other things. Bob is meant to fill those gaps.
|
||||
|
||||
Oh, and of course, heavily inspired by [Bob the Builder](https://en.wikipedia.org/wiki/Bob_the_Builder).
|
||||
The different between Bob and Squirrel is that Bob is solely a query builder.
|
||||
The users have to execute and manage the SQL connection themself.
|
||||
Meaning there are no ExecWith() function implemented on Bob, as you can
|
||||
find it on Squirrel.
|
||||
|
||||
The purpose of an SQL query builder is to prevent any typo or mistypes
|
||||
on the SQL queries. Although also with that reason, Bob might not always
|
||||
have the right query for you, depending on what you are doing with the
|
||||
SQL query. It might sometimes be better for you to write the SQL query
|
||||
yourself, if your problem is specific and needs some micro-tweaks.
|
||||
|
||||
With that being said, I hope you enjoy using Bob and consider starring or
|
||||
reporting any issues regarding the usage of Bob in your projects.
|
||||
|
||||
Oh, and of course, heavily inspired by [Bob the Builder](bob-wikipedia).
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import "github.com/aldy505/bob"
|
||||
```
|
||||
|
||||
## Usage
|
||||
Like any other Go projects when you're using Go modules, just put that
|
||||
text right there on the top of your projects, do `go mod tidy` and
|
||||
you are good to go.
|
||||
|
||||
It's not ready for large-scale production yet (although I've already using it on one of my projects). But, the API is probably close to how you'd do things on Squirrel.
|
||||
Either way, I'm not 100% confident enough to say that this thing is
|
||||
production ready. But, the way I see it, it's good enough to be used
|
||||
on a production-level applications. In fact, I'm using it on one of my
|
||||
current projects that's getting around 100-200 hits per day.
|
||||
|
||||
If you have any feature request or improvement ideas for the project,
|
||||
please kindly open an issue
|
||||
|
||||
### Create a table
|
||||
|
||||
|
@ -177,7 +210,7 @@ func main() {
|
|||
Key("email").
|
||||
Replace("age", 40).
|
||||
ToSql()
|
||||
|
||||
|
||||
// One more time, for MSSQL / SQL Server.
|
||||
sql, args, err = bob.
|
||||
Upsert("users", bob.MSSQL).
|
||||
|
@ -276,7 +309,7 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
_, err = db.Query(context.Background(), inventoryQuery[i])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -299,13 +332,6 @@ func main() {
|
|||
* `bob.Truncate(tableName)` - Truncate a table (`truncate "users"`)
|
||||
* `bob.Upsert(tableName, dialect)` - UPSERT function (`insert into "users" ("name", "email") values (?, ?) on duplicate key update email = ?`)
|
||||
|
||||
### TODO
|
||||
|
||||
Meaning these are some ideas for the future development of Bob.
|
||||
|
||||
* `bob.ExecWith()` - Just like Squirrel's [ExecWith](https://pkg.go.dev/github.com/Masterminds/squirrel?utm_source=godoc#ExecWith)
|
||||
* `bob.Count(tableName, columnName)` - Count query (`select count("active") from "users"`)
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are always welcome! As long as you add a test for your changes.
|
||||
|
@ -313,3 +339,20 @@ Contributions are always welcome! As long as you add a test for your changes.
|
|||
## License
|
||||
|
||||
Bob is licensed under [MIT license](./LICENSE)
|
||||
|
||||
[squirrel-url]: https://github.com/Masterminds/squirrel
|
||||
[knex-url]: https://knexjs.org/
|
||||
[bob-wikipedia]: https://en.wikipedia.org/wiki/Bob_the_Builder
|
||||
[pkg-go-dev-badge]: https://pkg.go.dev/badge/github.com/aldy505/bob.svg
|
||||
[pkg-go-dev-link]: https://pkg.go.dev/github.com/aldy505/bob
|
||||
[go-report-badge]: https://goreportcard.com/badge/github.com/aldy505/bob
|
||||
[go-report-link]: https://goreportcard.com/report/github.com/aldy505/bob
|
||||
[license-badge]: https://img.shields.io/github/license/aldy505/bob
|
||||
[codefactor-link]: https://www.codefactor.io/repository/github/aldy505/bob
|
||||
[codefactor-badge]: https://www.codefactor.io/repository/github/aldy505/bob/badge
|
||||
[codecov-badge]: https://codecov.io/gh/aldy505/bob/branch/master/graph/badge.svg?token=Noeexg5xEJ
|
||||
[codecov-link]: https://codecov.io/gh/aldy505/bob
|
||||
[codacy-badge]: https://app.codacy.com/project/badge/Grade/9b78970127c74c1a923533e05f65848d
|
||||
[codacy-link]: https://www.codacy.com/gh/aldy505/bob/dashboard?utm_source=github.com&utm_medium=referral&utm_content=aldy505/bob&utm_campaign=Badge_Grade
|
||||
[actions-badge]: https://github.com/aldy505/bob/actions/workflows/coverage.yml/badge.svg
|
||||
[actions-link]: https://github.com/aldy505/bob/actions/workflows/coverage.yml
|
||||
|
|
23
bob.go
23
bob.go
|
@ -1,3 +1,26 @@
|
|||
// Bob is an SQL builder library initially made as an extension for Squirrel
|
||||
// with functionality like Knex (from the Node.js world). Squirrel itself
|
||||
// doesn't provide other types of queries for creating a table, upsert,
|
||||
// and some other things. Bob is meant to fill those gaps.
|
||||
//
|
||||
// The different between Bob and Squirrel is that Bob is solely a query builder.
|
||||
// The users have to execute and manage the SQL connection themself.
|
||||
// Meaning there are no ExecWith() function implemented on Bob, as you can
|
||||
// find it on Squirrel.
|
||||
//
|
||||
// The purpose of an SQL query builder is to prevent any typo or mistypes
|
||||
// on the SQL queries. Although also with that reason, Bob might not always
|
||||
// have the right query for you, depending on what you are doing with the
|
||||
// SQL query. It might sometimes be better for you to write the SQL query
|
||||
// yourself, if your problem is specific and needs some micro-tweaks.
|
||||
//
|
||||
// With that being said, I hope you enjoy using Bob and consider starring or
|
||||
// reporting any issues regarding the usage of Bob in your projects.
|
||||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2021-present Reinaldy Rafli and Bob collaborators
|
||||
//
|
||||
package bob
|
||||
|
||||
import (
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
package bob_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/aldy505/bob"
|
||||
)
|
||||
|
||||
func ExampleCreateIndex() {
|
||||
sql, _, err := bob.
|
||||
CreateIndex("idx_email").
|
||||
On("users").
|
||||
Unique().
|
||||
Columns(bob.IndexColumn{Name: "email", Collate: "DEFAULT", Extras: []string{"ASC"}}).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
fmt.Printf("Handle this error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Print(sql)
|
||||
// Output: CREATE UNIQUE INDEX idx_email ON users (email COLLATE DEFAULT ASC);
|
||||
}
|
||||
|
||||
func ExampleHasTable() {
|
||||
sql, args, err := bob.HasTable("users").ToSql()
|
||||
if err != nil {
|
||||
fmt.Printf("Handle this error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("sql: %s, args: %v", sql, args)
|
||||
// Output: sql: SELECT * FROM information_schema.tables WHERE table_name = ? AND table_schema = current_schema();, args: [users]
|
||||
}
|
||||
|
||||
func ExampleHasColumn() {
|
||||
sql, args, err := bob.HasColumn("email").ToSql()
|
||||
if err != nil {
|
||||
fmt.Printf("Handle this error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("sql: %s, args: %v", sql, args)
|
||||
// Output: sql: SELECT * FROM information_schema.columns WHERE table_name = ? AND table_schema = current_schema();, args: [users]
|
||||
}
|
||||
|
||||
func ExampleDropTable() {
|
||||
sql, _, err := bob.DropTable("users").Cascade().ToSql()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(sql)
|
||||
// Output: DROP TABLE users CASCADE;
|
||||
}
|
||||
|
||||
func ExampleDropTableIfExists() {
|
||||
sql, _, err := bob.DropTableIfExists("users").ToSql()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(sql)
|
||||
// Output: DROP TABLE IF EXISTS users;
|
||||
}
|
||||
|
||||
func ExampleTruncate() {
|
||||
sql, _, err := bob.Truncate("users").ToSql()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(sql)
|
||||
// Output: TRUNCATE TABLE users;
|
||||
}
|
||||
|
||||
func ExampleRenameTable() {
|
||||
sql, _, err := bob.RenameTable("users", "people").ToSql()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(sql)
|
||||
// Output: ALTER TABLE users RENAME TO people;
|
||||
}
|
||||
|
||||
func ExampleUpsert() {
|
||||
// Example for MYSQL
|
||||
mysql, myArgs, err := bob.
|
||||
// Notice that you should give database dialect on the second params.
|
||||
// Available database dialect are MySQL, PostgreSQL, SQLite, and MSSQL.
|
||||
Upsert("users", bob.MySQL).
|
||||
Columns("name", "email", "age").
|
||||
// You could do multiple Values() call, but I'd suggest to not do it.
|
||||
// Because this is an upsert function, not an insert one.
|
||||
Values("Thomas Mueler", "tmueler@something.com", 25).
|
||||
Replace("age", 25).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
fmt.Printf("Handle this error: %v", err)
|
||||
}
|
||||
|
||||
// Another example for PostgreSQL
|
||||
pgsql, pgArgs, err := bob.
|
||||
Upsert("users", bob.PostgreSQL).
|
||||
Columns("name", "email", "age").
|
||||
Values("Billy Urtha", "billu@something.com", 30).
|
||||
Key("email").
|
||||
Replace("age", 40).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
fmt.Printf("Handle this error: %v", err)
|
||||
}
|
||||
|
||||
// One more time, for MSSQL / SQL Server.
|
||||
mssql, msArgs, err := bob.
|
||||
Upsert("users", bob.MSSQL).
|
||||
Columns("name", "email", "age").
|
||||
Values("George Rust", "georgee@something.com", 19).
|
||||
Key("email", "georgee@something.com").
|
||||
Replace("age", 18).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
fmt.Printf("Handle this error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("MySQL: %s, %v\n", mysql, myArgs)
|
||||
fmt.Printf("PostgreSQL: %s, %v\n", pgsql, pgArgs)
|
||||
fmt.Printf("MSSQL: %s, %v\n", mssql, msArgs)
|
||||
// Output:
|
||||
// MySQL: INSERT INTO "users" ("name", "email", "age") VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE "age" = ?;, [Thomas Mueler tmueler@something.com 25 25]
|
||||
// PostgreSQL: INSERT INTO "users" ("name", "email", "age") VALUES ($1, $2, $3) ON CONFLICT ("email") DO UPDATE SET "age" = $4;, [Billy Urtha billu@something.com 30 40]
|
||||
// MSSQL: IF NOT EXISTS (SELECT * FROM "users" WHERE "email" = @p1) INSERT INTO "users" ("name", "email", "age") VALUES (@p2, @p3, @p4) ELSE UPDATE "users" SET "age" = @p5 WHERE "email" = @p6;, [georgee@something.com George Rust georgee@something.com 19 18 georgee@something.com]
|
||||
}
|
Loading…
Reference in New Issue