docs: add proper information and introductions

This commit is contained in:
Reinaldy Rafli 2021-12-10 16:44:15 +07:00
parent 63c353537e
commit 19b92b7f3f
No known key found for this signature in database
GPG Key ID: CFDB9400255D8CB6
3 changed files with 212 additions and 14 deletions

View File

@ -1,18 +1,51 @@
# Bob - SQL Query Builder # 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 ```go
import "github.com/aldy505/bob" 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 ### Create a table
@ -299,13 +332,6 @@ func main() {
* `bob.Truncate(tableName)` - Truncate a table (`truncate "users"`) * `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 = ?`) * `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 ## Contributing
Contributions are always welcome! As long as you add a test for your changes. 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 ## License
Bob is licensed under [MIT license](./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
View File

@ -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 package bob
import ( import (

132
example_test.go Normal file
View File

@ -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]
}