Browse Source

Moved xql to github.com/archsh/go.xql

develop
Mingcai SHEN 8 years ago
parent
commit
95939e29d4
13 changed files with 2 additions and 1075 deletions
  1. +1
    -1
      models/inject/metas.go
  2. +1
    -1
      models/published/vod.go
  3. +0
    -44
      xql/driver.go
  4. +0
    -1
      xql/driver/mysql/mysql.go
  5. +0
    -187
      xql/driver/postgres/postgres.go
  6. +0
    -252
      xql/field-types.go
  7. +0
    -40
      xql/query-types.go
  8. +0
    -285
      xql/query.go
  9. +0
    -113
      xql/session.go
  10. +0
    -70
      xql/table.go
  11. +0
    -3
      xql/types.go
  12. +0
    -10
      xql/xql.go
  13. +0
    -68
      xql/xql_test.go

+ 1
- 1
models/inject/metas.go View File

@ -1,7 +1,7 @@
package inject
import (
"bitbucket.org/cygnux/kepler/xql"
"github.com/archsh/go.xql"
"bitbucket.org/cygnux/kepler/models/metas"
)

+ 1
- 1
models/published/vod.go View File

@ -5,7 +5,7 @@ import (
"encoding/json"
"database/sql/driver"
"time"
"bitbucket.org/cygnux/kepler/xql"
"github.com/archsh/go.xql"
)
//type HStore map[string]string

+ 0
- 44
xql/driver.go View File

@ -1,44 +0,0 @@
package xql
import (
"database/sql"
)
type StatementBuilder interface {
Create(*Table, ...interface{}) (string, []interface{}, error)
Select(*Table, []QueryColumn, []QueryFilter, []QueryOrder, int64, int64) (string, []interface{}, error)
Insert(*Table, interface{}, ...string) (string, []interface{}, error)
Update(*Table, []QueryFilter, ...UpdateColumn) (string, []interface{}, error)
Delete(*Table, []QueryFilter) (string, []interface{}, error)
}
var _statement_builders map[string]StatementBuilder
func init() {
_statement_builders = make(map[string]StatementBuilder)
}
func RegisterBuilder(name string, d StatementBuilder) {
_statement_builders[name] = d
}
type Engine struct {
db *sql.DB
driverName string
}
func CreateEngine(name string, dataSource string) (*Engine, error) {
db, err := sql.Open(name, dataSource)
if nil != err {
return nil, err
}
return &Engine{db:db, driverName:name}, nil
}
func (engine *Engine) MakeSession() *Session {
return &Session{
db: engine.db,
driverName: engine.driverName,
}
}

+ 0
- 1
xql/driver/mysql/mysql.go View File

@ -1 +0,0 @@
package mysql

+ 0
- 187
xql/driver/postgres/postgres.go View File

