Merge pull request #15 from aldy505/docs/examples

docs: examples
This commit is contained in:
Reinaldy Rafli 2021-12-10 16:57:58 +07:00 committed by GitHub
commit 6402e24423
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 218 additions and 44 deletions

View File

@ -1,26 +0,0 @@
name: Build test
on: [pull_request, push]
jobs:
build-test:
name: Build test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: [1.15.x, 1.16.x, 1.17.x]
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Run go vet
run: go vet
- name: Test
run: go test -v -race -covermode=atomic -failfast

View File

@ -3,21 +3,24 @@ name: Test and coverage
on: [push, pull_request]
jobs:
build:
check:
name: Check
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 2
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.17.x
- name: Vet check
run: go vet -v
- name: Run coverage
run: go test -v -race -coverprofile=coverage.out -covermode=atomic -failfast
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v1

View File

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

131
example_test.go Normal file
View File

@ -0,0 +1,131 @@
package bob_test
import (
"fmt"
"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").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.columns WHERE table_name = ? AND column_name = ? AND table_schema = current_schema();, args: [users email]
}
func ExampleDropTable() {
sql, _, err := bob.DropTable("users").Cascade().ToSql()
if err != nil {
fmt.Printf("Handle this error: %v", err)
}
fmt.Println(sql)
// Output: DROP TABLE "users" CASCADE;
}
func ExampleDropTableIfExists() {
sql, _, err := bob.DropTableIfExists("users").ToSql()
if err != nil {
fmt.Printf("Handle this error: %v", err)
}
fmt.Println(sql)
// Output: DROP TABLE IF EXISTS "users";
}
func ExampleTruncate() {
sql, _, err := bob.Truncate("users").ToSql()
if err != nil {
fmt.Printf("Handle this error: %v", err)
}
fmt.Println(sql)
// Output: TRUNCATE "users";
}
func ExampleRenameTable() {
sql, _, err := bob.RenameTable("users", "people").ToSql()
if err != nil {
fmt.Printf("Handle this error: %v", err)
}
fmt.Println(sql)
// Output: RENAME TABLE "users" 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]
}