2013-10-26 05:49:40 +04:00
|
|
|
package gorm
|
|
|
|
|
|
|
|
import (
|
2013-10-26 11:02:14 +04:00
|
|
|
"errors"
|
2013-10-26 08:33:05 +04:00
|
|
|
"fmt"
|
2013-10-26 07:59:58 +04:00
|
|
|
"reflect"
|
2013-10-27 06:17:11 +04:00
|
|
|
"regexp"
|
2013-10-26 05:49:40 +04:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2013-10-27 06:17:11 +04:00
|
|
|
func (s *Orm) validSql(str string) (result bool) {
|
|
|
|
result = regexp.MustCompile("^\\s*[\\w][\\w\\s,.]*[\\w]\\s*$").MatchString(str)
|
|
|
|
if !result {
|
|
|
|
s.Error = errors.New(fmt.Sprintf("SQL is not valid, %s", str))
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-10-26 07:59:58 +04:00
|
|
|
func (s *Orm) explain(value interface{}, operation string) *Orm {
|
2013-10-27 03:52:04 +04:00
|
|
|
s.Model(value)
|
2013-10-27 05:32:49 +04:00
|
|
|
|
2013-10-26 05:49:40 +04:00
|
|
|
switch operation {
|
2013-10-26 16:20:49 +04:00
|
|
|
case "Create":
|
|
|
|
s.createSql(value)
|
|
|
|
case "Update":
|
|
|
|
s.updateSql(value)
|
2013-10-26 05:49:40 +04:00
|
|
|
case "Delete":
|
|
|
|
s.deleteSql(value)
|
2013-10-26 07:59:58 +04:00
|
|
|
case "Query":
|
|
|
|
s.querySql(value)
|
2013-10-26 11:47:30 +04:00
|
|
|
case "CreateTable":
|
2013-10-27 03:52:04 +04:00
|
|
|
s.Sql = s.model.CreateTable()
|
2013-10-26 07:59:58 +04:00
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Orm) querySql(out interface{}) {
|
2013-10-27 05:50:11 +04:00
|
|
|
s.Sql = fmt.Sprintf("SELECT %v FROM %v %v", s.selectSql(), s.TableName, s.whereSql())
|
2013-10-26 07:59:58 +04:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Orm) query(out interface{}) {
|
2013-10-26 08:33:05 +04:00
|
|
|
var (
|
|
|
|
is_slice bool
|
|
|
|
dest_type reflect.Type
|
|
|
|
)
|
|
|
|
dest_out := reflect.Indirect(reflect.ValueOf(out))
|
|
|
|
|
|
|
|
if x := dest_out.Kind(); x == reflect.Slice {
|
|
|
|
is_slice = true
|
|
|
|
dest_type = dest_out.Type().Elem()
|
|
|
|
}
|
|
|
|
|
2013-10-26 10:10:47 +04:00
|
|
|
rows, err := s.db.Query(s.Sql, s.SqlVars...)
|
2013-10-26 11:02:14 +04:00
|
|
|
defer rows.Close()
|
2013-10-27 05:32:49 +04:00
|
|
|
|
2013-10-26 07:59:58 +04:00
|
|
|
s.Error = err
|
2013-10-26 11:02:14 +04:00
|
|
|
if rows.Err() != nil {
|
|
|
|
s.Error = rows.Err()
|
|
|
|
}
|
2013-10-26 08:33:05 +04:00
|
|
|
|
2013-10-26 11:02:14 +04:00
|
|
|
counts := 0
|
2013-10-26 07:59:58 +04:00
|
|
|
for rows.Next() {
|
2013-10-26 11:02:14 +04:00
|
|
|
counts += 1
|
2013-10-26 08:33:05 +04:00
|
|
|
var dest reflect.Value
|
|
|
|
if is_slice {
|
|
|
|
dest = reflect.New(dest_type).Elem()
|
|
|
|
} else {
|
|
|
|
dest = reflect.ValueOf(out).Elem()
|
|
|
|
}
|
|
|
|
|
2013-10-26 07:59:58 +04:00
|
|
|
columns, _ := rows.Columns()
|
|
|
|
var values []interface{}
|
|
|
|
for _, value := range columns {
|
2013-10-26 10:23:02 +04:00
|
|
|
values = append(values, dest.FieldByName(snakeToUpperCamel(value)).Addr().Interface())
|
2013-10-26 07:59:58 +04:00
|
|
|
}
|
|
|
|
s.Error = rows.Scan(values...)
|
2013-10-26 20:36:56 +04:00
|
|
|
|
|
|
|
if is_slice {
|
|
|
|
dest_out.Set(reflect.Append(dest_out, dest))
|
|
|
|
}
|
2013-10-26 05:49:40 +04:00
|
|
|
}
|
2013-10-26 20:36:56 +04:00
|
|
|
|
2013-10-26 11:02:14 +04:00
|
|
|
if (counts == 0) && !is_slice {
|
|
|
|
s.Error = errors.New("Record not found!")
|
|
|
|
}
|
2013-10-26 05:49:40 +04:00
|
|
|
}
|
|
|
|
|
2013-10-27 05:32:49 +04:00
|
|
|
func (s *Orm) pluck(value interface{}) {
|
|
|
|
dest_out := reflect.Indirect(reflect.ValueOf(value))
|
|
|
|
dest_type := dest_out.Type().Elem()
|
|
|
|
|
|
|
|
rows, err := s.db.Query(s.Sql, s.SqlVars...)
|
|
|
|
s.Error = err
|
|
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
2013-10-27 06:28:47 +04:00
|
|
|
dest := reflect.New(dest_type).Elem().Interface()
|
|
|
|
s.Error = rows.Scan(&dest)
|
|
|
|
dest_out.Set(reflect.Append(dest_out, reflect.ValueOf(dest)))
|
2013-10-27 05:32:49 +04:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-10-26 16:20:49 +04:00
|
|
|
func (s *Orm) createSql(value interface{}) {
|
2013-10-27 03:52:04 +04:00
|
|
|
columns, values := s.model.ColumnsAndValues()
|
2013-10-26 19:30:17 +04:00
|
|
|
|
|
|
|
var sqls []string
|
|
|
|
for _, value := range values {
|
|
|
|
sqls = append(sqls, s.addToVars(value))
|
|
|
|
}
|
|
|
|
|
2013-10-26 05:49:40 +04:00
|
|
|
s.Sql = fmt.Sprintf(
|
2013-10-26 16:20:49 +04:00
|
|
|
"INSERT INTO \"%v\" (%v) VALUES (%v) %v",
|
2013-10-26 05:49:40 +04:00
|
|
|
s.TableName,
|
2013-10-26 17:37:42 +04:00
|
|
|
strings.Join(s.quoteMap(columns), ","),
|
2013-10-26 19:30:17 +04:00
|
|
|
strings.Join(sqls, ","),
|
2013-10-27 03:52:04 +04:00
|
|
|
s.model.ReturningStr(),
|
2013-10-26 05:49:40 +04:00
|
|
|
)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-10-26 16:20:49 +04:00
|
|
|
func (s *Orm) create(value interface{}) {
|
|
|
|
var id int64
|
|
|
|
if s.driver == "postgres" {
|
|
|
|
s.Error = s.db.QueryRow(s.Sql, s.SqlVars...).Scan(&id)
|
|
|
|
} else {
|
|
|
|
s.SqlResult, s.Error = s.db.Exec(s.Sql, s.SqlVars...)
|
|
|
|
id, s.Error = s.SqlResult.LastInsertId()
|
|
|
|
}
|
|
|
|
|
2013-10-27 03:52:04 +04:00
|
|
|
result := reflect.ValueOf(s.model.Data).Elem()
|
|
|
|
result.FieldByName(s.model.PrimaryKey()).SetInt(id)
|
2013-10-26 16:20:49 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Orm) updateSql(value interface{}) {
|
2013-10-27 03:52:04 +04:00
|
|
|
columns, values := s.model.ColumnsAndValues()
|
2013-10-26 17:37:42 +04:00
|
|
|
var sets []string
|
|
|
|
for index, column := range columns {
|
2013-10-26 19:30:17 +04:00
|
|
|
sets = append(sets, fmt.Sprintf("%v = %v", s.quote(column), s.addToVars(values[index])))
|
2013-10-26 17:37:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
s.Sql = fmt.Sprintf(
|
2013-10-26 19:30:17 +04:00
|
|
|
"UPDATE %v SET %v %v",
|
2013-10-26 17:37:42 +04:00
|
|
|
s.TableName,
|
|
|
|
strings.Join(sets, ", "),
|
2013-10-26 19:30:17 +04:00
|
|
|
s.whereSql(),
|
2013-10-26 17:37:42 +04:00
|
|
|
)
|
2013-10-26 19:30:17 +04:00
|
|
|
|
2013-10-26 16:20:49 +04:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Orm) update(value interface{}) {
|
2013-10-26 17:37:42 +04:00
|
|
|
s.Exec()
|
2013-10-26 16:20:49 +04:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-10-26 05:49:40 +04:00
|
|
|
func (s *Orm) deleteSql(value interface{}) {
|
2013-10-26 17:51:44 +04:00
|
|
|
s.Sql = fmt.Sprintf("DELETE FROM %v %v", s.TableName, s.whereSql())
|
2013-10-26 05:49:40 +04:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Orm) whereSql() (sql string) {
|
2013-10-26 19:30:17 +04:00
|
|
|
var conditions []string
|
2013-10-27 03:52:04 +04:00
|
|
|
if !s.model.PrimaryKeyIsEmpty() {
|
|
|
|
conditions = append(conditions, fmt.Sprintf("(%v = %v)", s.quote(s.model.PrimaryKeyDb()), s.addToVars(s.model.PrimaryKeyValue())))
|
2013-10-26 19:30:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(s.whereClause) > 0 {
|
2013-10-26 10:10:47 +04:00
|
|
|
for _, clause := range s.whereClause {
|
2013-10-26 19:30:17 +04:00
|
|
|
str := "( " + clause["query"].(string) + " )"
|
2013-10-26 10:10:47 +04:00
|
|
|
args := clause["args"].([]interface{})
|
|
|
|
for _, arg := range args {
|
2013-10-26 22:51:34 +04:00
|
|
|
switch reflect.TypeOf(arg).Kind() {
|
|
|
|
case reflect.Slice: // For where("id in (?)", []int64{1,2})
|
|
|
|
v := reflect.ValueOf(arg)
|
2013-10-26 22:31:38 +04:00
|
|
|
|
|
|
|
var temp_marks []string
|
2013-10-26 22:51:34 +04:00
|
|
|
for i := 0; i < v.Len(); i++ {
|
2013-10-26 22:31:38 +04:00
|
|
|
temp_marks = append(temp_marks, "?")
|
|
|
|
}
|
2013-10-26 22:51:34 +04:00
|
|
|
|
2013-10-26 22:31:38 +04:00
|
|
|
str = strings.Replace(str, "?", strings.Join(temp_marks, ","), 1)
|
2013-10-26 22:51:34 +04:00
|
|
|
|
|
|
|
for i := 0; i < v.Len(); i++ {
|
|
|
|
str = strings.Replace(str, "?", s.addToVars(v.Index(i).Addr().Interface()), 1)
|
2013-10-26 22:31:38 +04:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
str = strings.Replace(str, "?", s.addToVars(arg), 1)
|
|
|
|
}
|
2013-10-26 10:10:47 +04:00
|
|
|
}
|
2013-10-26 19:30:17 +04:00
|
|
|
conditions = append(conditions, str)
|
2013-10-26 10:10:47 +04:00
|
|
|
}
|
|
|
|
}
|
2013-10-26 19:30:17 +04:00
|
|
|
|
|
|
|
if len(conditions) > 0 {
|
|
|
|
sql = "WHERE " + strings.Join(conditions, " AND ")
|
|
|
|
}
|
2013-10-26 05:49:40 +04:00
|
|
|
return
|
|
|
|
}
|
2013-10-26 19:30:17 +04:00
|
|
|
|
2013-10-27 05:50:11 +04:00
|
|
|
func (s *Orm) selectSql() string {
|
|
|
|
if len(s.selectStr) == 0 {
|
|
|
|
return " * "
|
|
|
|
} else {
|
|
|
|
return s.selectStr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-26 19:30:17 +04:00
|
|
|
func (s *Orm) addToVars(value interface{}) string {
|
|
|
|
s.SqlVars = append(s.SqlVars, value)
|
|
|
|
return fmt.Sprintf("$%d", len(s.SqlVars))
|
|
|
|
}
|