@ -1,187 +0,0 @@
package postgres
import (
"bitbucket.org/cygnux/kepler/xql"
"fmt"
"reflect"
"strings"
)
type PostgresBuilder struct {
}
func (pb PostgresBuilder) Create(t *xql.Table, options ...interface{}) (s string, args []interface{}, err error) {
return
}
func (pb PostgresBuilder) Select(t *xql.Table, cols []xql.QueryColumn, filters []xql.QueryFilter, orders []xql.QueryOrder, offset int64, limit int64) (s string, args []interface{}, err error) {
var colnames []string
for _,x := range cols {
colnames = append(colnames, x.String())
}
s = fmt.Sprintf("SELECT %s FROM ", strings.Join(colnames,","))
if t.Schema != "" {
s += t.Schema+"."
}
s += t.TableName
var n int
for i, f := range filters {
var cause string
switch f.Condition {
case xql.CONDITION_AND:
cause = "AND"
case xql.CONDITION_OR:
cause = "OR"
}
if i == 0 {
cause = "WHERE"
}
if f.Operator == "" {
s = fmt.Sprintf(`%s %s %s`, s, cause, f.Field)
} else if f.Reversed {
n += 1
s = fmt.Sprintf(`%s %s $%d %s %s`, s, cause, n, f.Operator, f.Field)
args = append(args, f.Value)
} else {
n += 1
s = fmt.Sprintf(`%s %s %s %s $%d`, s, cause, f.Field, f.Operator, n)
args = append(args, f.Value)
}
}
var s_orders []string
for _, o := range orders {
switch o.Type {
case xql.ORDER_ASC:
s_orders = append(s_orders, fmt.Sprintf(`%s ASC`, o.Field))
case xql.ORDER_DESC:
s_orders = append(s_orders, fmt.Sprintf(`%s DESC`, o.Field))
}
}
if len(s_orders) > 0 {
s = fmt.Sprintf(`%s ORDER BY %s`, s, strings.Join(s_orders, ","))
}
if offset >= 0 && limit >= 0 {
s = fmt.Sprintf(`%s OFFSET %d LIMIT %d`, s, offset, limit)
}
return
}
func (pb PostgresBuilder) Insert(t *xql.Table, obj interface{}, col...string) (s string, args []interface{}, err error) {
s = "INSERT INTO "
if t.Schema != "" {
s += t.Schema+"."
}
s += t.TableName
var cols []string
var vals []string
i := 0
r := reflect.ValueOf(obj)
if len(col) > 0 {
for _, n := range col {
v, ok := t.Columns[n]
if ! ok {
continue
}
i += 1
cols = append(cols, n)
vals = append(vals, fmt.Sprintf("$%d", i))
fv := reflect.Indirect(r).FieldByName(v.PropertyName).Interface()
args = append(args, fv)
}
}else{
for k, v := range t.Columns {
i += 1
cols = append(cols, k)
vals = append(vals, fmt.Sprintf("$%d", i))
fv := reflect.Indirect(r).FieldByName(v.PropertyName).Interface()
args = append(args, fv)
}
}
s = fmt.Sprintf("%s (%s) VALUES(%s)", s, strings.Join(cols,","), strings.Join(vals,","))
return
}
func (pb PostgresBuilder) Update(t *xql.Table, filters []xql.QueryFilter, cols ...xql.UpdateColumn) (s string, args []interface{}, err error) {
s = "UPDATE "
if t.Schema != "" {
s += t.Schema+"."
}
s += t.TableName
if len(cols) < 1 {
panic("Empty Update Columns!!!")
}
var n int
for i, uc := range cols {
if i == 0 {
s = s + " SET "
}
n += 1
s = fmt.Sprintf(`%s "%s"=$%d`,s, uc.Field, n)
args = append(args, uc.Value)
}
for i, f := range filters {
var cause string
switch f.Condition {
case xql.CONDITION_AND:
cause = "AND"
case xql.CONDITION_OR:
cause = "OR"
}
if i == 0 {
cause = "WHERE"
}
if f.Operator == "" {
s = fmt.Sprintf("%s %s %s", s, cause, f.Field)
} else if f.Reversed {
n += 1
s = fmt.Sprintf("%s %s $%d %s %s", s, cause, n, f.Operator, f.Field)
args = append(args, f.Value)
} else {
n += 1
s = fmt.Sprintf("%s %s %s %s $%d", s, cause, f.Field, f.Operator, n)
args = append(args, f.Value)
}
}
return
}
func (pb PostgresBuilder) Delete(t *xql.Table, filters []xql.QueryFilter) (s string, args []interface{}, err error) {
s = "DELETE FROM "
if t.Schema != "" {
s += t.Schema+"."
}
s += t.TableName
var n int
for i, f := range filters {
var cause string
switch f.Condition {
case xql.CONDITION_AND:
cause = "AND"
case xql.CONDITION_OR:
cause = "OR"
}
if i == 0 {
cause = "WHERE"
}
if f.Operator == "" {
s = fmt.Sprintf("%s %s %s", s, cause, f.Field)
} else if f.Reversed {
n += 1
s = fmt.Sprintf("%s %s $%d %s %s", s, cause, n, f.Operator, f.Field)
args = append(args, f.Value)
} else {
n += 1
s = fmt.Sprintf("%s %s %s %s $%d", s, cause, f.Field, f.Operator, n)
args = append(args, f.Value)
}
}
return
}
func init() {
xql.RegisterBuilder("postgres", &PostgresBuilder{})
}

+ 0
- 252
xql/field-types.go View File

