2
2
3
3
[](https://pkg.go.dev/github.com/aldy505/bob) [](https://goreportcard.com/report/github.com/aldy505/bob)  [](https://www.codefactor.io/repository/github/aldy505/bob) [](https://codecov.io/gh/aldy505/bob) [](https://www.codacy.com/gh/aldy505/bob/dashboard?utm_source=github.com&utm_medium=referral&utm_content=aldy505/bob&utm_campaign=Badge_Grade) [](https://github.com/aldy505/bob/actions/workflows/build.yml) [](https://github.com/aldy505/bob/actions/workflows/coverage.yml)
4
4
5
- I really need a create table SQL builder, and I can't find one. So, like everything else, I made one. Heavily inspired by [ Squirrel] ( https://github.com/Masterminds/squirrel ) and [ Knex] ( https://knexjs.org/ ) . And of course, I still use Squirrel for other types of queries (insert, select, and all), think this package as an extension for Squirrel .
5
+ 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 .
6
6
7
- Oh, and of course, heavily inspired by Bob the Builder.
7
+ Oh, and of course, heavily inspired by [ Bob the Builder] ( https://en.wikipedia.org/wiki/Bob_the_Builder ) .
8
8
9
9
``` go
10
10
import " github.com/aldy505/bob"
11
11
```
12
12
13
13
## Usage
14
14
15
- It's not ready for production yet. But, the API is probably close to how you'd do things on Squirrel. This is an example for using with pgx.
15
+ It's not ready for large-scale production yet (I've already using it on one of my projects). But, the API is probably close to how you'd do things on Squirrel.
16
+
17
+ ### Create a table
18
+
19
+ ``` go
20
+ import " github.com/aldy505/bob"
21
+
22
+ func main () {
23
+ // Note that CREATE TABLE don't return args params.
24
+ sql , _ , err := bob.
25
+ CreateTable (" tableName" ).
26
+ // The first parameter is the column's name.
27
+ // The second parameters and so on forth are extras.
28
+ StringColumn (" id" , " NOT NULL" , " PRIMARY KEY" , " AUTOINCREMENT" ).
29
+ StringColumn (" email" , " NOT NULL" , " UNIQUE" ).
30
+ // See the list of available column definition type through pkg.go.dev or scroll down below.
31
+ TextColumn (" password" ).
32
+ // Or add your custom types
33
+ AddColumn (bob.ColumnDef {Name: " tableName" , Type: " customType" , Extras: []string {" NOT NULL" }}).
34
+ ToSql ()
35
+ if err != nil {
36
+ // handle your error
37
+ }
38
+ }
39
+ ```
40
+
41
+ Available column definition types:
42
+ * ` StringColumn() ` - Default to ` VARCHAR(255) `
43
+ * ` TextColumn() ` - Default to ` TEXT `
44
+ * ` UUIDColumn() ` - Defaults to ` UUID `
45
+ * ` BooleanColumn() ` - Defaults to ` BOOLEAN `
46
+ * ` IntegerColumn() ` - Defaults to ` INTEGER ` . Postgres and SQLite only.
47
+ * ` IntColumn() ` - Defaults to ` INT ` . MySQL and MSSQL only.
48
+ * ` RealColumn() ` - Defaults to ` REAL ` . Postgres, MSSQL, and SQLite only.
49
+ * ` FloatColumn() ` - Defaults to ` FLOAT ` . Postgres and SQLite only.
50
+ * ` DateTimeColumn() ` - Defaults to ` DATETIME ` .
51
+ * ` TimeStampColumn() ` - Defaults to ` TIMESTAMP ` .
52
+ * ` TimeColumn() ` - Defaults to ` TIME ` .
53
+ * ` DateColumn() ` - Defaults to ` DATE ` .
54
+ * ` JSONColumn() ` - Dafults to ` JSON ` . MySQL and Postgres only.
55
+ * ` JSONBColumn() ` - Defaults to ` JSONB ` . Postgres only.
56
+ * ` BlobColumn() ` - Defaults to ` BLOB ` . MySQL and SQLite only.
57
+
58
+ For any other types, please use ` AddColumn() ` .
59
+
60
+ Another builder of ` bob.CreateTableIfNotExists() ` is also available.
61
+
62
+ ### Check if a table exists
63
+
64
+ ``` go
65
+ func main () {
66
+ sql , args , err := bob.HasTable (" users" ).ToSql ()
67
+ if err != nil {
68
+ log.Fatal (err)
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Check if a column exists
74
+
75
+ ``` go
76
+ func main () {
77
+ sql , args , err := bob.HasColumn (" email" ).ToSql ()
78
+ if err != nil {
79
+ log.Fatal (err)
80
+ }
81
+ }
82
+ ```
83
+
84
+ ### Placeholder format
85
+
86
+ Default placeholder is a question mark (MySQL-like). If you want to change it, simply use something like this:
87
+
88
+ ``` go
89
+ func main () {
90
+ // Option 1
91
+ sql , args , err := bob.HasTable (" users" ).PlaceholderFormat (bob.Dollar ).ToSql ()
92
+ if err != nil {
93
+ log.Fatal (err)
94
+ }
95
+
96
+ // Option 2
97
+ sql, args, err = bob.HasTable (" users" ).ToSql ()
98
+ if err != nil {
99
+ log.Fatal (err)
100
+ }
101
+ correctPlaceholder := bob.ReplacePlaceholder (sql, bob.Dollar )
102
+ }
103
+ ```
104
+
105
+ Available placeholder formats:
106
+ * ` bob.Question ` - ` INSERT INTO "users" (name) VALUES (?) `
107
+ * ` bob.Dollar ` - ` INSERT INTO "users" (name) VALUES ($1) `
108
+ * ` bob.Colon ` - ` INSERT INTO "users" (name) VALUES (:1) `
109
+ * ` bob.AtP ` - ` INSERT INTO "users" (name) VALUES (@p1) `
110
+
111
+ ### With pgx (PostgreSQL)
16
112
17
113
``` go
18
114
import (
@@ -36,7 +132,7 @@ func main() {
36
132
var hasTableUsers bool
37
133
err = db.QueryRow (context.Background (), sql, args...).Scan (&hasTableUsers)
38
134
if err != nil {
39
- if err. Error () == " no rows in result set " {
135
+ if err == bob. ErrEmptyTablePg {
40
136
hasTableUsers = false
41
137
} else {
42
138
log.Fatal (err)
@@ -46,47 +142,61 @@ func main() {
46
142
if !hasTableUsers {
47
143
// Create "users" table
48
144
// Note that this will return multiple query in a single string.
49
- sql , _ , err := bob.CreateTable (" users" ).
50
- Columns (" id" , " email" , " name" , " password" , " date" ).
51
- Types (" varchar(36)" , " varchar(255)" , " varchar(255)" , " text" , " date" ).
52
- Primary (" id" ).
53
- Unique (" email" )
145
+ sql , _ , err := bob.
146
+ CreateTable (" users" ).
147
+ IntegerColumn (" id" , " PRIMARY KEY" , " SERIAL" ).
148
+ StringColumn (" name" , " NOT NULL" ).
149
+ TextColumn (" password" , " NOT NULL" ).
150
+ DateColumn (" created_at" ).
54
151
ToSql ()
55
152
if err != nil {
56
153
log.Fatal (err)
57
154
}
58
155
59
- // If you don't do this, you will get the error:
60
- // ERROR: cannot insert multiple commands into a prepared statement (SQLSTATE 42601)
61
- splitQuery := strings.Split (sql, " ;" )
62
- for i := range splitQuery {
63
- _, err = db.Query (context.Background (), splitQuery[i])
64
- if err != nil {
65
- log.Fatal (err)
66
- }
156
+ _, err = db.Query (context.Background (), splitQuery[i])
157
+ if err != nil {
158
+ log.Fatal (err)
67
159
}
68
160
69
161
// Create another table, this time with CREATE TABLE IF NOT EXISTS
70
- sql , _ , err := bob.CreateTableIfNotExists (" inventory" ).
71
- Columns (" id" , " userID" , " items" , " quantity" ).
72
- Types (" varchar(36)" , " varchar(36)" , " json" , " int" ).
73
- Primary (" id" ).
162
+ sql , _ , err := bob.
163
+ CreateTableIfNotExists (" inventory" ).
164
+ UUIDColumn (" id" , " PRIMARY KEY" ).
165
+ IntegerColumn (" userID" , " FOREIGN KEY REFERENCES users(id)" ).
166
+ JSONColumn (" items" ).
167
+ IntegerColumn (" quantity" ).
74
168
ToSql ()
75
169
if err != nil {
76
170
log.Fatal (err)
77
171
}
78
172
79
- inventoryQuery := strings.Split (sql, " ;" )
80
- for i := range inventoryQuery {
81
- _, err = db.Query (context.Background (), inventoryQuery[i])
82
- if err != nil {
83
- log.Fatal (err)
84
- }
173
+ _, err = db.Query (context.Background (), inventoryQuery[i])
174
+ if err != nil {
175
+ log.Fatal (err)
85
176
}
86
177
}
87
178
}
88
179
```
89
180
181
+ ## Features
182
+
183
+ * ` bob.CreateTable(tableName) ` - Basic SQL create table
184
+ * ` bob.CreateTableIfNotExists(tableName) ` - Create table if not exists
185
+ * ` bob.HasTable(tableName) ` - Checks if column exists (return error if false, check example above for error handling)
186
+ * ` bob.HasColumn(columnName) ` - Check if a column exists on current table
187
+
188
+ ### TODO
189
+
190
+ Meaning these are some ideas for the future development of Bob.
191
+
192
+ * ` bob.DropTable(tableName) ` - Drop a table (` drop table "users" ` )
193
+ * ` bob.DropTableIfExists(tableName) ` - Drop a table if exists (` drop table if exists "users" ` )
194
+ * ` bob.RenameTable(tableName) ` - Rename a table (` rename table "users" to "old_users" ` )
195
+ * ` bob.Truncate(tableName) ` - Truncate a table (` truncate "users" ` )
196
+ * ` bob.Upsert(tableName) ` - UPSERT function (` insert into "users" ("name", "email") values (?, ?) on duplicate key update email = ? ` )
197
+ * ` bob.ExecWith() ` - Just like Squirrel's [ ExecWith] ( https://pkg.go.dev/github.com/Masterminds/squirrel?utm_source=godoc#ExecWith )
198
+ * ` bob.Count(tableName, columnName) ` - Count query (` select count("active") from "users" ` )
199
+
90
200
## Contributing
91
201
92
202
Contributions are always welcome! As long as you add a test for your changes.
0 commit comments