Skip to content

Commit c5677b8

Browse files
committed
Experimental MySQL support
1 parent dd562c0 commit c5677b8

30 files changed

+132
-99
lines changed

column.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ func (col ColumnElem) Create(d dialect.Dialect) (string, error) {
7979
if err != nil {
8080
return "", err
8181
}
82-
return fmt.Sprintf(`"%s" %s`, col.Name(), compiled), nil
82+
return fmt.Sprintf(`%s %s`, col.Name(), compiled), nil
8383
}
8484

8585
// FullName prefixes the column name with the table name
8686
// It deos not include opreators (such as 'max')
8787
func (col ColumnElem) FullName() string {
88-
return fmt.Sprintf(`"%s"."%s"`, col.table.Name(), col.name)
88+
return fmt.Sprintf(`%s.%s`, col.table.Name(), col.name)
8989
}
9090

9191
// IsInvalid will return true when a column that does not exist was

columnset.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func (set ColumnSet) IsEmpty() bool {
9898
func (set ColumnSet) Names() []string {
9999
names := make([]string, len(set.order))
100100
for i, col := range set.order {
101-
names[i] = fmt.Sprintf(`%s`, col.FullName())
101+
names[i] = col.FullName()
102102
}
103103
return names
104104
}

create.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (stmt CreateStmt) Compile(d dialect.Dialect, p *Parameters) (string, error)
5959
}
6060

