started models
This commit is contained in:
parent
ed7ee74924
commit
7542f56906
|
@ -436,7 +436,7 @@ func deleteComic(id int) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func main() {
|
||||
func mains() {
|
||||
var err error
|
||||
|
||||
errlog = log.New(log.Writer(), "[ERROR] ", log.Flags())
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"strings"
|
||||
"reflect"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
var columnTypeMap map[string]string = map[string]string {
|
||||
"int" : "INTEGER",
|
||||
"string" : "TEXT",
|
||||
"datetime" : "DATETIME",
|
||||
}
|
||||
|
||||
type ModelManager struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (mm *ModelManager) OpenDB(path string) error {
|
||||
var err error
|
||||
mm.db, err = sql.Open("sqlite3", path)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mm *ModelManager) CloseDB() error {
|
||||
return mm.db.Close()
|
||||
}
|
||||
|
||||
func (mm *ModelManager) Model(s interface{}) *Model {
|
||||
model := &Model{
|
||||
name : getStructName(s),
|
||||
manager : mm,
|
||||
}
|
||||
|
||||
tpe := reflect.ValueOf(s).Elem()
|
||||
|
||||
model.fields = make([]reflect.StructField, tpe.NumField())
|
||||
model.fieldInterfaces = make([]interface{}, tpe.NumField())
|
||||
model.value = tpe
|
||||
|
||||
for i := 0; i < tpe.NumField(); i ++ {
|
||||
model.fields[i] = tpe.Type().Field(i)
|
||||
model.fieldInterfaces[i] = tpe.Field(i).Interface()
|
||||
}
|
||||
|
||||
return model
|
||||
}
|
||||
|
||||
type Model struct {
|
||||
idColumn string
|
||||
idInterface interface{}
|
||||
name string
|
||||
fields []reflect.StructField
|
||||
fieldInterfaces []interface{}
|
||||
value reflect.Value
|
||||
manager *ModelManager
|
||||
}
|
||||
|
||||
func (m *Model) buildSquema() string {
|
||||
s := 0
|
||||
has_key := false
|
||||
|
||||
squema := "CREATE TABLE IF NOT EXISTS " + m.name + " (\n"
|
||||
for i, f := range m.fields {
|
||||
if !f.IsExported() {
|
||||
continue
|
||||
}
|
||||
s++
|
||||
|
||||
t, ok := columnTypeMap[f.Type.String()]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
cn := getColumnName(f.Name)
|
||||
squema += "\t" + cn + " " + t
|
||||
|
||||
p, _ := f.Tag.Lookup("primary_key")
|
||||
if p == "true" && !has_key {
|
||||
has_key = true
|
||||
m.idColumn = cn
|
||||
m.idInterface = m.value.Field(i).Interface()
|
||||
squema += " PRIMARY KEY"
|
||||
}
|
||||
|
||||
p, _ = f.Tag.Lookup("can_null")
|
||||
if p != "true" {
|
||||
squema += " NOT NULL"
|
||||
}
|
||||
|
||||
if i < len(m.fields)-1 {
|
||||
squema += ","
|
||||
}
|
||||
squema += "\n"
|
||||
}
|
||||
squema += ");"
|
||||
|
||||
m.fields = m.fields[:s]
|
||||
|
||||
if !has_key {
|
||||
m.idColumn = "id"
|
||||
}
|
||||
|
||||
return squema
|
||||
}
|
||||
|
||||
func (m *Model) Create() error {
|
||||
_, err := m.manager.db.Exec(m.buildSquema())
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *Model) Insert() error {
|
||||
columns := ""
|
||||
inputs := ""
|
||||
|
||||
for i, f := range m.fields {
|
||||
columns += getColumnName(f.Name)
|
||||
inputs += "?"
|
||||
if i < len(m.fields)-1 {
|
||||
columns += ","
|
||||
inputs += ","
|
||||
}
|
||||
}
|
||||
|
||||
exp := fmt.Sprintf("INSERT INTO %s(%s) VALUES(%s)", m.name, columns, inputs)
|
||||
_, err := m.manager.db.Exec(exp, m.fieldInterfaces...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *Model) Update() error {
|
||||
inputs := ""
|
||||
|
||||
fields := make([]interface{}, len(m.fields))
|
||||
for i, f := range m.fields {
|
||||
if m.idColumn == f.Name {
|
||||
continue
|
||||
}
|
||||
|
||||
fields[i] = m.value.Field(i).Interface()
|
||||
|
||||
inputs += getColumnName(f.Name) + " = ?"
|
||||
if i < len(m.fields)-1 {
|
||||
inputs += ","
|
||||
}
|
||||
}
|
||||
fields = append(fields, m.idInterface)
|
||||
|
||||
exp := fmt.Sprintf("UPDATE %s SET %s WHERE %s = ?", m.name, inputs, m.idColumn)
|
||||
_, err := m.manager.db.Exec(exp, fields...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *Model) FindBy(column string, by interface{}) (*QueryResults, error) {
|
||||
r := &QueryResults{}
|
||||
|
||||
rows, err := m.manager.db.Query("SELECT * FROM " + m.name + " WHERE ? = ?;", column, by)
|
||||
r.rows = rows
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !r.rows.Next() {
|
||||
return nil, errors.New("no such entry found")
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (m *Model) FindByID(id interface{}) (*QueryResults, error) {
|
||||
return m.FindBy(m.idColumn, id)
|
||||
}
|
||||
|
||||
func (m *Model) ReadResults(r *QueryResults) bool {
|
||||
r.rows.Scan(m.fieldInterfaces...)
|
||||
return r.rows.Next()
|
||||
}
|
||||
|
||||
type QueryResults struct {
|
||||
rows * sql.Rows
|
||||
}
|
||||
|
||||
func (r *QueryResults) Close() error {
|
||||
return r.rows.Close()
|
||||
}
|
||||
|
||||
func getStructName(s interface{}) string {
|
||||
n := ""
|
||||
if t := reflect.TypeOf(s); t.Kind() == reflect.Ptr {
|
||||
n = t.Elem().Name()
|
||||
} else {
|
||||
n = t.Name()
|
||||
}
|
||||
|
||||
return strings.ToLower(n)
|
||||
}
|
||||
|
||||
func getColumnName(column string) string {
|
||||
return strings.ToLower(column)
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
This string `primary_key:"true" `
|
||||
Iss int `can_null:"true"`
|
||||
ATest string `primary_key:"true" `
|
||||
}
|
||||
|
||||
func main() {
|
||||
mm := &ModelManager{}
|
||||
test := Test{
|
||||
ATest : "fingers crossed",
|
||||
}
|
||||
|
||||
test.This = "sdssd"
|
||||
m := mm.Model(&test)
|
||||
|
||||
mm.OpenDB("db.sqlite")
|
||||
defer mm.CloseDB()
|
||||
m.Create()
|
||||
|
||||
m.Insert()
|
||||
test.ATest = "LOOaaaaaaaaaaaOL"
|
||||
m.Update()
|
||||
|
||||
a := Test{}
|
||||
ma := mm.Model(&a)
|
||||
fmt.Println(m.idColumn)
|
||||
res, err := ma.FindByID("sdssd")
|
||||
panic(err)
|
||||
if res != nil {
|
||||
defer res.Close()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue