mapping now supported single mapping and struct derive
This commit is contained in:
parent
d82b879453
commit
5e90d61fa8
19
engine.go
19
engine.go
|
@ -2,7 +2,7 @@ package xorm
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
//"fmt"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -154,7 +154,7 @@ func (engine *Engine) MapType(t reflect.Type) *Table {
|
|||
|
||||
if ormTagStr != "" {
|
||||
col = Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false,
|
||||
IsAutoIncrement: false}
|
||||
IsAutoIncrement: false, MapType: TWOSIDES}
|
||||
ormTagStr = strings.ToLower(ormTagStr)
|
||||
tags := strings.Split(ormTagStr, " ")
|
||||
// TODO:
|
||||
|
@ -162,9 +162,22 @@ func (engine *Engine) MapType(t reflect.Type) *Table {
|
|||
if tags[0] == "-" {
|
||||
continue
|
||||
}
|
||||
if (tags[0] == "extends") &&
|
||||
(fieldType.Kind() == reflect.Struct) &&
|
||||
t.Field(i).Anonymous {
|
||||
parentTable := engine.MapType(fieldType)
|
||||
for name, col := range parentTable.Columns {
|
||||
col.FieldName = fmt.Sprintf("%v.%v", fieldType.Name(), col.FieldName)
|
||||
table.Columns[name] = col
|
||||
}
|
||||
}
|
||||
for j, key := range tags {
|
||||
k := strings.ToLower(key)
|
||||
switch {
|
||||
case k == "<-":
|
||||
col.MapType = ONLYFROMDB
|
||||
case k == "->":
|
||||
col.MapType = ONLYTODB
|
||||
case k == "pk":
|
||||
col.IsPrimaryKey = true
|
||||
col.Nullable = false
|
||||
|
@ -230,7 +243,7 @@ func (engine *Engine) MapType(t reflect.Type) *Table {
|
|||
} else {
|
||||
sqlType := Type2SQLType(fieldType)
|
||||
col = Column{engine.Mapper.Obj2Table(t.Field(i).Name), t.Field(i).Name, sqlType,
|
||||
sqlType.DefaultLength, sqlType.DefaultLength2, true, "", false, false, false}
|
||||
sqlType.DefaultLength, sqlType.DefaultLength2, true, "", false, false, false, TWOSIDES}
|
||||
|
||||
if col.Name == "id" {
|
||||
col.IsPrimaryKey = true
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"os"
|
||||
. "xorm"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id int64
|
||||
Name string
|
||||
}
|
||||
|
||||
type LoginInfo struct {
|
||||
Id int64
|
||||
IP string
|
||||
UserId int64
|
||||
}
|
||||
|
||||
type LoginInfo1 struct {
|
||||
LoginInfo `xorm:"extends"`
|
||||
UserName string
|
||||
}
|
||||
|
||||
func main() {
|
||||
f := "derive.db"
|
||||
os.Remove(f)
|
||||
|
||||
Orm, err := NewEngine("sqlite3", f)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
Orm.ShowSQL = true
|
||||
err = Orm.CreateTables(&User{}, &LoginInfo{})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = Orm.Insert(&User{1, "xlw"}, &LoginInfo{1, "127.0.0.1", 1})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
info := LoginInfo{}
|
||||
_, err = Orm.Id(1).Get(&info)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
fmt.Println(info)
|
||||
|
||||
infos := make([]LoginInfo1, 0)
|
||||
err = Orm.Sql(`select *, (select name from user where id = login_info.user_id) as user_name from
|
||||
login_info limit 10`).Find(&infos)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(infos)
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"os"
|
||||
. "xorm"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id int64
|
||||
Name string
|
||||
}
|
||||
|
||||
type LoginInfo struct {
|
||||
Id int64
|
||||
IP string
|
||||
UserId int64
|
||||
// timestamp should be updated by database, so only allow get from db
|
||||
TimeStamp string `xorm:"<-"`
|
||||
// assume
|
||||
Nonuse int `xorm:"->"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
f := "singleMapping.db"
|
||||
os.Remove(f)
|
||||
|
||||
Orm, err := NewEngine("sqlite3", f)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
Orm.ShowSQL = true
|
||||
err = Orm.CreateTables(&User{}, &LoginInfo{})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = Orm.Insert(&User{1, "xlw"}, &LoginInfo{1, "127.0.0.1", 1, "", 23})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
info := LoginInfo{}
|
||||
_, err = Orm.Id(1).Get(&info)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
fmt.Println(info)
|
||||
}
|
26
session.go
26
session.go
|
@ -157,8 +157,21 @@ func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]b
|
|||
table := session.Engine.Tables[Type(obj)]
|
||||
|
||||
for key, data := range objMap {
|
||||
structField := dataStruct.FieldByName(table.Columns[key].FieldName)
|
||||
if !structField.CanSet() {
|
||||
fieldName := table.Columns[key].FieldName
|
||||
fieldPath := strings.Split(fieldName, ".")
|
||||
var structField reflect.Value
|
||||
if len(fieldPath) > 2 {
|
||||
fmt.Printf("xorm: Warning! Unsupported mutliderive %v\n", fieldName)
|
||||
continue
|
||||
} else if len(fieldPath) == 2 {
|
||||
parentField := dataStruct.FieldByName(fieldPath[0])
|
||||
if parentField.IsValid() {
|
||||
structField = parentField.FieldByName(fieldPath[1])
|
||||
}
|
||||
} else {
|
||||
structField = dataStruct.FieldByName(fieldName)
|
||||
}
|
||||
if !structField.IsValid() || !structField.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -618,6 +631,9 @@ func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
|
|||
if col.IsAutoIncrement && fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
if col.MapType == ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
if table, ok := session.Engine.Tables[fieldValue.Type()]; ok {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumn().FieldName)
|
||||
fmt.Println(pkField.Interface())
|
||||
|
@ -636,6 +652,9 @@ func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
|
|||
if col.IsAutoIncrement && fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
if col.MapType == ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
if table, ok := session.Engine.Tables[fieldValue.Type()]; ok {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumn().FieldName)
|
||||
args = append(args, pkField.Interface())
|
||||
|
@ -681,6 +700,9 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) {
|
|||
if col.IsAutoIncrement && fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
if col.MapType == ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
if fieldTable, ok := session.Engine.Tables[fieldValue.Type()]; ok {
|
||||
if fieldTable.PrimaryKey != "" {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumn().FieldName)
|
||||
|
|
|
@ -202,8 +202,10 @@ func (statement *Statement) selectColumnStr() string {
|
|||
table := statement.RefTable
|
||||
colNames := make([]string, 0)
|
||||
for _, col := range table.Columns {
|
||||
if col.MapType != ONLYTODB {
|
||||
colNames = append(colNames, statement.TableName()+"."+col.Name)
|
||||
}
|
||||
}
|
||||
return strings.Join(colNames, ", ")
|
||||
}
|
||||
|
||||
|
|
7
table.go
7
table.go
|
@ -64,6 +64,12 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
|
|||
return
|
||||
}
|
||||
|
||||
const (
|
||||
TWOSIDES = iota + 1
|
||||
ONLYTODB
|
||||
ONLYFROMDB
|
||||
)
|
||||
|
||||
type Column struct {
|
||||
Name string
|
||||
FieldName string
|
||||
|
@ -75,6 +81,7 @@ type Column struct {
|
|||
IsUnique bool
|
||||
IsPrimaryKey bool
|
||||
IsAutoIncrement bool
|
||||
MapType int
|
||||
}
|
||||
|
||||
type Table struct {
|
||||
|
|
Loading…
Reference in New Issue