From 1268d4b2efa11a6f614c9dc7b6e56ac75ae0d179 Mon Sep 17 00:00:00 2001 From: lqs Date: Sun, 18 Nov 2018 22:11:43 +0800 Subject: [PATCH] initial commit --- LICENSE | 21 ++++ README.md | 58 ++++++++++ alias.go | 14 +++ common.go | 148 ++++++++++++++++++++++++ cursor.go | 81 +++++++++++++ database.go | 62 ++++++++++ delete.go | 52 +++++++++ expression.go | 272 ++++++++++++++++++++++++++++++++++++++++++++ field.go | 37 ++++++ generator.go | 213 ++++++++++++++++++++++++++++++++++ insert.go | 147 ++++++++++++++++++++++++ logo.png | Bin 0 -> 101348 bytes order.go | 18 +++ select.go | 250 ++++++++++++++++++++++++++++++++++++++++ sqlingo-gen/main.go | 26 +++++ table.go | 29 +++++ update.go | 80 +++++++++++++ 17 files changed, 1508 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 alias.go create mode 100644 common.go create mode 100644 cursor.go create mode 100644 database.go create mode 100644 delete.go create mode 100644 expression.go create mode 100644 field.go create mode 100644 generator.go create mode 100644 insert.go create mode 100644 logo.png create mode 100644 order.go create mode 100644 select.go create mode 100644 sqlingo-gen/main.go create mode 100644 table.go create mode 100644 update.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e5a74e6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Liu Qishuai + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5902b5f --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ + + +**sqlingo** is a SQL DSL & ORM library in Go. It generates code from your database and lets you write SQL queries easily. + +WARNING: sqlingo is still under development. It's expected to be released by end of November 2018. + +## Tutorial + +### Prepare your database +In order to generate code, sqlingo requires your tables are already created in the database. + +### Install sqlingo code generator +``` +$ go get -u github.com/lqs/sqlingo/sqlingo-gen +``` + +### Generate code for your database +``` +$ mkdir -p generated/sqlingo +$ sqlingo-gen root:123456@/database_name >generated/sqlingo/database_name.dsl.go +``` + +### Start using sqlingo +Create `main.go` to use the generated code +``` +import ( + "github.com/lqs/sqlingo" + "./generated/sqlingo" +) + +func main() { + db, err := sqlingo.Open("mysql", "root:123456@/database_name") + if err != nil { + panic(err) + } + + # insert some rows + customer1 := &CustomerModel{name: "Customer One"} + customer2 := &CustomerModel{name: "Customer Two"} + db.InsertInto(Customer). + Values(customer1, customer2). + Execute() + + # do some queries + var customers []*CustomerModel + db.SelectFrom(Customer). + Where(Customer.Id.In(1, 2)). + Fetch(&customers) + + # more examples + var customerId int64 + var orderId int64 + db.Select(Customer.Id, Order.Id). + From(Customer, Order). + Where(Customer.Id.Equals(Order.CustomerId), Order.Id.Equals(1)). + Fetch(&customerId, &orderId) +} +``` \ No newline at end of file diff --git a/alias.go b/alias.go new file mode 100644 index 0000000..d1335d9 --- /dev/null +++ b/alias.go @@ -0,0 +1,14 @@ +package sqlingo + +type Alias interface { + GetSQL() string +} + +type alias struct { + expression Expression + name string +} + +func (a *alias) GetSQL() string { + return a.expression.GetSQL() + " AS " + getSQLForName(a.name) +} diff --git a/common.go b/common.go new file mode 100644 index 0000000..ed81997 --- /dev/null +++ b/common.go @@ -0,0 +1,148 @@ +package sqlingo + +import ( + "fmt" + "runtime" + "strings" +) + +type Model interface { + GetTable() Table + GetValues() []interface{} +} + +type Assignment interface { + GetSQL() string +} + +type assignment struct { + Assignment + field Field + value interface{} +} + +func (a *assignment) GetSQL() string { + value, _ := getSQLFromWhatever(a.value) + return a.field.GetSQL() + " = " + value +} + +func Raw(sql string) UnknownExpression { + return &expression{sql: sql, priority: 99} +} + +func And(expressions ...BooleanExpression) (result BooleanExpression) { + if len(expressions) == 0 { + result = &expression{sql: "TRUE"} + return + } + for i, condition := range expressions { + if i == 0 { + result = condition + } else { + result = result.And(condition) + } + } + return +} + +func Or(expressions ...BooleanExpression) (result BooleanExpression) { + if len(expressions) == 0 { + result = &expression{sql: "FALSE"} + return + } + for i, condition := range expressions { + if i == 0 { + result = condition + } else { + result = result.Or(condition) + } + } + return +} + +func Function(name string, args ...Expression) Expression { + return &expression{sql: name + "(" + commaExpressions(args) + ")"} +} + +func If(predicate Expression, trueValue Expression, falseValue Expression) (result Expression) { + return Function("IF", predicate, trueValue, falseValue) +} + +func commaFields(fields []Field) string { + sql := "" + for i, item := range fields { + if i > 0 { + sql += ", " + } + sql += item.GetSQL() + } + return sql +} + +func commaExpressions(expressions []Expression) string { + sql := "" + for i, item := range expressions { + if i > 0 { + sql += ", " + } + sql += item.GetSQL() + } + return sql +} + +func commaValues(values []interface{}) string { + sql := "" + for i, item := range values { + if i > 0 { + sql += ", " + } + value, _ := getSQLFromWhatever(item) + sql += value + } + return sql +} + +func commaAssignments(assignments []assignment) string { + sql := "" + for i, item := range assignments { + if i > 0 { + sql += ", " + } + sql += item.GetSQL() + } + return sql +} + +func commaOrderBys(orderBys []OrderBy) string { + sql := "" + for i, item := range orderBys { + if i > 0 { + sql += ", " + } + sql += item.GetSQL() + } + return sql +} + +func getSQLForName(name string) string { + // TODO: check reserved words + return "`" + name + "`" +} + +func getCallerInfo() string { + for i := 0; true; i++ { + _, file, line, ok := runtime.Caller(i) + if !ok { + break + } + segs := strings.Split(file, "/") + name := segs[len(segs)-1] + switch name { + case "common.go", "select.go", "insert.go", "update.go", "delete.go": + continue + default: + return fmt.Sprintf("/* %s:%d */ ", name, line) + } + } + return "" +} diff --git a/cursor.go b/cursor.go new file mode 100644 index 0000000..7f1e701 --- /dev/null +++ b/cursor.go @@ -0,0 +1,81 @@ +package sqlingo + +import ( + "database/sql" + "fmt" + "reflect" +) + +type Cursor interface { + Next() bool + Scan(dest ...interface{}) error + Close() error +} + +type cursor struct { + rows *sql.Rows +} + +func (c *cursor) Next() bool { + return c.rows.Next() +} + +func preparePointers(val reflect.Value, scans *[]interface{}) error { + kind := val.Kind() + switch kind { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64, + reflect.String: + *scans = append(*scans, val.Addr().Interface()) + case reflect.Slice: + case reflect.Struct: + for j := 0; j < val.NumField(); j++ { + field := val.Field(j) + if field.Kind() == reflect.Interface { + continue + } + *scans = append(*scans, field.Addr().Interface()) + } + case reflect.Ptr: + toType := val.Type().Elem() + switch toType.Kind() { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64, + reflect.String: + *scans = append(*scans, val.Addr().Interface()) + default: + to := reflect.New(toType).Elem() + val.Set(to.Addr()) + preparePointers(to, scans) + } + default: + println("unknown type %s", kind.String()) + return fmt.Errorf("unknown type %s", kind.String()) + } + return nil +} + +func (c *cursor) Scan(dest ...interface{}) error { + + var scans []interface{} + for i, item := range dest { + if reflect.ValueOf(item).Kind() != reflect.Ptr { + return fmt.Errorf("argument %d is not pointer", i) + } + + val := reflect.Indirect(reflect.ValueOf(item)) + + preparePointers(val, &scans) + } + + err := c.rows.Scan(scans...) + return err +} + +func (c *cursor) Close() error { + return c.rows.Close() +} diff --git a/database.go b/database.go new file mode 100644 index 0000000..4216de3 --- /dev/null +++ b/database.go @@ -0,0 +1,62 @@ +package sqlingo + +import ( + "database/sql" + "golang.org/x/text/language" + "golang.org/x/text/message" + "time" +) + +type Database struct { + db *sql.DB + debugMode bool + dialect string +} + +func (d *Database) SetDebugMode(debugMode bool) { + d.debugMode = debugMode +} + +func Open(driverName string, dataSourceName string) (db *Database, err error) { + var sqlDB *sql.DB + if dataSourceName != "" { + sqlDB, err = sql.Open(driverName, dataSourceName) + if err != nil { + return + } + } + db = &Database{ + dialect: driverName, + db: sqlDB, + } + return +} + +func (d *Database) GetDB() *sql.DB { + return d.db +} + +func (d *Database) Query(sql string) (Cursor, error) { + startTime := time.Now().UnixNano() + rows, err := d.db.Query(sql) + endTime := time.Now().UnixNano() + printLog(endTime-startTime, sql) + if err != nil { + return nil, err + } + return &cursor{rows: rows}, nil +} + +func (d *Database) Execute(sql string) (sql.Result, error) { + startTime := time.Now().UnixNano() + result, err := d.db.Exec(sql) + endTime := time.Now().UnixNano() + printLog(endTime-startTime, sql) + return result, err +} + +var printer = message.NewPrinter(language.English) + +func printLog(duration int64, sql string) { + printer.Printf("[%9d µs] %s\n", duration/1000, sql) +} diff --git a/delete.go b/delete.go new file mode 100644 index 0000000..733e9e1 --- /dev/null +++ b/delete.go @@ -0,0 +1,52 @@ +package sqlingo + +import ( + "database/sql" +) + +type DeleteWithTable interface { + Where(conditions ...BooleanExpression) DeleteWithWhere +} + +type DeleteWithWhere interface { + GetSQL() (string, error) + Execute() (result sql.Result, err error) +} + +type deleteStatus struct { + database *Database + table *Table + where *BooleanExpression +} + +func (s *deleteStatus) copy() *deleteStatus { + delete_ := *s + return &delete_ +} + +func (d *Database) DeleteFrom(table Table) DeleteWithTable { + return &deleteStatus{database: d, table: &table} +} + +func (s *deleteStatus) Where(conditions ...BooleanExpression) DeleteWithWhere { + delete_ := s.copy() + condition := And(conditions...) + delete_.where = &condition + return delete_ +} + +func (s *deleteStatus) GetSQL() (string, error) { + sqlString := getCallerInfo() + "DELETE FROM " + (*s.table).GetSQL() + " WHERE " + (*s.where).GetSQL() + + + + return sqlString, nil +} + +func (s *deleteStatus) Execute() (sql.Result, error) { + sqlString, err := s.GetSQL() + if err != nil { + return nil, err + } + return s.database.Execute(sqlString) +} diff --git a/expression.go b/expression.go new file mode 100644 index 0000000..8fac0b3 --- /dev/null +++ b/expression.go @@ -0,0 +1,272 @@ +package sqlingo + +import ( + "reflect" + "strconv" + "strings" +) + +type Expression interface { + GetSQL() string + getOperatorPriority() int + + NotEquals(other interface{}) BooleanExpression + Equals(other interface{}) BooleanExpression + LessThan(other interface{}) BooleanExpression + LessThanOrEquals(other interface{}) BooleanExpression + GreaterThan(other interface{}) BooleanExpression + GreaterThanOrEquals(other interface{}) BooleanExpression + + IsNull() BooleanExpression + IsNotNull() BooleanExpression + In(values ...interface{}) BooleanExpression + Between(min interface{}, max interface{}) BooleanExpression + Desc() OrderBy + + As(alias string) Alias +} + +type BooleanExpression interface { + Expression + And(other interface{}) BooleanExpression + Or(other interface{}) BooleanExpression + Not() BooleanExpression +} + +type NumberExpression interface { + Expression + Add(other interface{}) NumberExpression + Sub(other interface{}) NumberExpression + Mul(other interface{}) NumberExpression + Div(other interface{}) NumberExpression + IntDiv(other interface{}) NumberExpression + Mod(other interface{}) NumberExpression + + Sum() NumberExpression +} + +type StringExpression interface { + Expression +} + +type UnknownExpression interface { + Expression + And(other interface{}) BooleanExpression + Or(other interface{}) BooleanExpression + Not() BooleanExpression + Add(other interface{}) NumberExpression + Sub(other interface{}) NumberExpression + Mul(other interface{}) NumberExpression + Div(other interface{}) NumberExpression + IntDiv(other interface{}) NumberExpression + Mod(other interface{}) NumberExpression + + Sum() NumberExpression +} + +type expression struct { + sql string + priority int +} + +func (e *expression) As(name string) Alias { + return &alias{expression: e, name: name} +} + +func (e *expression) GetSQL() string { + return e.sql +} + +func getSQLFromWhatever(value interface{}) (sql string, priority int) { + switch value.(type) { + case Expression: + return value.(Expression).GetSQL(), value.(Expression).getOperatorPriority() + case Assignment: + return value.(Assignment).GetSQL(), 0 + case int, int8, int16, int32, int64: + return strconv.FormatInt(reflect.ValueOf(value).Int(), 10), 0 + case uint, uint8, uint16, uint32, uint64: + return strconv.FormatUint(reflect.ValueOf(value).Uint(), 10), 0 + case string: + return "\"" + strings.Replace(value.(string), "\"", "\\\"", -1) + "\"", 0 + case []interface{}: + return "(" + commaValues(value.([]interface{})) + ")", 0 + default: + if value == nil { + return "NULL", 0 + } + v := reflect.ValueOf(value) + for v.Kind() == reflect.Ptr { + if v.IsNil() { + return "NULL", 0 + } + return getSQLFromWhatever(reflect.Indirect(v).Interface()) + } + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return getSQLFromWhatever(v.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return getSQLFromWhatever(v.Uint()) + default: + return "[invalid type " + v.Kind().String() + "]", 99 + } + } +} + +/* +1 INTERVAL +2 BINARY, COLLATE +3 ! +4 - (unary minus), ~ (unary bit inversion) +5 ^ +6 *, /, DIV, %, MOD +7 -, + +8 <<, >> +9 & +10 | +11 = (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN +12 BETWEEN, CASE, WHEN, THEN, ELSE +13 NOT +14 AND, && +15 XOR +16 OR, || +17 = (assignment), := + */ +func (e *expression) NotEquals(other interface{}) BooleanExpression { + return e.binaryOperation("<>", other, 11) +} + +func (e *expression) Equals(other interface{}) BooleanExpression { + return e.binaryOperation("=", other, 11) +} + +func (e *expression) LessThan(other interface{}) BooleanExpression { + return e.binaryOperation("<", other, 11) +} + +func (e *expression) LessThanOrEquals(other interface{}) BooleanExpression { + return e.binaryOperation("<=", other, 11) +} + +func (e *expression) GreaterThan(other interface{}) BooleanExpression { + return e.binaryOperation(">", other, 11) +} + +func (e *expression) GreaterThanOrEquals(other interface{}) BooleanExpression { + return e.binaryOperation(">=", other, 11) +} + +func (e *expression) And(other interface{}) BooleanExpression { + return e.binaryOperation("AND", other, 14) +} + +func (e *expression) Or(other interface{}) BooleanExpression { + return e.binaryOperation("OR", other, 16) +} + +func (e *expression) Add(other interface{}) NumberExpression { + return e.binaryOperation("+", other, 7) +} + +func (e *expression) Sub(other interface{}) NumberExpression { + return e.binaryOperation("-", other, 7) +} + +func (e *expression) Mul(other interface{}) NumberExpression { + return e.binaryOperation("*", other, 6) +} + +func (e *expression) Div(other interface{}) NumberExpression { + return e.binaryOperation("/", other, 6) +} + +func (e *expression) IntDiv(other interface{}) NumberExpression { + return e.binaryOperation("DIV", other, 6) +} + +func (e *expression) Mod(other interface{}) NumberExpression { + return e.binaryOperation("%", other, 6) +} + +func (e *expression) Sum() NumberExpression { + return e.function("SUM") +} + +func (e *expression) binaryOperation(operator string, value interface{}, priority int) *expression { + left := e.GetSQL() + leftLevel := e.priority + right, rightLevel := getSQLFromWhatever(value) + if leftLevel > priority { + left = "(" + left + ")" + } + if rightLevel >= priority { + right = "(" + right + ")" + } + return &expression{ + sql: left + " " + operator + " " + right, + priority: priority, + } +} + +func (e *expression) function(name string) *expression { + return &expression{sql: name + "(" + e.GetSQL() + ")", priority: 0} +} + +func (e *expression) IsNull() BooleanExpression { + return &expression{sql: e.GetSQL() + " IS NULL", priority: 11} +} + +func (e *expression) Not() BooleanExpression { + return &expression{sql: "NOT " + e.GetSQL(), priority: 13} +} + +func (e *expression) IsNotNull() BooleanExpression { + return &expression{sql: e.GetSQL() + " IS NOT NULL", priority: 11} +} + +func (e *expression) In(values ...interface{}) BooleanExpression { + if len(values) == 1 { + firstValue := values[0] + valueOfFirstValue := reflect.ValueOf(firstValue) + if valueOfFirstValue.Kind() == reflect.Slice { + length := valueOfFirstValue.Len() + values = make([]interface{}, length) + for i := 0; i < length; i++ { + value := valueOfFirstValue.Index(i) + values[i] = value.Interface() + } + } + } + if len(values) == 0 { + return &expression{sql: "FALSE", priority: 0} + } + + sql := e.GetSQL() + " IN (" + for i, value := range values { + if i > 0 { + sql += ", " + } + valueSql, _ := getSQLFromWhatever(value) + sql += valueSql + } + sql += ")" + return &expression{sql: sql, priority: 11} +} + +func (e *expression) Between(min interface{}, max interface{}) BooleanExpression { + minSql, _ := getSQLFromWhatever(min) + maxSql, _ := getSQLFromWhatever(max) + sql := e.GetSQL() + " BETWEEN " + minSql + " AND " + maxSql + return &expression{sql: sql, priority: 12} +} + +func (e *expression) getOperatorPriority() int { + return e.priority +} + +func (e *expression) Desc() OrderBy { + return &orderBy{by: e, desc: true} +} + +func NewExpression(sql string, priority int) { +} diff --git a/field.go b/field.go new file mode 100644 index 0000000..90658f7 --- /dev/null +++ b/field.go @@ -0,0 +1,37 @@ +package sqlingo + +type Field interface { + Expression +} + +type NumberField interface { + NumberExpression +} + +type BooleanField interface { + BooleanExpression +} + +type StringField interface { + StringExpression +} + +func newFieldExpression(tableName string, fieldName string) *expression { + sql := getSQLForName(fieldName) + if tableName != "" { + sql = getSQLForName(tableName) + "." + sql + } + return &expression{sql: sql, priority: 0} +} + +func NewNumberField(tableName string, fieldName string) NumberField { + return newFieldExpression(tableName, fieldName) +} + +func NewBooleanField(tableName string, fieldName string) BooleanField { + return newFieldExpression(tableName, fieldName) +} + +func NewStringField(tableName string, fieldName string) StringField { + return newFieldExpression(tableName, fieldName) +} diff --git a/generator.go b/generator.go new file mode 100644 index 0000000..89d85c6 --- /dev/null +++ b/generator.go @@ -0,0 +1,213 @@ +package sqlingo + +import ( + "database/sql" + "errors" + "go/format" + "regexp" + "strconv" + "unicode" +) + +func convertCase(s string) (result string) { + nextCharShouldBeUpperCase := true + for _, ch := range s { + if ch == '_' { + nextCharShouldBeUpperCase = true + } else { + if nextCharShouldBeUpperCase { + result += string(unicode.ToUpper(ch)) + nextCharShouldBeUpperCase = false + } else { + result += string(ch) + } + } + } + return +} + +func getType(s string, nullable bool) (goType string, fieldClass string, err error) { + r, _ := regexp.Compile("([a-z]+)(\\(([0-9]+)\\))?") + + submatches := r.FindStringSubmatch(s) + fieldType := submatches[1] + fieldSize := 0 + if submatches[3] != "" { + fieldSize, err = strconv.Atoi(submatches[3]) + if err != nil { + return + } + } + switch fieldType { + case "tinyint": + goType = "int8" + fieldClass = "NumberField" + case "smallint": + goType = "int16" + fieldClass = "NumberField" + case "int": + goType = "int32" + fieldClass = "NumberField" + case "bigint": + goType = "int64" + fieldClass = "NumberField" + case "float", "double": + goType = "float64" + fieldClass = "NumberField" + case "char", "varchar", "text", "mediumtext", "longtext", "enum", "datetime": + goType = "string" + fieldClass = "StringField" + case "blob": + goType = "[]byte" + fieldClass = "StringField" + case "bit": + if fieldSize == 1 { + goType = "bool" + fieldClass = "BooleanField" + } else { + goType = "string" + fieldClass = "StringField" + } + } + if nullable { + goType = "*" + goType + } + return +} + +func wrapQuote(s string) string { + return "\"" + s + "\"" +} + +func Generate(driverName string, dataSourceName string, tableNames *[]string) (string, error) { + + mysql, err := sql.Open(driverName, dataSourceName) + if err != nil { + return "", err + } + + rows, err := mysql.Query("SELECT DATABASE()") + if err != nil { + return "", err + } + var dbName *string + if rows.Next() { + err := rows.Scan(&dbName) + if err != nil { + return "", err + } + } + + if dbName == nil { + return "", errors.New("no database selected") + } + + code := "package " + *dbName + "_dsl\n" + code += "import . \"github.com/lqs/sqlingo\"\n" + + if tableNames == nil { + tableNames = &[]string{} + rows, err := mysql.Query("SHOW TABLES") + if err != nil { + return "", err + } + for rows.Next() { + var name string + rows.Scan(&name) + *tableNames = append(*tableNames, name) + } + } + + for _, tableName := range *tableNames { + rows, err := mysql.Query("SHOW FULL COLUMNS FROM " + getSQLForName(tableName)) + if err != nil { + return "", err + } + + tableLines := "" + modelLines := "" + objectLines := "\tTable: NewTable(\"" + tableName + "\"),\n" + classLines := "" + + className := convertCase(tableName) + tableStructName := "t" + className + + modelClassName := className + "Model" + + fields := "" + values := "" + + for rows.Next() { + columns, err := rows.Columns() + if err != nil { + return "", err + } + var pointers []interface{} + for i := 0; i < len(columns); i++ { + var value *string + pointers = append(pointers, &value) + } + err = rows.Scan(pointers...) + if err != nil { + return "", err + } + row := make(map[string]string) + for i, column := range columns { + pointer := *pointers[i].(**string) + if pointer != nil { + row[column] = *pointer + } + } + + goName := convertCase(row["Field"]) + goType, fieldClass, _ := getType(row["Type"], row["Null"] == "YES") + + fieldStructName := "f" + className + goName + + tableLines += "\t" + goName + " *" + fieldStructName + "\n" + modelLines += "\t" + goName + " " + goType + "\n" + objectLines += "\t" + goName + ": &" + fieldStructName + "{" + objectLines += "New" + fieldClass + "(" + wrapQuote(tableName) + ", " + wrapQuote(row["Field"]) + ")},\n" + classLines += "type " + fieldStructName + " struct{ " + fieldClass + " }\n" + + fields += "t." + goName + ", " + values += "m." + goName + ", " + } + + //println(tableLines, recordLines, objectLines, classLines) + + code += "type " + tableStructName + " struct {\n\tTable\n" + code += tableLines + code += "}\n\n" + + code += classLines + + code += "var " + className + " = &" + tableStructName + "{\n" + code += objectLines + code += "}\n\n" + + code += "func (t t" + className + ") GetFields() []Field {\n" + code += "\treturn []Field{" + fields + "}\n" + code += "}\n\n" + + code += "type " + modelClassName + " struct {\n" + //code += "\tModel\n" + code += modelLines + code += "}\n\n" + + code += "func (m " + modelClassName + ") GetTable() Table {\n" + code += "\treturn " + className + "\n" + code += "}\n\n" + + code += "func (m " + modelClassName + ") GetValues() []interface{} {\n" + code += "\treturn []interface{}{" + values + "}\n" + code += "}\n\n" + } + + codeOut, err := format.Source([]byte(code)) + if err != nil { + return "", err + } + + return string(codeOut), nil +} diff --git a/insert.go b/insert.go new file mode 100644 index 0000000..739bd27 --- /dev/null +++ b/insert.go @@ -0,0 +1,147 @@ +package sqlingo + +import ( + "database/sql" + "reflect" +) + +type insertStatus struct { + database *Database + table *Table + fields []Field + values []interface{} + models []Model + onDuplicateKeyUpdateAssignments []assignment +} + +func (s *insertStatus) copy() *insertStatus { + insert := *s + s.fields = append([]Field{}, s.fields...) + s.values = append([]interface{}{}, s.values...) + s.onDuplicateKeyUpdateAssignments = append([]assignment{}, s.onDuplicateKeyUpdateAssignments...) + return &insert +} + +type InsertWithTable interface { + Fields(fields ... Field) InsertWithValues + Values(values ... interface{}) InsertWithValues + Models(models ... interface{}) InsertWithModels +} + +type InsertWithValues interface { + Values(values ... interface{}) InsertWithValues + OnDuplicateKeyUpdate() InsertWithOnDuplicateKeyUpdateBegin + Execute() (result sql.Result, err error) +} + +type InsertWithModels interface { + Models(models ... interface{}) InsertWithModels + OnDuplicateKeyUpdate() InsertWithOnDuplicateKeyUpdateBegin + GetSQL() (string, error) + Execute() (result sql.Result, err error) +} + +type InsertWithOnDuplicateKeyUpdateBegin interface { + Set(Field Field, value interface{}) InsertWithOnDuplicateKeyUpdate +} + +type InsertWithOnDuplicateKeyUpdate interface { + Set(Field Field, value interface{}) InsertWithOnDuplicateKeyUpdate + GetSQL() (string, error) + Execute() (result sql.Result, err error) +} + +func (d *Database) InsertInto(table Table) InsertWithTable { + return &insertStatus{database: d, table: &table} +} + +func (s *insertStatus) Fields(fields ... Field) InsertWithValues { + insert := s.copy() + insert.fields = fields + return insert +} + +func (s *insertStatus) Values(values ... interface{}) InsertWithValues { + insert := s.copy() + insert.values = append(insert.values, values) + return insert +} + +func (s *insertStatus) addModel(model interface{}) { + m0, ok := model.(Model) + if ok { + s.models = append(s.models, m0) + return + } + + value := reflect.ValueOf(model) + if value.Kind() == reflect.Ptr { + value = reflect.Indirect(value) + s.addModel(value.Interface()) + } + if value.Kind() == reflect.Slice { + for i := 0; i < value.Len(); i++ { + elem := value.Index(i) + addr := elem.Addr() + inter := addr.Interface() + s.addModel(inter) + } + return + } +} + +func (s *insertStatus) Models(models ... interface{}) InsertWithModels { + if len(models) == 0 { + return s + } + + insert := s.copy() + for _, model := range models { + insert.addModel(&model) + } + return insert +} + +func (s *insertStatus) OnDuplicateKeyUpdate() InsertWithOnDuplicateKeyUpdateBegin { + insert := s.copy() + return insert +} + +func (s *insertStatus) Set(field Field, value interface{}) InsertWithOnDuplicateKeyUpdate { + insert := s.copy() + insert.onDuplicateKeyUpdateAssignments = append(insert.onDuplicateKeyUpdateAssignments, assignment{ + field: field, + value: value, + }) + return insert +} + +func (s *insertStatus) GetSQL() (string, error) { + var fields []Field + var values []interface{} + if len(s.models) > 0 { + fields = s.models[0].GetTable().GetFields() + for _, model := range s.models { + values = append(values, model.GetValues()) + } + } else { + fields = s.fields + values = s.values + } + + sqlString := getCallerInfo() + "INSERT INTO " + (*s.table).GetSQL() + " (" + commaFields(fields) + ") VALUES " + commaValues(values) + if len(s.onDuplicateKeyUpdateAssignments) > 0 { + sqlString += " ON DUPLICATE KEY UPDATE " + commaAssignments(s.onDuplicateKeyUpdateAssignments) + } + + return sqlString, nil + +} + +func (s *insertStatus) Execute() (result sql.Result, err error) { + sqlString, err := s.GetSQL() + if err != nil { + return nil, err + } + return s.database.Execute(sqlString) +} diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..eed4c18c3102b4765361da60bc44f6d1059bb298 GIT binary patch literal 101348 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%0Afq(9-U)pSJ_vXElCpE| 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 0 { + var values []interface{} + for _, table := range s.tables { + values = append(values, table) + } + sql += " FROM " + commaValues(values) + } + + if s.where != nil { + sql += " WHERE " + (*s.where).GetSQL() + } + + if len(s.groupBys) != 0 { + sql += " GROUP BY " + commaExpressions(s.groupBys) + + if s.having != nil { + sql += " HAVING " + (*s.having).GetSQL() + } + } + + if len(s.orderBys) > 0 { + sql += " ORDER BY " + commaOrderBys(s.orderBys) + } + + if s.limit != nil { + sql += " LIMIT " + strconv.Itoa(*s.limit) + } + + if s.offset != nil { + sql += " OFFSET " + strconv.Itoa(*s.offset) + } + + sql += s.lock + + return sql +} + +func (s *selectStatus) FetchCursor() (Cursor, error) { + sqlString := s.GetSQL() + + cursor, err := s.database.Query(sqlString) + if err != nil { + return nil, err + } + return cursor, nil +} + +func (s *selectStatus) Fetch(dest ...interface{}) error { + if len(dest) == 1 { + if reflect.ValueOf(dest[0]).Kind() == reflect.Ptr { + val := reflect.Indirect(reflect.ValueOf(dest[0])) + if val.Kind() == reflect.Slice { + cursor, err := s.FetchCursor() + if err != nil { + return err + } + defer cursor.Close() + + for cursor.Next() { + if err != nil { + return err + } + elem := reflect.New(val.Type().Elem()) + row := elem.Interface() + cursor.Scan(row) + val.Set(reflect.Append(val, reflect.Indirect(elem))) + } + return nil + } + } + } + + cursor, err := s.FetchCursor() + if err != nil { + return err + } + defer cursor.Close() + + for cursor.Next() { + err = cursor.Scan(dest...) + if err != nil { + return err + } + break + } + + return nil +} diff --git a/sqlingo-gen/main.go b/sqlingo-gen/main.go new file mode 100644 index 0000000..abd734c --- /dev/null +++ b/sqlingo-gen/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + _ "github.com/go-sql-driver/mysql" + "github.com/lqs/sqlingo" + "os" +) + +func main() { + + if len(os.Args) != 2 { + fmt.Printf("Usage: %s username:password@/database\n", os.Args[0]) + return + } + + dataSourceName := os.Args[1] + + code, err := sqlingo.Generate("mysql", dataSourceName, nil) + if err != nil { + panic(err) + } + + fmt.Print(code) +} + diff --git a/table.go b/table.go new file mode 100644 index 0000000..1de8a0c --- /dev/null +++ b/table.go @@ -0,0 +1,29 @@ +package sqlingo + +type Table interface { + GetName() string + GetSQL() string + GetFields() []Field +} + +type table struct { + Table + name string + sql string +} + +func (t *table) GetName() string { + return t.name +} + +func (t *table) GetSQL() string { + return t.sql +} + +func (t *table) getOperatorPriority() int { + return 0 +} + +func NewTable(name string) Table { + return &table{name: name, sql: getSQLForName(name)} +} diff --git a/update.go b/update.go new file mode 100644 index 0000000..1973018 --- /dev/null +++ b/update.go @@ -0,0 +1,80 @@ +package sqlingo + +import ( + "database/sql" +) + +type updateStatus struct { + database *Database + table *Table + assignments []assignment + where *BooleanExpression +} + +func (s *updateStatus) copy() *updateStatus { + update := *s + update.assignments = append([]assignment{}, s.assignments...) + return &update +} + +func (d *Database) Update(table Table) UpdateWithTable { + return &updateStatus{database: d, table: &table} +} + +type UpdateWithTable interface { + Set(field Field, value interface{}) UpdateWithSet + SetMap(map[Field]interface{}) UpdateWithSet +} + +type UpdateWithSet interface { + Set(Field Field, value interface{}) UpdateWithSet + Where(conditions ...BooleanExpression) UpdateWithWhere +} + +type UpdateWithWhere interface { + GetSQL() (string, error) + Execute() (sql.Result, error) +} + +func (s *updateStatus) Set(field Field, value interface{}) UpdateWithSet { + update := s.copy() + update.assignments = append(update.assignments, assignment{ + field: field, + value: value, + }) + return update +} + +func (s *updateStatus) SetMap(values map[Field]interface{}) UpdateWithSet { + update := s.copy() + for field, value := range values { + update.assignments = append(update.assignments, assignment{ + field: field, + value: value, + }) + } + return update +} + +func (s *updateStatus) Where(conditions ...BooleanExpression) UpdateWithWhere { + update := s.copy() + condition := And(conditions...) + update.where = &condition + return update +} + +func (s *updateStatus) GetSQL() (string, error) { + sqlString := getCallerInfo() + "UPDATE " + (*s.table).GetSQL() + + " SET " + commaAssignments(s.assignments) + + " WHERE " + (*s.where).GetSQL() + + return sqlString, nil +} + +func (s *updateStatus) Execute() (sql.Result, error) { + sqlString, err := s.GetSQL() + if err != nil { + return nil, err + } + return s.database.Execute(sqlString) +}