@ -1,252 +0,0 @@
package xql
import (
"errors"
"strings"
"fmt"
"regexp"
"database/sql"
"database/sql/driver"
"encoding/json"
)
type JSONDictionary map[string]interface{}
type JSONDictionaryArray []JSONDictionary
type HSTOREDictionary map[string]interface{}
type StringArray []string
type IntegerArray []int
type SmallIntegerArray []int16
type BoolArray []bool
func (p *JSONDictionary) Scan(src interface{}) error {
if nil == src {
*p = nil
return nil
}
source, ok := src.([]byte)
if !ok {
return errors.New("Type assertion .([]byte) failed.")
}
var i JSONDictionary
err := json.Unmarshal(source, &i)
if err != nil {
return err
}
*p = i
return nil
}
func (p JSONDictionary) Value() (driver.Value, error) {
j, err := json.Marshal(p)
return j, err
}
func (p *JSONDictionaryArray) Scan(src interface{}) error {
source, ok := src.([]byte)
if !ok {
return errors.New("Type assertion .([]byte) failed.")
}
var i JSONDictionaryArray
err := json.Unmarshal(source, &i)
if err != nil {
return err
}
*p = i
return nil
}
func (p JSONDictionaryArray) Value() (driver.Value, error) {
j, err := json.Marshal(p)
return j, err
}
// PARSING ARRAYS
// SEE http://www.postgresql.org/docs/9.1/static/arrays.html#ARRAYS-IO
// Arrays are output within {} and a delimiter, which is a comma for most
// postgres types (; for box)
//
// Individual values are surrounded by quotes:
// The array output routine will put double quotes around element values if
// they are empty strings, contain curly braces, delimiter characters,
// double quotes, backslashes, or white space, or match the word NULL.
// Double quotes and backslashes embedded in element values will be
// backslash-escaped. For numeric data types it is safe to assume that double
// quotes will never appear, but for textual data types one should be prepared
// to cope with either the presence or absence of quotes.
// construct a regexp to extract values:
var (
// unquoted array values must not contain: (" , \ { } whitespace NULL)
// and must be at least one char
unquotedChar = `[^",\\{}\s(NULL)]`
unquotedValue = fmt.Sprintf("(%s)+", unquotedChar)
// quoted array values are surrounded by double quotes, can be any
// character except " or \, which must be backslash escaped:
quotedChar = `[^"\\]|\\"|\\\\`
quotedValue = fmt.Sprintf("\"(%s)*\"", quotedChar)
// an array value may be either quoted or unquoted:
arrayValue = fmt.Sprintf("(?P<value>(%s|%s))", unquotedValue, quotedValue)
// Array values are separated with a comma IF there is more than one value:
arrayExp = regexp.MustCompile(fmt.Sprintf("((%s)(,)?)", arrayValue))
valueIndex int
)
// Find the index of the 'value' named expression
func init() {
for i, subexp := range arrayExp.SubexpNames() {
if subexp == "value" {
valueIndex = i
break
}
}
}
// Parse the output string from the array type.
// Regex used: (((?P<value>(([^",\\{}\s(NULL)])+|"([^"\\]|\\"|\\\\)*")))(,)?)
func parseArray(array string) []string {
results := make([]string, 0)
matches := arrayExp.FindAllStringSubmatch(array, -1)
for _, match := range matches {
s := match[valueIndex]
// the string _might_ be wrapped in quotes, so trim them:
s = strings.Trim(s, "\"")
results = append(results, s)
}
return results
}
func (p *StringArray) Scan(src interface{}) error {
asBytes, ok := src.([]byte)
if !ok {
return error(errors.New("Scan source was not []bytes"))
}
asString := string(asBytes)
parsed := parseArray(asString)
(*p) = StringArray(parsed)
return nil
}
func (p StringArray) Value() (driver.Value, error) {
j, err := json.Marshal(p)
return j, err
}
// escapes and quotes hstore keys/values
// s should be a sql.NullString or string
func hQuote(s interface{}) string {
var str string
switch v := s.(type) {
case sql.NullString:
if !v.Valid {
return "NULL"
}
str = v.String
case string:
str = v
default:
panic("not a string or sql.NullString")
}
str = strings.Replace(str, "\\", "\\\\", -1)
return `"` + strings.Replace(str, "\"", "\\\"", -1) + `"`
}
// Scan implements the Scanner interface.
//
// Note h.Map is reallocated before the scan to clear existing values. If the
// hstore column's database value is NULL, then h.Map is set to nil instead.
func (h *HSTOREDictionary) Scan(value interface{}) error {
if value == nil {
*h = nil
return nil
}
m := make(map[string]interface{})
var b byte
pair := [][]byte{{}, {}}
pi := 0
inQuote := false
didQuote := false
sawSlash := false
bindex := 0
for bindex, b = range value.([]byte) {
if sawSlash {
pair[pi] = append(pair[pi], b)
sawSlash = false
continue
}
switch b {
case '\\':
sawSlash = true
continue
case '"':
inQuote = !inQuote
if !didQuote {
didQuote = true
}
continue
default:
if !inQuote {
switch b {
case ' ', '\t', '\n', '\r':
continue
case '=':
continue
case '>':
pi = 1
didQuote = false
continue
case ',':
s := string(pair[1])
if !didQuote && len(s) == 4 && strings.ToLower(s) == "null" {
m[string(pair[0])] = nil // sql.NullString{String: "", Valid: false}
} else {
m[string(pair[0])] = string(pair[1]) // sql.NullString{String: string(pair[1]), Valid: true}
}
pair[0] = []byte{}
pair[1] = []byte{}
pi = 0
continue
}
}
}
pair[pi] = append(pair[pi], b)
}
if bindex > 0 {
s := string(pair[1])
if !didQuote && len(s) == 4 && strings.ToLower(s) == "null" {
m[string(pair[0])] = nil // sql.NullString{String: "", Valid: false}
} else {
m[string(pair[0])] = string(pair[1]) // sql.NullString{String: string(pair[1]), Valid: true}
}
}
*h = m
return nil
}
// Value implements the driver Valuer interface. Note if h.Map is nil, the
// database column value will be set to NULL.
func (h HSTOREDictionary) Value() (driver.Value, error) {
if h == nil {
return nil, nil
}
parts := []string{}
for key, val := range h {
thispart := hQuote(key) + "=>" + hQuote(val)
parts = append(parts, thispart)
}
return []byte(strings.Join(parts, ",")), nil
}

