simple orm add
This commit is contained in:
parent
c73ae76b25
commit
918fed8166
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 数据源本地存储已忽略文件
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/stardb.iml" filepath="$PROJECT_DIR$/.idea/stardb.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
9
.idea/stardb.iml
generated
Normal file
9
.idea/stardb.iml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
93
orm_v1.go
Normal file
93
orm_v1.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package stardb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (star *StarRows) Orm(ins interface{}) error {
|
||||||
|
//check if is slice
|
||||||
|
if !star.parsed {
|
||||||
|
if err := star.parserows(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t := reflect.TypeOf(ins)
|
||||||
|
v := reflect.ValueOf(ins)
|
||||||
|
if t.Kind() != reflect.Ptr {
|
||||||
|
return errors.New("interface not writable")
|
||||||
|
}
|
||||||
|
//now convert to slice
|
||||||
|
t = t.Elem()
|
||||||
|
v = v.Elem()
|
||||||
|
if star.Length == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if v.Kind() == reflect.Slice || v.Kind() == reflect.Array {
|
||||||
|
//get type of slice
|
||||||
|
sigType := t.Elem()
|
||||||
|
var result reflect.Value
|
||||||
|
result = reflect.New(t).Elem()
|
||||||
|
for i := 0; i < star.Length; i++ {
|
||||||
|
val := reflect.New(sigType)
|
||||||
|
star.setAllRefValue(val.Interface(), "db", i)
|
||||||
|
result = reflect.Append(result, val.Elem())
|
||||||
|
}
|
||||||
|
v.Set(result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return star.setAllRefValue(ins, "db", 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (star *StarDB) QueryX(sql string, ins interface{}, args ...interface{}) (*StarRows, error) {
|
||||||
|
kvMap, err := getAllRefValue(ins, "db")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for k, v := range args {
|
||||||
|
switch v.(type) {
|
||||||
|
case string:
|
||||||
|
str := v.(string)
|
||||||
|
if strings.Index(str, ":") == 0 {
|
||||||
|
if _, ok := kvMap[str[1:]]; ok {
|
||||||
|
args[k] = kvMap[str[1:]]
|
||||||
|
} else {
|
||||||
|
args[k] = ""
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Index(str, `\:`) == 0 {
|
||||||
|
args[k] = kvMap[str[1:]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return star.Query(sql, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (star *StarDB) ExecX(sql string, ins interface{}, args ...interface{}) (sql.Result, error) {
|
||||||
|
kvMap, err := getAllRefValue(ins, "db")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for k, v := range args {
|
||||||
|
switch v.(type) {
|
||||||
|
case string:
|
||||||
|
str := v.(string)
|
||||||
|
if strings.Index(str, ":") == 0 {
|
||||||
|
if _, ok := kvMap[str[1:]]; ok {
|
||||||
|
args[k] = kvMap[str[1:]]
|
||||||
|
} else {
|
||||||
|
args[k] = ""
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Index(str, `\:`) == 0 {
|
||||||
|
args[k] = kvMap[str[1:]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return star.Exec(sql, args)
|
||||||
|
}
|
162
reflect.go
Normal file
162
reflect.go
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
package stardb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (star *StarRows) setAllRefValue(stc interface{}, skey string, rows int) error {
|
||||||
|
t := reflect.TypeOf(stc)
|
||||||
|
v := reflect.ValueOf(stc).Elem()
|
||||||
|
if t.Kind() != reflect.Ptr || !v.CanSet() {
|
||||||
|
return errors.New("interface{} is not writable")
|
||||||
|
}
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return errors.New("interface{} is not a struct")
|
||||||
|
}
|
||||||
|
t = t.Elem()
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
tp := t.Field(i)
|
||||||
|
seg := tp.Tag.Get(skey)
|
||||||
|
if seg == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := star.Row(rows).columnref[seg]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
myInt64 := star.Row(rows).MustInt64(seg)
|
||||||
|
myUint64 := uint64(star.Row(rows).MustInt64(seg))
|
||||||
|
switch v.Field(i).Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
v.Field(i).SetString(star.Row(rows).MustString(seg))
|
||||||
|
case reflect.Int64:
|
||||||
|
v.Field(i).SetInt(myInt64)
|
||||||
|
case reflect.Int32:
|
||||||
|
v.Field(i).SetInt(int64(star.Row(rows).MustInt32(seg)))
|
||||||
|
case reflect.Int16:
|
||||||
|
v.Field(i).SetInt(int64(int16(myInt64)))
|
||||||
|
case reflect.Int8:
|
||||||
|
v.Field(i).SetInt(int64(int8(myInt64)))
|
||||||
|
case reflect.Uint64:
|
||||||
|
v.Field(i).SetUint(myUint64)
|
||||||
|
case reflect.Uint32:
|
||||||
|
v.Field(i).SetUint(uint64(uint32(myUint64)))
|
||||||
|
case reflect.Uint16:
|
||||||
|
v.Field(i).SetUint(uint64(uint16(myUint64)))
|
||||||
|
case reflect.Uint8:
|
||||||
|
v.Field(i).SetUint(uint64(uint8(myUint64)))
|
||||||
|
case reflect.Bool:
|
||||||
|
v.Field(i).SetBool(star.Row(rows).MustBool(seg))
|
||||||
|
case reflect.Float64:
|
||||||
|
v.Field(i).SetFloat(star.Row(rows).MustFloat64(seg))
|
||||||
|
case reflect.Float32:
|
||||||
|
v.Field(i).SetFloat(float64(star.Row(rows).MustFloat32(seg)))
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setAllRefValue(stc interface{}, skey string, kv map[string]interface{}) error {
|
||||||
|
t := reflect.TypeOf(stc)
|
||||||
|
v := reflect.ValueOf(stc).Elem()
|
||||||
|
if t.Kind() != reflect.Ptr || !v.CanSet() {
|
||||||
|
return errors.New("interface{} is not writable")
|
||||||
|
}
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return errors.New("interface{} is not a struct")
|
||||||
|
}
|
||||||
|
t = t.Elem()
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
tp := t.Field(i)
|
||||||
|
seg := tp.Tag.Get(skey)
|
||||||
|
if seg == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := kv[seg]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v.Field(i).Set(reflect.ValueOf(kv[seg]))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setRefValue(stc interface{}, skey, key string, value interface{}) error {
|
||||||
|
t := reflect.TypeOf(stc)
|
||||||
|
v := reflect.ValueOf(stc).Elem()
|
||||||
|
if t.Kind() != reflect.Ptr || !v.CanSet() {
|
||||||
|
return errors.New("interface{} is not writable")
|
||||||
|
}
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return errors.New("interface{} is not a struct")
|
||||||
|
}
|
||||||
|
t = t.Elem()
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
tp := t.Field(i)
|
||||||
|
seg := tp.Tag.Get(skey)
|
||||||
|
if seg == "" || key != seg {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v.Field(i).Set(reflect.ValueOf(value))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllRefValue(stc interface{}, skey string) (map[string]interface{}, error) {
|
||||||
|
result := make(map[string]interface{})
|
||||||
|
t := reflect.TypeOf(stc)
|
||||||
|
v := reflect.ValueOf(stc)
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return nil, errors.New("interface{} is not a struct")
|
||||||
|
}
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
t = t.Elem()
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
tp := t.Field(i)
|
||||||
|
seg := tp.Tag.Get(skey)
|
||||||
|
if seg == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
value := v.Field(i)
|
||||||
|
if !value.CanInterface() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result[seg] = value.Interface()
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllRefKey(stc interface{}, skey string) ([]string, error) {
|
||||||
|
var result []string
|
||||||
|
_, isStruct := isWritableStruct(stc)
|
||||||
|
if !isStruct {
|
||||||
|
return []string{}, errors.New("interface{} is not a struct")
|
||||||
|
}
|
||||||
|
t := reflect.TypeOf(stc)
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
profile := t.Field(i)
|
||||||
|
seg := profile.Tag.Get(skey)
|
||||||
|
if seg != "" {
|
||||||
|
result = append(result, seg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isWritableStruct(stc interface{}) (isWritable bool, isStruct bool) {
|
||||||
|
t := reflect.TypeOf(stc)
|
||||||
|
v := reflect.ValueOf(stc)
|
||||||
|
if t.Kind() == reflect.Ptr && v.Elem().CanSet() {
|
||||||
|
isWritable = true
|
||||||
|
}
|
||||||
|
if v.Kind() == reflect.Struct {
|
||||||
|
isStruct = true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
44
reflect_test.go
Normal file
44
reflect_test.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package stardb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Useless struct {
|
||||||
|
Leader string `db:"leader"`
|
||||||
|
Usable bool `db:"use"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_SetRefVal(t *testing.T) {
|
||||||
|
var hehe = Useless{
|
||||||
|
Leader: "no",
|
||||||
|
}
|
||||||
|
mmval := map[string]interface{}{
|
||||||
|
"leader": "hehe",
|
||||||
|
"use": true,
|
||||||
|
}
|
||||||
|
fmt.Printf("%+v\n", hehe)
|
||||||
|
fmt.Println(setRefValue(&hehe, "db", "leader", "sb"))
|
||||||
|
fmt.Printf("%+v\n", hehe)
|
||||||
|
fmt.Println(setAllRefValue(&hehe, "db", mmval))
|
||||||
|
fmt.Printf("%+v\n", hehe)
|
||||||
|
fmt.Println(getAllRefKey(hehe, "db"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Ref(t *testing.T) {
|
||||||
|
var me []Useless
|
||||||
|
p := reflect.TypeOf(&me).Elem()
|
||||||
|
v := reflect.ValueOf(&me).Elem()
|
||||||
|
mmval := map[string]interface{}{
|
||||||
|
"leader": "hehe",
|
||||||
|
"use": true,
|
||||||
|
}
|
||||||
|
newVal := reflect.New(p)
|
||||||
|
val := reflect.New(p.Elem())
|
||||||
|
setAllRefValue(val.Interface(), "db", mmval)
|
||||||
|
mynum:= reflect.Append(newVal.Elem(), val.Elem())
|
||||||
|
v.Set(mynum)
|
||||||
|
fmt.Println(val.Interface(), me, v)
|
||||||
|
}
|
26
stardb_v1.go
26
stardb_v1.go
@ -11,7 +11,7 @@ import (
|
|||||||
// StarDB 一个简单封装的DB库
|
// StarDB 一个简单封装的DB库
|
||||||
type StarDB struct {
|
type StarDB struct {
|
||||||
DB *sql.DB
|
DB *sql.DB
|
||||||
Rows *sql.Rows
|
ManualScan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// StarRows 为查询结果集(按行)
|
// StarRows 为查询结果集(按行)
|
||||||
@ -23,6 +23,7 @@ type StarRows struct {
|
|||||||
ColumnsType []reflect.Type
|
ColumnsType []reflect.Type
|
||||||
columnref map[string]int
|
columnref map[string]int
|
||||||
result [][]interface{}
|
result [][]interface{}
|
||||||
|
parsed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// StarResult 为查询结果集(总)
|
// StarResult 为查询结果集(总)
|
||||||
@ -674,7 +675,10 @@ func (star *StarRows) Close() error {
|
|||||||
return star.Rows.Close()
|
return star.Rows.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (star *StarRows) parserows() {
|
func (star *StarRows) parserows() error {
|
||||||
|
defer func() {
|
||||||
|
star.parsed = true
|
||||||
|
}()
|
||||||
star.result = [][]interface{}{}
|
star.result = [][]interface{}{}
|
||||||
star.columnref = make(map[string]int)
|
star.columnref = make(map[string]int)
|
||||||
star.StringResult = []map[string]string{}
|
star.StringResult = []map[string]string{}
|
||||||
@ -691,7 +695,7 @@ func (star *StarRows) parserows() {
|
|||||||
}
|
}
|
||||||
for star.Rows.Next() {
|
for star.Rows.Next() {
|
||||||
if err := star.Rows.Scan(scanArgs...); err != nil {
|
if err := star.Rows.Scan(scanArgs...); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
record := make(map[string]string)
|
record := make(map[string]string)
|
||||||
var rescopy []interface{}
|
var rescopy []interface{}
|
||||||
@ -724,11 +728,13 @@ func (star *StarRows) parserows() {
|
|||||||
star.StringResult = append(star.StringResult, record)
|
star.StringResult = append(star.StringResult, record)
|
||||||
}
|
}
|
||||||
star.Length = len(star.StringResult)
|
star.Length = len(star.StringResult)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query 进行Query操作
|
// Query 进行Query操作
|
||||||
func (star *StarDB) Query(args ...interface{}) (*StarRows, error) {
|
func (star *StarDB) Query(args ...interface{}) (*StarRows, error) {
|
||||||
var err error
|
var err error
|
||||||
|
var rows *sql.Rows
|
||||||
effect := new(StarRows)
|
effect := new(StarRows)
|
||||||
if err = star.DB.Ping(); err != nil {
|
if err = star.DB.Ping(); err != nil {
|
||||||
return effect, err
|
return effect, err
|
||||||
@ -738,10 +744,10 @@ func (star *StarDB) Query(args ...interface{}) (*StarRows, error) {
|
|||||||
}
|
}
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
sql := args[0]
|
sql := args[0]
|
||||||
if star.Rows, err = star.DB.Query(sql.(string)); err != nil {
|
if rows, err = star.DB.Query(sql.(string)); err != nil {
|
||||||
return effect, err
|
return effect, err
|
||||||
}
|
}
|
||||||
effect.Rows = star.Rows
|
effect.Rows = rows
|
||||||
effect.parserows()
|
effect.parserows()
|
||||||
return effect, nil
|
return effect, nil
|
||||||
}
|
}
|
||||||
@ -760,12 +766,14 @@ func (star *StarDB) Query(args ...interface{}) (*StarRows, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if star.Rows, err = stmt.Query(para...); err != nil {
|
if rows, err = stmt.Query(para...); err != nil {
|
||||||
return effect, err
|
return effect, err
|
||||||
}
|
}
|
||||||
effect.Rows = star.Rows
|
effect.Rows = rows
|
||||||
effect.parserows()
|
if !star.ManualScan {
|
||||||
return effect, nil
|
err = effect.parserows()
|
||||||
|
}
|
||||||
|
return effect, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open 打开一个新的数据库
|
// Open 打开一个新的数据库
|
||||||
|
Loading…
x
Reference in New Issue
Block a user