TODO: autostore
This commit is contained in:
parent
f86c255407
commit
2236e13af7
|
@ -1,28 +1,163 @@
|
||||||
package intimate
|
package intimate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Store struct {
|
type Store struct {
|
||||||
|
db *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStore() *Store {
|
type Table struct {
|
||||||
return &Store{}
|
store *Store
|
||||||
|
name string
|
||||||
|
setting interface{}
|
||||||
|
|
||||||
|
updatesql string
|
||||||
|
selectsql string
|
||||||
|
insertsql string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *Store) Update(obj interface{}, objfields ...interface{}) {
|
// const updatesql = "UPDATE %s SET %s WHERE %s = ?"
|
||||||
ov := reflect.ValueOf(obj)
|
|
||||||
ot := ov.Type()
|
func NewStore(uri string) *Store {
|
||||||
log.Printf("%#v,%#v", ov, ot)
|
db, err := sql.Open("mysql", uri)
|
||||||
log.Println(reflect.Indirect(reflect.ValueOf(objfields[0])))
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
s := &Store{db: db}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (store *Store) Table(name string) *Table {
|
||||||
|
table := &Table{store: store}
|
||||||
|
table.name = name
|
||||||
|
|
||||||
|
table.insertsql = `INSERT INTO ` + table.name + `(%s) values(%s)`
|
||||||
|
table.updatesql = `UPDATE ` + table.name + ` SET %s WHERE %s = ?`
|
||||||
|
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
|
||||||
|
type Queue struct {
|
||||||
|
table *Table
|
||||||
|
obj reflect.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Table) Insert(obj interface{}) error {
|
||||||
|
ov := reflect.ValueOf(obj).Elem()
|
||||||
|
ot := reflect.TypeOf(obj)
|
||||||
|
|
||||||
|
fieldsql := ""
|
||||||
|
argssql := ""
|
||||||
|
|
||||||
|
var args []interface{}
|
||||||
|
for i := 0; i < ov.NumField(); i++ {
|
||||||
|
field := ov.Field(i)
|
||||||
|
ftype := ot.Elem().Field(i)
|
||||||
|
|
||||||
|
if fname, ok := ftype.Tag.Lookup("field"); ok {
|
||||||
|
if flag, ok := ftype.Tag.Lookup("uid"); ok {
|
||||||
|
if flag == "auto" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k := ftype.Type.Kind()
|
||||||
|
if k == reflect.Ptr || k == reflect.Interface {
|
||||||
|
if !field.IsNil() {
|
||||||
|
felem := field.Elem()
|
||||||
|
args = append(args, felem.Interface())
|
||||||
|
fieldsql += fname + ","
|
||||||
|
argssql += "?,"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args = append(args, field.Interface())
|
||||||
|
fieldsql += fname + ","
|
||||||
|
argssql += "?,"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ssql := fmt.Sprintf(t.insertsql, fieldsql[:len(fieldsql)-1], argssql[:len(argssql)-1])
|
||||||
|
_, err := t.store.db.Exec(ssql, args...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Table) Update(obj interface{}) error {
|
||||||
|
|
||||||
|
ov := reflect.ValueOf(obj).Elem()
|
||||||
|
ot := reflect.TypeOf(obj)
|
||||||
|
|
||||||
|
fieldsql := ""
|
||||||
|
var uidname string
|
||||||
|
var uidvalue interface{}
|
||||||
|
|
||||||
|
var args []interface{}
|
||||||
|
for i := 0; i < ov.NumField(); i++ {
|
||||||
|
field := ov.Field(i)
|
||||||
|
ftype := ot.Elem().Field(i)
|
||||||
|
|
||||||
|
if fname, ok := ftype.Tag.Lookup("field"); ok {
|
||||||
|
if _, ok := ftype.Tag.Lookup("uid"); ok {
|
||||||
|
if uidvalue != nil {
|
||||||
|
panic(fmt.Errorf("uid must unique, %s and %s", uidname, fname))
|
||||||
|
}
|
||||||
|
uidname = fname
|
||||||
|
uidvalue = field.Interface()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
k := ftype.Type.Kind()
|
||||||
|
if k == reflect.Ptr || k == reflect.Interface {
|
||||||
|
if !field.IsNil() {
|
||||||
|
felem := field.Elem()
|
||||||
|
args = append(args, felem.Interface())
|
||||||
|
fieldsql += fname + " = ?,"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args = append(args, field.Interface())
|
||||||
|
fieldsql += fname + " = ?,"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if uidvalue == nil {
|
||||||
|
panic(fmt.Errorf("update must contain `uid` tag"))
|
||||||
|
}
|
||||||
|
|
||||||
|
usql := fmt.Sprintf(t.updatesql, fieldsql[:len(fieldsql)-1], uidname)
|
||||||
|
args = append(args, uidvalue)
|
||||||
|
_, err := t.store.db.Exec(usql, args...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type TSreamer struct {
|
||||||
|
Uid int `field:"uid" uid:"auto"`
|
||||||
|
Name interface{} `field:"name"`
|
||||||
|
UserID *sql.NullString `field:"userid"`
|
||||||
|
Ext *sql.NullString `field:"ext"`
|
||||||
|
Iface interface{} `field:"tag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAutoStore(t *testing.T) {
|
func TestAutoStore(t *testing.T) {
|
||||||
store := NewStore()
|
uri := "root:@tcp(127.0.0.1:4000)/test?parseTime=true&loc=Local&charset=utf8mb4&collation=utf8mb4_unicode_ci"
|
||||||
streamer := &Streamer{}
|
store := NewStore(uri)
|
||||||
|
streamer := &TSreamer{}
|
||||||
|
|
||||||
store.Update(streamer, streamer.Channel)
|
streamer.Uid = 2
|
||||||
|
streamer.UserID = nil
|
||||||
|
streamer.Name = "streamer"
|
||||||
|
streamer.Ext = &sql.NullString{String: "ext", Valid: true}
|
||||||
|
err := store.Table("streamer").Update(streamer)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@ func (sl *StreamerList) Set(field string, value interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Streamer struct {
|
type Streamer struct {
|
||||||
Uid int64 //
|
Uid int64 `field:"uid" uid:"auto"` //
|
||||||
Platform Platform //
|
Platform Platform `field:"platform"` //
|
||||||
UserId string //
|
UserId string //
|
||||||
|
|
||||||
UserName sql.NullString //
|
UserName sql.NullString //
|
||||||
|
|
Loading…
Reference in New Issue
Block a user