+ 0
- 40
xql/query-types.go View File

@ -1,40 +0,0 @@
package xql
type ConditionType uint
const (
CONDITION_AND ConditionType = iota
CONDITION_OR
)
type OrderType uint
const (
ORDER_ASC OrderType = iota
ORDER_DESC
)
type QueryFilter struct {
Condition ConditionType // AND , OR
Reversed bool // Reversed Field and Value if it is true
Field string
Operator string // Value will not used if empty.
Value interface{}
}
type QueryOrder struct {
Type OrderType
Field string
}
type QueryColumn struct {
FieldName string
Function string
Alias string
}
type UpdateColumn struct {
Field string
Operator string
Value interface{}
}

+ 0
- 285
xql/query.go View File

@ -1,285 +0,0 @@
package xql
import (
"errors"
log "github.com/Sirupsen/logrus"
"reflect"
"database/sql"
)
func (qc QueryColumn) String(as...bool) string {
s := ""
if qc.Function != "" {
s = qc.Function+"("+qc.FieldName+")"
}else{
s = qc.FieldName
}
if qc.Alias != "" && len(as)>0 && as[0] {
s = s + " AS " + qc.Alias
}
return s
}
type QuerySet struct {
session *Session
table *Table
queries []QueryColumn
filters []QueryFilter
orders []QueryOrder
offset int64
limit int64
}
type XRow struct {
row *sql.Row
qs *QuerySet
}
func (self *XRow) Scan(dest ...interface{}) error {
if nil == self.row {
return errors.New("Nil row.")
}
if len(dest) < 1 {
panic("Empty output!")
}
if len(dest) == 1 {
d := dest[0]
if reflect.TypeOf(d) == reflect.TypeOf(self.qs.table.Entity) {
var outputs []interface{}
r := reflect.ValueOf(d)
for _, qc := range self.qs.queries {
c, _ := self.qs.table.Columns[qc.FieldName]
vp := r.Elem().FieldByName(c.PropertyName).Addr().Interface()
outputs = append(outputs, vp)
}
return self.row.Scan(outputs...)
}
}
return self.row.Scan(dest...)
}
type XRows struct {
rows *sql.Rows
qs *QuerySet
}
func (self *XRows) Scan(dest ...interface{}) error {
if nil == self.rows {
return errors.New("No rows.")
}
if len(dest) < 1 {
panic("Empty output!")
}
if len(dest) == 1 {
d := dest[0]
if reflect.TypeOf(d) == reflect.TypeOf(self.qs.table.Entity) {
var outputs []interface{}
r := reflect.ValueOf(d)
for _, qc := range self.qs.queries {
c, _ := self.qs.table.Columns[qc.FieldName]
vp := r.Elem().FieldByName(c.PropertyName).Addr().Interface()
outputs = append(outputs, vp)
}
return self.rows.Scan(outputs...)
}
}
return self.rows.Scan(dest...)
}
func (self *XRows) Next() bool {
if nil == self.rows {
return false
}
return self.rows.Next()
}
func (self *XRows) Close() {
self.rows.Close()
self.rows = nil
}
func makeQueryOrder(table *Table, s string) QueryOrder {
qo := QueryOrder{}
if s[:1] == "-" {
qo.Type = ORDER_DESC
qo.Field = s[1:]
} else {
qo.Type = ORDER_ASC
qo.Field = s
}
return qo
}
func (self *QuerySet) Filter(cons ...interface{}) *QuerySet {
for _, con := range cons {
if vs, ok := con.(string); ok {
self.filters = append(self.filters, QueryFilter{
Field: vs,
})
}else if vm, ok := con.(map[string]interface{}); ok {
for k, v := range vm {
self.filters = append(self.filters, QueryFilter{
Field:k,
Value:v,
Operator: "=",
})
}
}else if vf, ok := con.(QueryFilter); ok {
self.filters = append(self.filters, vf)
}
}
return self
}
func (self *QuerySet) OrderBy(orders ...interface{}) *QuerySet {
for _, x := range orders {
switch x.(type) {
case string:
qo := makeQueryOrder(self.table, x.(string))
self.orders = append(self.orders, qo)
case QueryOrder:
self.orders = append(self.orders, x.(QueryOrder))
default:
panic("Not supported parameter type.")
}
}
return self
}
func (self *QuerySet) Offset(offset int64) *QuerySet {
self.offset = offset
return self
}
func (self *QuerySet) Limit(limit int64) *QuerySet {
self.limit = limit
return self
}
func (self *QuerySet) Count(cols...string) (int64,error) {
s, args, err := self.session.getStatementBuilder().Select(self.table,
[]QueryColumn{{Function:"COUNT", FieldName:"*"}},
self.filters, nil, -1, -1)
if nil != err {
return 0, err
}
row := self.session.doQueryRow(s, args...)
var n int64
if e := row.Scan(&n); nil != e {
return 0, e
}
return n, nil
}
func (self *QuerySet) All() (*XRows, error) {
s, args, err := self.session.getStatementBuilder().Select(self.table, self.queries,
self.filters, self.orders, self.offset, self.limit)
if nil != err {
return nil, err
}
rows, err := self.session.doQuery(s, args...)
if nil != err {
return nil, err
}
xrows := &XRows{rows:rows, qs:self}
return xrows, nil
}
func (self *QuerySet) One() *XRow {
s, args, err := self.session.getStatementBuilder().Select(self.table, self.queries,
self.filters, self.orders, self.offset, 1)
if nil != err {
return nil
}
row := self.session.doQueryRow(s, args...)
xrow := &XRow{row:row, qs:self}
return xrow
}
func (self *QuerySet) Update(vals interface{}) (int64, error) {
cols := []UpdateColumn{}
if cm, ok := vals.(map[string]interface{}); ok {
for k, v := range cm {
uc := UpdateColumn{Field:k, Value:v, Operator:"="}
cols = append(cols, uc)
}
}else if cx, ok := vals.([]UpdateColumn); ok {
cols = cx
}
s, args, err := self.session.getStatementBuilder().Update(self.table, self.filters, cols...)
if nil != err {
return 0, err
}
var ret sql.Result
ret, err = self.session.doExec(s, args...)
if nil != err {
return 0, err
}else{
rows, e := ret.RowsAffected()
return rows, e
}
return 0, nil
}
func (self *QuerySet) Delete() (int64, error) {
s, args, err := self.session.getStatementBuilder().Delete(self.table, self.filters)
if nil != err {
return 0, err
}
var ret sql.Result
ret, err = self.session.doExec(s, args...)
if nil != err {
return 0, err
}else{
rows, e := ret.RowsAffected()
return rows, e
}
return 0, nil
}
func (self *QuerySet) Insert(objs ...interface{}) (int64, error) {
//log.Debugln("Insert:> ", objs)
//log.Debugln("Table:> ", self.table)
//var ret sql.Result
var rows int64 = 0
var cols []string
if len(self.queries) > 0 {
for _,x := range self.queries {
cols = append(cols, x.FieldName)
}
}
for _, obj := range objs {
log.Debugln("reflect.TypeOf(obj)>", reflect.TypeOf(obj))
log.Debugln("reflect.TypeOf(self.table.Entity)>", reflect.TypeOf(self.table.Entity))
if reflect.TypeOf(obj) != reflect.TypeOf(self.table.Entity) {
return 0, errors.New("Invalid data type.")
}
s, args, err := self.session.getStatementBuilder().Insert(self.table, obj, cols...)
if nil != err {
return 0, err
}
_, err = self.session.doExec(s, args...)
if nil != err {
return 0, err
}else{
//if nil != ret {
// n, e := ret.LastInsertId()
// if nil == e {
// rows += n
// }else{
// rows += 1
// }
// //log.Debugln("Insert:> ", n)
//}else{
// rows += 1
//}
rows += 1
}
}
return rows, nil
}