6161
return fmt.Sprintf(
62-
"%s \"%s\" (\n %s\n);",
62+
"%s %s (\n %s\n);",
6363
name,
6464
stmt.table.Name(),
6565
strings.Join(compiled, ",\n "),

create_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ func TestCreate(t *testing.T) {
88
expect := NewTester(t, &defaultDialect{})
99

1010
expect.SQL(
11-
`CREATE TABLE "users" (
12-
"id" INTEGER,
13-
"email" VARCHAR(256) NOT NULL,
14-
"name" VARCHAR(32) NOT NULL,
15-
"password" VARCHAR,
16-
"created_at" TIMESTAMP,
17-
PRIMARY KEY ("id"),
18-
UNIQUE ("email")
19-
);`,
2011
users.Create(),
12+
`CREATE TABLE users (
13+
id INTEGER,
14+
email VARCHAR(256) NOT NULL,
15+
name VARCHAR(32) NOT NULL,
16+
password VARCHAR,
17+
created_at TIMESTAMP,
18+
PRIMARY KEY (id),
19+
UNIQUE (email)
20+
);`,
2121
)
2222
}

delete.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func (stmt DeleteStmt) Compile(d dialect.Dialect, ps *Parameters) (string, error
2525
if err := stmt.Error(); err != nil {
2626
return "", err
2727
}
28-
compiled := fmt.Sprintf(`DELETE FROM "%s"`, stmt.table.Name())
28+
compiled := fmt.Sprintf(`DELETE FROM %s`, stmt.table.Name())
2929

3030
if stmt.where != nil {
3131
cc, err := stmt.where.Compile(d, ps)

delete_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ func TestDelete(t *testing.T) {
88
// Test a complete delete
99
// TODO Require an All when no clauses are given to prevent mass deletes?
1010
expect.SQL(
11-
`DELETE FROM "users"`,
1211
users.Delete(),
12+
`DELETE FROM users`,
1313
)
1414

1515
// Test a delete with a WHERE
1616
expect.SQL(
17-
`DELETE FROM "users" WHERE "users"."id" = $1`,
1817
users.Delete().Where(users.C("id").Equals(1)),
18+
`DELETE FROM users WHERE users.id = $1`,
1919
1,
2020
)
2121

2222
expect.SQL(
23-
`DELETE FROM "users" WHERE ("users"."id" = $1 AND "users"."name" = $2)`,
2423
Delete(users).Where(users.C("id").Equals(1), users.C("name").Equals("admin")),
24+
`DELETE FROM users WHERE (users.id = $1 AND users.name = $2)`,
2525
1, "admin",
2626
)
2727
}

foreignkey.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (fk FKElem) Create(d dialect.Dialect) (string, error) {
4242
return "", err
4343
}
4444
compiled := fmt.Sprintf(
45-
`"%s" %s REFERENCES %s("%s")`,
45+
`%s %s REFERENCES %s(%s)`,
4646
fk.name,
4747
ct,
4848
fk.col.Table().Name(),

foreignkey_test.go

+14-14
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@ func TestForeignKey(t *testing.T) {
66
expect := NewTester(t, &defaultDialect{})
77

88
expect.SQL(
9-
`CREATE TABLE "contacts" (
10-
"id" INTEGER,
11-
"user_id" INTEGER REFERENCES users("id"),
12-
"key" VARCHAR,
13-
"value" VARCHAR,
14-
PRIMARY KEY ("id"),
15-
UNIQUE ("user_id", "key")
16-
);`,
179
contacts.Create(),
10+
`CREATE TABLE contacts (
11+
id INTEGER,
12+
user_id INTEGER REFERENCES users(id),
13+
key VARCHAR,
14+
value VARCHAR,
15+
PRIMARY KEY (id),
16+
UNIQUE (user_id, key)
17+
);`,
1818
)
1919

2020
expect.SQL(
21-
`CREATE TABLE "messages" (
22-
"id" INTEGER,
23-
"user_id" INTEGER REFERENCES users("id"),
24-
"parent_id" INTEGER REFERENCES messages("id"),
25-
"text" TEXT
26-
);`,
2721
messages.Create(),
22+
`CREATE TABLE messages (
23+
id INTEGER,
24+
user_id INTEGER REFERENCES users(id),
25+
parent_id INTEGER REFERENCES messages(id),
26+
text TEXT
27+
);`,
2828
)
2929

3030
if len(messages.ForeignKeys()) != 2 {

function.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,33 @@ func Function(name string, col Columnar) ColumnElem {
55
}
66

77
func Avg(expression Columnar) ColumnElem {
8-
return Function("avg", expression)
8+
return Function("AVG", expression)
99
}
1010

1111
func Count(expression Columnar) ColumnElem {
12-
return Function("count", expression)
12+
return Function("COUNT", expression)
1313
}
1414

1515
func Date(expression Columnar) ColumnElem {
16-
return Function("date", expression)
16+
return Function("DATE", expression)
1717
}
1818

1919
func Max(expression Columnar) ColumnElem {
20-
return Function("max", expression)
20+
return Function("MAX", expression)
2121
}
2222

2323
func Min(expression Columnar) ColumnElem {
24-
return Function("min", expression)
24+
return Function("MIN", expression)
2525
}
2626

2727
func StdDev(expression Columnar) ColumnElem {
28-
return Function("stddev", expression)
28+
return Function("STDDEV", expression)
2929
}
3030

3131
func Sum(expression Columnar) ColumnElem {
32-
return Function("sum", expression)
32+
return Function("SUM", expression)
3333
}
3434

3535
func Variance(expression Columnar) ColumnElem {
36-
return Function("variance", expression)
36+
return Function("VARIANCE", expression)
3737
}

function_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ func TestFunctions(t *testing.T) {
66
expect := NewTester(t, &defaultDialect{})
77

88
expect.SQL(
9-
`SELECT count("users"."id") FROM "users"`,
109
Select(Count(users.C("id"))),
10+
`SELECT COUNT(users.id) FROM users`,
1111
)
1212

1313
expect.SQL(
14-
`SELECT count("users"."id") AS "Count" FROM "users"`,
1514
Select(Count(users.C("id")).As("Count")),
15+
`SELECT COUNT(users.id) AS "Count" FROM users`,
1616
)
1717
}

insert.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (stmt InsertStmt) Compile(d dialect.Dialect, ps *Parameters) (string, error
5454

5555
columns := make([]string, len(stmt.columns))
5656
for i, column := range stmt.columns {
57-
columns[i] = fmt.Sprintf(`"%s"`, column.Name())
57+
columns[i] = column.Name()
5858
}
5959

6060
// args must be divisable by cols without remainder
@@ -95,7 +95,7 @@ func (stmt InsertStmt) Compile(d dialect.Dialect, ps *Parameters) (string, error
9595

9696
// TODO Bulk insert syntax is dialect specific
9797
return fmt.Sprintf(
98-
`INSERT INTO "%s" (%s) VALUES %s`,
98+
`INSERT INTO %s (%s) VALUES %s`,
9999
stmt.table.Name(),
100100
strings.Join(columns, ", "),
101101
strings.Join(parameters, ", "),

insert_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,27 @@ func TestInsert(t *testing.T) {
1111

1212
// By default, an INSERT without values will assume a single entry
1313
expect.SQL(
14-
`INSERT INTO "contacts" ("id", "user_id", "key", "value") VALUES ($1, $2, $3, $4)`,
1514
contacts.Insert(),
15+
`INSERT INTO contacts (id, user_id, key, value) VALUES ($1, $2, $3, $4)`,
1616
nil, nil, nil, nil,
1717
)
1818

1919
expect.SQL(
20-
`INSERT INTO "users" ("name", "password") VALUES ($1, $2)`,
2120
Insert(users.C("name"), users.C("password")),
21+
`INSERT INTO users (name, password) VALUES ($1, $2)`,
2222
nil, nil,
2323
)
2424

2525
expect.SQL(
26-
`INSERT INTO "users" ("email", "name") VALUES ($1, $2)`,
2726
users.Insert().Values(user{Name: "admin", Email: "[email protected]"}),
27+
`INSERT INTO users (email, name) VALUES ($1, $2)`,
2828
"[email protected]", "admin",
2929
)
3030

3131
// Use sql.Values
3232
expect.SQL(
33-
`INSERT INTO "users" ("id", "name") VALUES ($1, $2)`,
3433
users.Insert().Values(Values{"id": 1, "name": "user"}),
34+
`INSERT INTO users (id, name) VALUES ($1, $2)`,
3535
1, "user",
3636
)
3737
}

join.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ func (j JoinClause) String() string {
2323
func (j JoinClause) Compile(d dialect.Dialect, ps *Parameters) (string, error) {
2424
// Ignore clauses if CROSS
2525
if j.method == CROSSJOIN {
26-
return fmt.Sprintf(`%s "%s"`, CROSSJOIN, j.table.Name()), nil
26+
return fmt.Sprintf(`%s %s`, CROSSJOIN, j.table.Name()), nil
2727
}
2828

2929
// If no clauses were given, assume the join is NATURAL
3030
if len(j.ArrayClause.clauses) == 0 {
3131
return fmt.Sprintf(
32-
`NATURAL %s "%s"`, j.method, j.table.Name(),
32+
`NATURAL %s %s`, j.method, j.table.Name(),
3333
), nil
3434
}
3535

@@ -41,6 +41,6 @@ func (j JoinClause) Compile(d dialect.Dialect, ps *Parameters) (string, error) {
4141
}
4242

4343
return fmt.Sprintf(
44-
`%s "%s" ON %s`, j.method, j.table.Name(), clauses,
44+
`%s %s ON %s`, j.method, j.table.Name(), clauses,
4545
), nil
4646
}

join_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,16 @@ func TestJoinClause(t *testing.T) {
2626
expect := NewTester(t, &defaultDialect{})
2727

2828
expect.SQL(
29-
`SELECT "a"."id", "a"."value" FROM "a" CROSS JOIN "relations"`,
3029
Select(tableA).CrossJoin(relations),
30+
`SELECT a.id, a.value FROM a CROSS JOIN relations`,
3131
)
3232

3333
expect.SQL(
34-
`SELECT "a"."id", "a"."value" FROM "a" NATURAL INNER JOIN "relations"`,
3534
Select(tableA).InnerJoin(relations),
35+
`SELECT a.id, a.value FROM a NATURAL INNER JOIN relations`,
3636
)
3737

3838
expect.SQL(
39-
`SELECT "a"."id", "a"."value" FROM "a" LEFT OUTER JOIN "relations" ON "a"."id" = "relations"."a_id" AND "a"."id" = $1 LEFT OUTER JOIN "b" ON "b"."id" = "relations"."b_id"`,
4039
Select(tableA).LeftOuterJoin(
4140
relations,
4241
tableA.C("id").Equals(relations.C("a_id")),
@@ -45,6 +44,7 @@ func TestJoinClause(t *testing.T) {
4544
tableB,
4645
tableB.C("id").Equals(relations.C("b_id")),
4746
),
47+
`SELECT a.id, a.value FROM a LEFT OUTER JOIN relations ON a.id = relations.a_id AND a.id = $1 LEFT OUTER JOIN b ON b.id = relations.b_id`,
4848
2,
4949
)
5050

mysql/mysql.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package mysql
2+
3+
import (
4+
_ "github.com/go-sql-driver/mysql"
5+
6+
"github.com/aodin/sol/dialect"
7+
)
8+
9+
// MySQL implements the Dialect interface for MySQL databases.
10+
type MySQL struct{}
11+
12+
// The MySQL dialect must implement the dialect.Dialect interface
13+
var _ dialect.Dialect = &MySQL{}
14+
15+
// Param returns the MySQL specific parameterization scheme.
16+
func (d *MySQL) Param(i int) string {
17+
return `?`
18+
}
19+
20+
// Dialect is a constructor for the MySQL Dialect
21+
func Dialect() *MySQL {
22+
return &MySQL{}
23+
}
24+
25+
// Add the MySQL dialect to the dialect registry
26+
func init() {
27+
dialect.Register("mysql", Dialect())
28+
}

order_test.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,22 @@ func TestOrder(t *testing.T) {
77

88
// Asc is implied
99
ord := OrderedColumn{inner: users.C("id")}
10-
expect.SQL(`"users"."id"`, ord)
10+
expect.SQL(ord, `users.id`)
1111

1212
// Desc
13-
expect.SQL(`"users"."id" DESC`, ord.Desc())
13+
expect.SQL(ord.Desc(), `users.id DESC`)
1414

1515
// Desc, nulls first
1616
expect.SQL(
17-
`"users"."id" DESC NULLS FIRST`,
1817
ord.Desc().NullsFirst(),
18+
`users.id DESC NULLS FIRST`,
1919
)
2020

2121
// Asc, Nulls last
22-
expect.SQL(`"users"."id" NULLS LAST`, ord.Asc().NullsLast())
22+
expect.SQL(
23+
ord.Asc().NullsLast(),
24+
`users.id NULLS LAST`,
25+
)
2326

2427
// Calling Orderable on an OrderableColumn should return a copy of itself
2528
if ord.inner.Name() != ord.Orderable().inner.Name() {

postgres/column_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ func TestColumn(t *testing.T) {
1010
expect := sol.NewTester(t, Dialect())
1111

1212
expect.SQL(
13-
`SELECT "meetings"."uuid", "meetings"."time" FROM "meetings" WHERE "meetings"."time" @> $1`,
1413
meetings.Select().Where(meetings.C("time").Contains("today")),
14+
`SELECT meetings.uuid, meetings.time FROM meetings WHERE meetings.time @> $1`,
1515
"today",
1616
)
1717
}

0 commit comments

Comments
 (0)