Skip to content

Commit

Permalink
fix: replacePlaceholder now do things properly
Browse files Browse the repository at this point in the history
test: added more tests
  • Loading branch information
aldy505 committed Jun 26, 2021
1 parent 5c112c7 commit 03e6bdb
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 43 deletions.
26 changes: 9 additions & 17 deletions .github/COMMIT_CONVENTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,29 @@ Angular's [commit message guidelines](https://github.com/angular/angular/blob/ma

Appears under "Features" header, pencil subheader:

```
```xml
feat(pencil): add 'graphiteWidth' option
```

Appears under "Bug Fixes" header, graphite subheader, with a link to issue #28:

```
```xml
fix(graphite): stop graphite breaking when width < 0.1

Closes #28
```

Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:

```
```xml
perf(pencil): remove graphiteWidth option

BREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reason.
```

The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.

```
```xml
revert: feat(pencil): add 'graphiteWidth' option

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
Expand All @@ -40,7 +40,7 @@ This reverts commit 667ecc1654a317a13331b17617d973392f415f02.

A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:

```
```xml
<type>(<scope>): <subject>
<BLANK LINE>
<body>
Expand Down Expand Up @@ -71,9 +71,9 @@ The scope could be anything specifying place of the commit change. For example `

The subject contains succinct description of the change:

* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end

### Body

Expand All @@ -87,14 +87,6 @@ reference GitHub issues that this commit **Closes**.

**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.