+ 0
- 113
xql/session.go View File

@ -1,113 +0,0 @@
package xql
import (
"errors"
"database/sql"
"fmt"
log "github.com/Sirupsen/logrus"
)
type Session struct {
driverName string
db *sql.DB
tx *sql.Tx
}
func (self *Session) getStatementBuilder() StatementBuilder {
if s, ok := _statement_builders[self.driverName]; ok {
return s
}else{
panic(fmt.Sprintf("Statement Builder '%s' not registered! ", self.driverName))
}
return nil
}
func (self *Session) Query(table *Table, columns ...interface{}) *QuerySet {
qs := &QuerySet{session:self, offset:-1, limit:-1}
qs.table = table
if len(columns) > 0 {
for _, c := range columns {
if qc, ok := c.(QueryColumn); ok {
qs.queries = append(qs.queries, qc)
}else if qcn, ok := c.(string); ok {
if col, ok := qs.table.Columns[qcn]; !ok {
panic("Invalid column name.")
}else{
qs.queries = append(qs.queries, QueryColumn{FieldName:col.FieldName, Alias:col.FieldName})
}
}else{
panic("Unsupported parameter type!")
}
}
}else{
for _, col := range qs.table.Columns {
qs.queries = append(qs.queries, QueryColumn{FieldName:col.FieldName, Alias:col.FieldName})
}
}
return qs
}
func (self *Session) Begin() error {
if nil != self.tx {
return errors.New("Already in Tx!")
}
tx, err := self.db.Begin()
if nil == err {
self.tx = tx
}
return err
}
func (self *Session) Commit() error {
if nil == self.tx {
return errors.New("Not open Tx!")
}
err := self.tx.Commit()
if nil == err {
self.tx = nil
}
return err
}
func (self *Session) Rollback() error {
if nil == self.tx {
return errors.New("Not open Tx!")
}
err := self.tx.Rollback()
self.tx = nil
return err
}
func (self *Session) doExec(query string, args ...interface{}) (sql.Result, error) {
if self.tx != nil {
log.Debugln("doExec in Tx: ", query, args)
return self.tx.Exec(query, args...)
}else{
log.Debugln("doExec in DB: ", query, args)
return self.db.Exec(query, args...)
}
return nil, nil
}
func (self *Session) doQuery(query string, args ...interface{}) (*sql.Rows, error) {
if self.tx != nil {
log.Debugln("doQuery in Tx: ", query, args)
return self.tx.Query(query, args...)
}else{
log.Debugln("doQuery in DB: ", query, args)
return self.db.Query(query, args...)
}
return nil, nil
}
func (self *Session) doQueryRow(query string, args ...interface{}) *sql.Row {
if self.tx != nil {
log.Debugln("doQueryRow in Tx: ", query, args)
return self.tx.QueryRow(query, args...)
}else{
log.Debugln("doQueryRow in Db: ", query, args)
return self.db.QueryRow(query, args...)
}
return nil
}

