完成autostore.
TODO: 替换old store 类.
This commit is contained in:
parent
1590fa0c82
commit
7849d09a18
69
autostore.go
69
autostore.go
@ -10,6 +10,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*Store 结构体. 必须使用tag. field 数据库字段标签 uid 唯一id字段标签必须存在
|
||||||
|
*/
|
||||||
type Store struct {
|
type Store struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
}
|
}
|
||||||
@ -35,6 +37,7 @@ func NewStore(uri string) *Store {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Table 选择表.
|
||||||
func (store *Store) Table(name string) *Table {
|
func (store *Store) Table(name string) *Table {
|
||||||
table := &Table{store: store}
|
table := &Table{store: store}
|
||||||
table.name = name
|
table.name = name
|
||||||
@ -42,9 +45,11 @@ func (store *Store) Table(name string) *Table {
|
|||||||
table.insertsql = `INSERT INTO ` + table.name + `(%s) values(%s)`
|
table.insertsql = `INSERT INTO ` + table.name + `(%s) values(%s)`
|
||||||
table.updatesql = `UPDATE ` + table.name + ` SET %s WHERE %s = ?`
|
table.updatesql = `UPDATE ` + table.name + ` SET %s WHERE %s = ?`
|
||||||
// table.selectsql = `FROM ` + table.name + `WHERE operator`
|
// table.selectsql = `FROM ` + table.name + `WHERE operator`
|
||||||
|
table.selectsql = `SELECT %s FROM ` + table.name + ` WHERE %s `
|
||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Queue mysql 队列结构
|
||||||
type Queue struct {
|
type Queue struct {
|
||||||
table *Table
|
table *Table
|
||||||
obj reflect.Type
|
obj reflect.Type
|
||||||
@ -66,6 +71,7 @@ const (
|
|||||||
OpERROR OperatorType = "10000"
|
OpERROR OperatorType = "10000"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Queue 根据Table生成一个队列. 处理结构. 每次弹出一个 obj 是要处理的结构体 自定义的whereCondition条件
|
||||||
func (t *Table) Queue(obj interface{}, whereCondition string) *Queue {
|
func (t *Table) Queue(obj interface{}, whereCondition string) *Queue {
|
||||||
q := &Queue{}
|
q := &Queue{}
|
||||||
q.condition = whereCondition
|
q.condition = whereCondition
|
||||||
@ -88,6 +94,68 @@ func (t *Table) Queue(obj interface{}, whereCondition string) *Queue {
|
|||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pop 队列弹出一个数据(任务). 参考队列处理 不支持嵌套.
|
||||||
|
func (queue *Queue) Pop() (result interface{}, err error) {
|
||||||
|
|
||||||
|
db := queue.table.store.db
|
||||||
|
tx, err := db.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
cerr := tx.Commit()
|
||||||
|
if cerr != nil {
|
||||||
|
log.Println(cerr)
|
||||||
|
log.Println(tx.Rollback())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
selectsql := `SELECT ` + queue.selected + ` FROM ` + queue.table.name + ` WHERE ` + queue.condition + " limit 1 for update"
|
||||||
|
rows, err := tx.Query(selectsql)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("table: %s queue is empty", queue.table.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
var fields = make([]interface{}, queue.obj.NumField())
|
||||||
|
for i := range fields {
|
||||||
|
var iv interface{}
|
||||||
|
fields[i] = &iv
|
||||||
|
}
|
||||||
|
|
||||||
|
if rows.Next() {
|
||||||
|
err = rows.Scan(fields...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
columntypes, err := rows.ColumnTypes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = tx.Exec("UPDATE "+queue.table.name+" SET operator = "+string(OpWAIT)+" WHERE "+queue.uidname+" = ?", fields[queue.uididx])
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
obj := reflect.New(queue.obj).Elem()
|
||||||
|
for i := 0; i < obj.NumField(); i++ {
|
||||||
|
field := obj.Field(i)
|
||||||
|
convert(*fields[i].(*interface{}), field, columntypes[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj.Addr().Interface(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert nil 不插入. 不支持嵌套.
|
||||||
func (t *Table) Insert(obj interface{}) error {
|
func (t *Table) Insert(obj interface{}) error {
|
||||||
ov := reflect.ValueOf(obj).Elem()
|
ov := reflect.ValueOf(obj).Elem()
|
||||||
ot := reflect.TypeOf(obj)
|
ot := reflect.TypeOf(obj)
|
||||||
@ -130,6 +198,7 @@ func (t *Table) Insert(obj interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update 结构体更新
|
||||||
func (t *Table) Update(obj interface{}) error {
|
func (t *Table) Update(obj interface{}) error {
|
||||||
|
|
||||||
ov := reflect.ValueOf(obj).Elem()
|
ov := reflect.ValueOf(obj).Elem()
|
||||||
|
@ -3,79 +3,13 @@ package intimate
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (queue *Queue) Pop() (result interface{}, err error) {
|
func estAutoStore(t *testing.T) {
|
||||||
|
|
||||||
db := queue.table.store.db
|
|
||||||
tx, err := db.Begin()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
cerr := tx.Commit()
|
|
||||||
if cerr != nil {
|
|
||||||
log.Println(cerr)
|
|
||||||
log.Println(tx.Rollback())
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
selectsql := `SELECT ` + queue.selected + ` FROM ` + queue.table.name + ` WHERE ` + queue.condition + " limit 1 for update"
|
|
||||||
rows, err := tx.Query(selectsql)
|
|
||||||
// err = rows.Err()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("table: %s queue is empty", queue.table.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
var fields = make([]interface{}, queue.obj.NumField())
|
|
||||||
for i := range fields {
|
|
||||||
var iv interface{}
|
|
||||||
fields[i] = &iv
|
|
||||||
}
|
|
||||||
|
|
||||||
// if !rows.Next() {
|
|
||||||
// return nil, fmt.Errorf("table: %s queue is empty", queue.table.name)
|
|
||||||
// }
|
|
||||||
if rows.Next() {
|
|
||||||
err = rows.Scan(fields...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
columntypes, err := rows.ColumnTypes()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = rows.Close(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = tx.Exec("UPDATE "+queue.table.name+" SET operator = "+string(OpWAIT)+" WHERE "+queue.uidname+" = ?", fields[queue.uididx])
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
obj := reflect.New(queue.obj).Elem()
|
|
||||||
for i := 0; i < obj.NumField(); i++ {
|
|
||||||
field := obj.Field(i)
|
|
||||||
convert(*fields[i].(*interface{}), field, columntypes[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj.Addr().Interface(), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAutoStore(t *testing.T) {
|
|
||||||
uri := "root:@tcp(127.0.0.1:4000)/test?parseTime=true&loc=Local&charset=utf8mb4&collation=utf8mb4_unicode_ci"
|
uri := "root:@tcp(127.0.0.1:4000)/test?parseTime=true&loc=Local&charset=utf8mb4&collation=utf8mb4_unicode_ci"
|
||||||
store := NewStore(uri)
|
store := NewStore(uri)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user