A detailed explanation can be found in this [document](#commit-message-format).
A detailed explanation can be found in this [document][commit-message-format].

[npm-image]: https://badge.fury.io/js/conventional-changelog-angular.svg
[npm-url]: https://npmjs.org/package/conventional-changelog-angular
[travis-image]: https://travis-ci.org/conventional-changelog/conventional-changelog-angular.svg?branch=master
[travis-url]: https://travis-ci.org/conventional-changelog/conventional-changelog-angular
[daviddm-image]: https://david-dm.org/conventional-changelog/conventional-changelog-angular.svg?theme=shields.io
[daviddm-url]: https://david-dm.org/conventional-changelog/conventional-changelog-angular
[coveralls-image]: https://coveralls.io/repos/conventional-changelog/conventional-changelog-angular/badge.svg
[coveralls-url]: https://coveralls.io/r/conventional-changelog/conventional-changelog-angular
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func main() {
Types("varchar(36)", "varchar(255)", "varchar(255)", "text", "date").
Primary("id").
Unique("email")
ToSql()
ToSQL()
if err != nil {
log.Fatal(err)
}
Expand Down
9 changes: 5 additions & 4 deletions append.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package bob

import "io"

func appendToSql(parts []BobBuilder, w io.Writer, sep string, args []interface{}) ([]interface{}, error) {
// appendToSQL - Documentation coming soon
func appendToSQL(parts []BobBuilder, w io.Writer, sep string, args []interface{}) ([]interface{}, error) {
for i, p := range parts {
partSql, partArgs, err := p.ToSql()
partSQL, partArgs, err := p.ToSQL()
if err != nil {
return nil, err
} else if len(partSql) == 0 {
} else if len(partSQL) == 0 {
continue
}

Expand All @@ -18,7 +19,7 @@ func appendToSql(parts []BobBuilder, w io.Writer, sep string, args []interface{}
}
}

_, err = io.WriteString(w, partSql)
_, err = io.WriteString(w, partSQL)
if err != nil {
return nil, err
}
Expand Down
11 changes: 10 additions & 1 deletion bob.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,43 @@ package bob

import "github.com/lann/builder"

// BobBuilderType is the type for BobBuilder
type BobBuilderType builder.Builder

// BobBuilder interface wraps the ToSQL method
type BobBuilder interface {
ToSql() (string, []interface{}, error)
ToSQL() (string, []interface{}, error)
}

// CreateTable creates a table with CreateBuilder interface
func (b BobBuilderType) CreateTable(table string) CreateBuilder {
return CreateBuilder(b).Name(table)
}

// HasTable checks if a table exists with HasBuilder interface
func (b BobBuilderType) HasTable(table string) HasBuilder {
return HasBuilder(b).HasTable(table)
}

// HasColumn checks if a column exists with HasBuilder interface
func (b BobBuilderType) HasColumn(column string) HasBuilder {
return HasBuilder(b).HasColumn(column)
}

// BobStmtBuilder is the parent builder for BobBuilderType
var BobStmtBuilder = BobBuilderType(builder.EmptyBuilder)

// CreateTable creates a table with CreateBuilder interface
func CreateTable(table string) CreateBuilder {
return BobStmtBuilder.CreateTable(table)
}

// HasTable checks if a table exists with HasBuilder interface
func HasTable(table string) HasBuilder {
return BobStmtBuilder.HasTable(table)
}

// HasColumn checks if a column exists with HasBuilder interface
func HasColumn(col string) HasBuilder {
return BobStmtBuilder.HasColumn(col)
}
14 changes: 11 additions & 3 deletions create.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,44 @@ func init() {
builder.Register(CreateBuilder{}, createData{})
}

// Name sets the table name
func (b CreateBuilder) Name(name string) CreateBuilder {
return builder.Set(b, "TableName", name).(CreateBuilder)
}

// WithSchema specifies the schema to be used when using the schema-building commands.
func (b CreateBuilder) WithSchema(name string) CreateBuilder {
return builder.Set(b, "Schema", name).(CreateBuilder)
}

// Columns sets the column names
func (b CreateBuilder) Columns(cols ...string) CreateBuilder {
return builder.Set(b, "Columns", cols).(CreateBuilder)
}

// Types set a type for certain column
func (b CreateBuilder) Types(types ...string) CreateBuilder {
return builder.Set(b, "Types", types).(CreateBuilder)
}

// Primary will set that column as the primary key for a table.
func (b CreateBuilder) Primary(column string) CreateBuilder {
return builder.Set(b, "Primary", column).(CreateBuilder)
}

// Unique adds an unique index to a table over the given columns.
func (b CreateBuilder) Unique(column string) CreateBuilder {
return builder.Set(b, "Unique", column).(CreateBuilder)
}

func (b CreateBuilder) ToSql() (string, []interface{}, error) {
// ToSQL returns 3 variables filled out with the correct values based on bindings, etc.
func (b CreateBuilder) ToSQL() (string, []interface{}, error) {
data := builder.GetStruct(b).(createData)
return data.ToSql()
return data.ToSQL()
}

func (d *createData) ToSql() (sqlStr string, args []interface{}, err error) {
// ToSQL returns 3 variables filled out with the correct values based on bindings, etc.
func (d *createData) ToSQL() (sqlStr string, args []interface{}, err error) {
if len(d.TableName) == 0 || d.TableName == "" {
err = errors.New("create statements must specify a table")
return
Expand Down
14 changes: 7 additions & 7 deletions create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

func TestCreate(t *testing.T) {
t.Run("should return correct sql string with basic columns and types", func(t *testing.T) {
sql, _, err := bob.CreateTable("users").Columns("name", "password", "date").Types("varchar(255)", "text", "date").ToSql()
sql, _, err := bob.CreateTable("users").Columns("name", "password", "date").Types("varchar(255)", "text", "date").ToSQL()
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -24,7 +24,7 @@ func TestCreate(t *testing.T) {
Types("uuid", "varchar(255)", "varchar(255)", "text", "date").
Primary("id").
Unique("email").
ToSql()
ToSQL()
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -35,7 +35,7 @@ func TestCreate(t *testing.T) {
})

t.Run("should be able to have a schema name", func(t *testing.T) {
sql, _, err := bob.CreateTable("users").WithSchema("private").Columns("name", "password", "date").Types("varchar(255)", "text", "date").ToSql()
sql, _, err := bob.CreateTable("users").WithSchema("private").Columns("name", "password", "date").Types("varchar(255)", "text", "date").ToSQL()
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -49,28 +49,28 @@ func TestCreate(t *testing.T) {
_, _, err := bob.CreateTable("users").
Columns("id", "name", "email", "password", "date").
Types("uuid", "varchar(255)", "varchar(255)", "date").
ToSql()
ToSQL()
if err.Error() != "columns and types should have equal length" {
t.Fatal("should throw an error, it didn't:", err.Error())
}
})

t.Run("should emit error on empty table name", func(t *testing.T) {
_, _, err := bob.CreateTable("").Columns("name").Types("text").ToSql()
_, _, err := bob.CreateTable("").Columns("name").Types("text").ToSQL()
if err.Error() != "create statements must specify a table" {
t.Fatal("should throw an error, it didn't:", err.Error())
}
})

t.Run("should emit error for primary key not in columns", func(t *testing.T) {
_, _, err := bob.CreateTable("users").Columns("name").Types("text").Primary("id").ToSql()
_, _, err := bob.CreateTable("users").Columns("name").Types("text").Primary("id").ToSQL()
if err.Error() != "supplied primary column name doesn't exists on columns" {
t.Fatal("should throw an error, it didn't:", err.Error())
}
})

t.Run("should emit error for unique key not in columns", func(t *testing.T) {
_, _, err := bob.CreateTable("users").Columns("name").Types("text").Unique("id").ToSql()
_, _, err := bob.CreateTable("users").Columns("name").Types("text").Unique("id").ToSQL()
if err.Error() != "supplied unique column name doesn't exists on columns" {
t.Fatal("should throw an error, it didn't:", err.Error())
}
Expand Down
12 changes: 9 additions & 3 deletions has.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,34 @@ func init() {
builder.Register(HasBuilder{}, hasData{})
}

// HasTable checks for a table's existence by tableName, resolving with a boolean to signal if the table exists.
func (h HasBuilder) HasTable(table string) HasBuilder {
return builder.Set(h, "Name", table).(HasBuilder)
}

// HasColumn checks if a column exists in the current table, resolves the promise with a boolean, true if the column exists, false otherwise.
func (h HasBuilder) HasColumn(column string) HasBuilder {
return builder.Set(h, "Column", column).(HasBuilder)
}

// WithSchema specifies the schema to be used when using the schema-building commands.
func (h HasBuilder) WithSchema(schema string) HasBuilder {
return builder.Set(h, "Schema", schema).(HasBuilder)
}

// PlaceholderFormat changes the default placeholder (?) to desired placeholder.
func (h HasBuilder) PlaceholderFormat(f string) HasBuilder {
return builder.Set(h, "Placeholder", f).(HasBuilder)
}

func (h HasBuilder) ToSql() (string, []interface{}, error) {
// ToSQL returns 3 variables filled out with the correct values based on bindings, etc.
func (h HasBuilder) ToSQL() (string, []interface{}, error) {
data := builder.GetStruct(h).(hasData)
return data.ToSql()
return data.ToSQL()
}

func (d *hasData) ToSql() (sqlStr string, args []interface{}, err error) {
// ToSQL returns 3 variables filled out with the correct values based on bindings, etc.
func (d *hasData) ToSQL() (sqlStr string, args []interface{}, err error) {
sql := &bytes.Buffer{}
if d.Name == "" {
err = errors.New("has statement should have a table name")
Expand Down
59 changes: 57 additions & 2 deletions has_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

func TestHas(t *testing.T) {
t.Run("should be able to create a hasTable query", func(t *testing.T) {
sql, args, err := bob.HasTable("users").ToSql()
sql, args, err := bob.HasTable("users").ToSQL()
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -26,7 +26,7 @@ func TestHas(t *testing.T) {
})

t.Run("should be able to create a hasColumn query", func(t *testing.T) {
sql, args, err := bob.HasTable("users").HasColumn("name").ToSql()
sql, args, err := bob.HasTable("users").HasColumn("name").ToSQL()
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -40,4 +40,59 @@ func TestHas(t *testing.T) {
t.Fatal("args is not equal with argsResult:", args)
}
})

t.Run("should be able to create a hasColumn query (but reversed)", func(t *testing.T) {
sql, args, err := bob.HasColumn("name").HasTable("users").ToSQL()
if err != nil {
t.Fatal(err.Error())
}

result := "SELECT * FROM information_schema.columns WHERE table_name = ? AND column_name = ? AND table_schema = current_schema();"
if sql != result {
t.Fatal("sql is not equal with result:", sql)
}

if len(args) != 2 {
t.Fatal("args is not equal with argsResult:", args)
}
})

t.Run("should be able to create a hasTable query with schema", func(t *testing.T) {
sql, args, err := bob.HasTable("users").WithSchema("private").ToSQL()
if err != nil {
t.Fatal(err.Error())
}

result := "SELECT * FROM information_schema.tables WHERE table_name = ? AND table_schema = ?;"
if sql != result {
t.Fatal("sql is not equal with result:", sql)
}

if len(args) != 2 {
t.Fatal("args is not equal with argsResult:", args)
}
})

t.Run("should be able to have a different placeholder", func(t *testing.T) {
sql, args, err := bob.HasTable("users").HasColumn("name").PlaceholderFormat(bob.Dollar).ToSQL()
if err != nil {
t.Fatal(err.Error())
}

result := "SELECT * FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = current_schema();"
if sql != result {
t.Fatal("sql is not equal with result:", sql)
}

if len(args) != 2 {
t.Fatal("args is not equal with argsResult:", args)
}
})

t.Run("should expect an error for no table name", func(t *testing.T) {
_, _, err := bob.HasTable("").ToSQL()
if err.Error() != "has statement should have a table name" {
t.Fatal("error is different:", err.Error())
}
})
}

0 comments on commit 03e6bdb

Please sign in to comment.