+ 0
- 70
xql/table.go View File

@ -1,70 +0,0 @@
package xql
import (
"reflect"
"bitbucket.org/cygnux/kepler/utils"
"strings"
)
type Table struct {
TableName string
Schema string
Entity interface{}
Columns map[string]Column
PrimaryKey []string
}
type Column struct {
FieldName string
PropertyName string
Type string
Length uint16
Unique bool
Nullable bool
Indexed bool
PrimaryKey bool
}
func DeclareTable(name string, entity interface{}, schema ...string) *Table {
t := &Table{
TableName:name,
Entity: entity,
Columns: make(map[string]Column),
}
if len(schema) > 0 {
t.Schema = schema[0]
}
if nil != entity {
et := reflect.TypeOf(entity)
for i:=0; i< et.Elem().NumField(); i++ {
f := et.Elem().Field(i)
//f.Name
c := Column{PropertyName:f.Name}
x_tags := strings.Split(f.Tag.Get("xql"),",")
if len(x_tags) < 1 || x_tags[0]=="" {
c.FieldName = utils.Camel2Underscore(f.Name)
}else if x_tags[0] == "-" {
continue
}else{
c.FieldName = x_tags[0]
for _, x := range x_tags[1:] {
switch x {
case "pk":
c.PrimaryKey = true
t.PrimaryKey = append(t.PrimaryKey, x)
case "indexed":
c.Indexed = true
case "nullable":
c.Nullable = true
case "unique":
c.Unique = true
}
}
}
t.Columns[c.FieldName] = c
}
}
return t
}

+ 0
- 3
xql/types.go View File

@ -1,3 +0,0 @@
package xql

+ 0
- 10
xql/xql.go View File

@ -1,10 +0,0 @@
package xql
import "database/sql"
func MakeSession(db *sql.DB, driverName string) *Session {
return &Session{db:db, driverName:driverName}
}

+ 0
- 68
xql/xql_test.go View File

@ -1,68 +0,0 @@
package xql
import (
"testing"
"time"
_ "github.com/lib/pq"
"bitbucket.org/cygnux/kepler/models/metas"
"github.com/archsh/go.uuid"
_ "bitbucket.org/cygnux/kepler/xql/driver/postgres"
)
var MovieCrew = DeclareTable("metas_crews", &metas.Crew{}, "deneb")
func TestCreateEngine(t *testing.T) {
t1 := time.Now()
engine, e := CreateEngine("postgres",
"host=localhost port=5432 user=postgres password=postgres dbname=cygnuxdb sslmode=disable")
if nil != e {
t.Fatal("Connec DB failed:> ", e)
}
t.Log("MovieCrew:> ", MovieCrew)
_ = engine.MakeSession()
t.Log("Time spent:> ", time.Now().Sub(t1))
}
func TestQuerySet_Insert(t *testing.T) {
t1 := time.Now()
engine, e := CreateEngine("postgres",
"host=localhost port=5432 user=postgres password=postgres dbname=cygnuxdb sslmode=disable")
if nil != e {
t.Fatal("Connec DB failed:> ", e)
}
t.Log("MovieCrew:> ", MovieCrew)
sess := engine.MakeSession()
c1 := metas.Crew{Id:uuid.NewV4().String(), FullName:"Tom Cruse", Region:"US"}
c2 := metas.Crew{Id:uuid.NewV4().String(), FullName:"Hue Jackman", Region:"US"}
n, e := sess.Query(MovieCrew).Insert(&c1, &c2)
if nil != e {
t.Fatal("Insert failed:> ", e)
}
t.Log("Insert lines:>", n)
t.Log("Time spent:> ", time.Now().Sub(t1))
}
func TestQuerySet_Update(t *testing.T) {
t1 := time.Now()
t.Log("Time spent:> ", time.Now().Sub(t1))
}
func TestQuerySet_Delete(t *testing.T) {
t1 := time.Now()
t.Log("Time spent:> ", time.Now().Sub(t1))
}
func TestQuerySet_One(t *testing.T) {
t1 := time.Now()
t.Log("Time spent:> ", time.Now().Sub(t1))
}
func TestQuerySet_Scan(t *testing.T) {
t1 := time.Now()
t.Log("Time spent:> ", time.Now().Sub(t1))
}

Loading…
Cancel
Save