Giter Site home page Giter Site logo

go-xorm / xorm Goto Github PK

View Code? Open in Web Editor NEW
6.7K 265.0 758.0 4.18 MB

Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle, Moved to https://gitea.com/xorm/xorm

License: BSD 3-Clause "New" or "Revised" License

Go 99.87% Shell 0.13%
golang orm mysql sqlite mssql postgres postgresql tidb

xorm's Introduction

xorm HAS BEEN MOVED TO https://gitea.com/xorm/xorm . THIS REPOSITORY WILL NOT BE UPDATED ANY MORE.

中文

Xorm is a simple and powerful ORM for Go.

CircleCI codecov Join the chat at https://img.shields.io/discord/323460943201959939.svg

Features

  • Struct <-> Table Mapping Support

  • Chainable APIs

  • Transaction Support

  • Both ORM and raw SQL operation Support

  • Sync database schema Support

  • Query Cache speed up

  • Database Reverse support, See Xorm Tool README

  • Simple cascade loading support

  • Optimistic Locking support

  • SQL Builder support via xorm.io/builder

  • Automatical Read/Write seperatelly

  • Postgres schema support

  • Context Cache support

Drivers Support

Drivers for Go's sql package which currently support database/sql includes:

Installation

go get github.com/go-xorm/xorm

Documents

Quick Start

  • Create Engine
engine, err := xorm.NewEngine(driverName, dataSourceName)
  • Define a struct and Sync2 table struct to database
type User struct {
    Id int64
    Name string
    Salt string
    Age int
    Passwd string `xorm:"varchar(200)"`
    Created time.Time `xorm:"created"`
    Updated time.Time `xorm:"updated"`
}

err := engine.Sync2(new(User))
  • Create Engine Group
dataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName}
engineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice)
masterEngine, err := xorm.NewEngine(driverName, masterDataSourceName)
slave1Engine, err := xorm.NewEngine(driverName, slave1DataSourceName)
slave2Engine, err := xorm.NewEngine(driverName, slave2DataSourceName)
engineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, slave2Engine})

Then all place where engine you can just use engineGroup.

  • Query runs a SQL string, the returned results is []map[string][]byte, QueryString returns []map[string]string, QueryInterface returns []map[string]interface{}.
results, err := engine.Query("select * from user")
results, err := engine.Where("a = 1").Query()

results, err := engine.QueryString("select * from user")
results, err := engine.Where("a = 1").QueryString()

results, err := engine.QueryInterface("select * from user")
results, err := engine.Where("a = 1").QueryInterface()
  • Exec runs a SQL string, it returns affected and error
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
  • Insert one or multiple records to database
affected, err := engine.Insert(&user)
// INSERT INTO struct () values ()

affected, err := engine.Insert(&user1, &user2)
// INSERT INTO struct1 () values ()
// INSERT INTO struct2 () values ()

affected, err := engine.Insert(&users)
// INSERT INTO struct () values (),(),()

affected, err := engine.Insert(&user1, &users)
// INSERT INTO struct1 () values ()
// INSERT INTO struct2 () values (),(),()
  • Get query one record from database
has, err := engine.Get(&user)
// SELECT * FROM user LIMIT 1

has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1

var name string
has, err := engine.Table(&user).Where("id = ?", id).Cols("name").Get(&name)
// SELECT name FROM user WHERE id = ?

var id int64
has, err := engine.Table(&user).Where("name = ?", name).Cols("id").Get(&id)
has, err := engine.SQL("select id from user").Get(&id)
// SELECT id FROM user WHERE name = ?

var valuesMap = make(map[string]string)
has, err := engine.Table(&user).Where("id = ?", id).Get(&valuesMap)
// SELECT * FROM user WHERE id = ?

var valuesSlice = make([]interface{}, len(cols))
has, err := engine.Table(&user).Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
// SELECT col1, col2, col3 FROM user WHERE id = ?
  • Exist check if one record exist on table
has, err := testEngine.Exist(new(RecordExist))
// SELECT * FROM record_exist LIMIT 1

has, err = testEngine.Exist(&RecordExist{
		Name: "test1",
	})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1

has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1

has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist()
// select * from record_exist where name = ?

has, err = testEngine.Table("record_exist").Exist()
// SELECT * FROM record_exist LIMIT 1

has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist()
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
  • Find query multiple records from database, also you can use join and extends
var users []User
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0

type Detail struct {
    Id int64
    UserId int64 `xorm:"index"`
}

type UserDetail struct {
    User `xorm:"extends"`
    Detail `xorm:"extends"`
}

var users []UserDetail
err := engine.Table("user").Select("user.*, detail.*").
    Join("INNER", "detail", "detail.user_id = user.id").
    Where("user.name = ?", name).Limit(10, 0).
    Find(&users)
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0
  • Iterate and Rows query multiple records and record by record handle, there are two methods Iterate and Rows
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
    user := bean.(*User)
    return nil
})
// SELECT * FROM user

err := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
    user := bean.(*User)
    return nil
})
// SELECT * FROM user Limit 0, 100
// SELECT * FROM user Limit 101, 100

rows, err := engine.Rows(&User{Name:name})
// SELECT * FROM user
defer rows.Close()
bean := new(Struct)
for rows.Next() {
    err = rows.Scan(bean)
}
  • Update update one or more records, default will update non-empty and non-zero fields except when you use Cols, AllCols and so on.
affected, err := engine.ID(1).Update(&user)
// UPDATE user SET ... Where id = ?

affected, err := engine.Update(&user, &User{Name:name})
// UPDATE user SET ... Where name = ?

var ids = []int64{1, 2, 3}
affected, err := engine.In("id", ids).Update(&user)
// UPDATE user SET ... Where id IN (?, ?, ?)

// force update indicated columns by Cols
affected, err := engine.ID(1).Cols("age").Update(&User{Name:name, Age: 12})
// UPDATE user SET age = ?, updated=? Where id = ?

// force NOT update indicated columns by Omit
affected, err := engine.ID(1).Omit("name").Update(&User{Name:name, Age: 12})
// UPDATE user SET age = ?, updated=? Where id = ?

affected, err := engine.ID(1).AllCols().Update(&user)
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
  • Delete delete one or more records, Delete MUST have condition
affected, err := engine.Where(...).Delete(&user)
// DELETE FROM user Where ...

affected, err := engine.ID(2).Delete(&user)
// DELETE FROM user Where id = ?
  • Count count records
counts, err := engine.Count(&user)
// SELECT count(*) AS total FROM user
  • FindAndCount combines function Find with Count which is usually used in query by page
var users []User
counts, err := engine.FindAndCount(&users)
  • Sum sum functions
agesFloat64, err := engine.Sum(&user, "age")
// SELECT sum(age) AS total FROM user

agesInt64, err := engine.SumInt(&user, "age")
// SELECT sum(age) AS total FROM user

sumFloat64Slice, err := engine.Sums(&user, "age", "score")
// SELECT sum(age), sum(score) FROM user

sumInt64Slice, err := engine.SumsInt(&user, "age", "score")
// SELECT sum(age), sum(score) FROM user
  • Query conditions builder
err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users)
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)
  • Multiple operations in one go routine, no transation here but resue session memory
session := engine.NewSession()
defer session.Close()

user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
if _, err := session.Insert(&user1); err != nil {
    return err
}

user2 := Userinfo{Username: "yyy"}
if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {
    return err
}

if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {
    return err
}

return nil
  • Transation should on one go routine. There is transaction and resue session memory
session := engine.NewSession()
defer session.Close()

// add Begin() before any action
if err := session.Begin(); err != nil {
    // if returned then will rollback automatically
    return err
}

user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
if _, err := session.Insert(&user1); err != nil {
    return err
}

user2 := Userinfo{Username: "yyy"}
if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {
    return err
}

if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {
    return err
}

// add Commit() after all actions
return session.Commit()
  • Or you can use Transaction to replace above codes.
res, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) {
    user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
    if _, err := session.Insert(&user1); err != nil {
        return nil, err
    }

    user2 := Userinfo{Username: "yyy"}
    if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {
        return nil, err
    }

    if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {
        return nil, err
    }
    return nil, nil
})
  • Context Cache, if enabled, current query result will be cached on session and be used by next same statement on the same session.
	sess := engine.NewSession()
	defer sess.Close()

	var context = xorm.NewMemoryContextCache()

	var c2 ContextGetStruct
	has, err := sess.ID(1).ContextCache(context).Get(&c2)
	assert.NoError(t, err)
	assert.True(t, has)
	assert.EqualValues(t, 1, c2.Id)
	assert.EqualValues(t, "1", c2.Name)
	sql, args := sess.LastSQL()
	assert.True(t, len(sql) > 0)
	assert.True(t, len(args) > 0)

	var c3 ContextGetStruct
	has, err = sess.ID(1).ContextCache(context).Get(&c3)
	assert.NoError(t, err)
	assert.True(t, has)
	assert.EqualValues(t, 1, c3.Id)
	assert.EqualValues(t, "1", c3.Name)
	sql, args = sess.LastSQL()
	assert.True(t, len(sql) == 0)
	assert.True(t, len(args) == 0)

Contributing

If you want to pull request, please see CONTRIBUTING. And we also provide Xorm on Google Groups to discuss.

Credits

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

Changelog

  • v0.7.0

    • Some bugs fixed
  • v0.6.6

    • Some bugs fixed
  • v0.6.5

    • Postgres schema support
    • vgo support
    • Add FindAndCount
    • Database special params support via NewEngineWithParams
    • Some bugs fixed
  • v0.6.4

    • Automatical Read/Write seperatelly
    • Query/QueryString/QueryInterface and action with Where/And
    • Get support non-struct variables
    • BufferSize on Iterate
    • fix some other bugs.

More changes ...

Cases

LICENSE

BSD License http://creativecommons.org/licenses/BSD/

xorm's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xorm's Issues

建议增加类似qbs的Iterate方法

[杭州]无闻 8:25:14
http://gowalker.org/github.com/coocood/qbs#Qbs_Iterate
[杭州]无闻 8:25:29
xorm有没有这种方法
[杭州]无闻 8:25:35
一次一个读取
[杭州]无闻 8:25:42
不是一次性全部读入内存
无闻说的这个有么?
正雄 21:09:11
Iterate the rows, the first parameter is a struct pointer, the second parameter is a fucntion which will get called on each row, the in do function the structPtr's value will be set to the current row's value.. if do function returns an error, the iteration will be stopped.

读一行 即时调用函数处理 继续一行

现在一个表有万多条记录 想有个类似游标的方法来读数据

http://gowalker.org/github.com/coocood/qbs#Qbs_Iterate

文档链接更新

README_CN.md里面的快速开始链接失效,应该链接到docs/QuickStart.md.

In操作mysql数据库问题

Engine.In("id", "2,3,4,5,6,7,8").Find(&menus)

这样的操作只会返回 id=2的这一条数据,,并不会返回所有的

建议增加一个全局时间切换的开关,UTC时间 local时间

目前各种orm对数据的处理都不规范,没有统一的规定究竟是utc时间为准,还是local时间为准,建议xorm里增加一个时间开关,可以设定究竟当前orm内部时间转换以何种为准.

这样的话,用户就可以根据需求自己自行选择.而不至于每次预期读出的是某时间,发觉实际上却是相差了7 8个小时,还得自己手工减减加加处理一番~

新手请教:刚更新了0.3.1版本,以前正常的程序现在运行期间报错了

刚更新了0.3.1版本,以前是0.2.3,以前正常的程序现在运行期间报错了,写了一个最简单的测试程序也报同样的错误,大家有遇到过吗?请指教,多谢。

最简代码:

type User struct {
    Id       int32
    UserName string
}

func main() {
  var db *xorm.Engine
  var err error
  db, err = xorm.NewEngine("mysql", fmt.Sprintf("%v:%v@tcp(%v:3306)/%v?charset=utf8",dbUser, dbPwd, dbhost, dbName))
  if err != nil {
        fmt.Println(err)
        return
  }
  info := User{}
  _, err = db.Id(1).Get(&info)
  if err != nil {
        fmt.Println(err)
        return
  }
}

运行后报的错误为:

SELECT `User`.`Id`, `User`.`UserName`, `User`.`FullName`, `User`.`Created` FROM `User` WHERE Id=? LIMIT 1
[1]
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x486584]

goroutine 1 [running]:
github.com/lunny/xorm.(*Session).bytes2Value(0xc0800b3000, 0x0, 0xc0800b7300, 0xc080000350, 0x8, ...)
    E:/testGo/src/github.com/lunny/xorm/session.go:1966 +0x124
github.com/lunny/xorm.(*Session).row2Bean(0xc0800b3000, 0xc08007d6c0, 0xc0800b8080, 0x4, 0x4, ...)
    E:/testGo/src/github.com/lunny/xorm/session.go:1637 +0x987
github.com/lunny/xorm.(*Session).Get(0xc0800b3000, 0x5d6920, 0xc08007e7c0, 0xc0800b3000, 0x0, ...)
    E:/testGo/src/github.com/lunny/xorm/session.go:922 +0x4e2
main.main()
    E:/testGo/src/sampleTest/main.go:58 +0x158

goroutine 3 [syscall]:
syscall.Syscall6(0x7746bbc0, 0x5, 0x9c, 0xc08007af00, 0xc080000250, ...)
    C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist417694871/go/src/pkg/runtime/zsyscall_windows_windows_amd64.c:97 +0x55
syscall.GetQueuedCompletionStatus(0x9c, 0xc08007af00, 0xc080000250, 0xc080000248, 0xffffffff, ...)
    C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist417694871/go/src/pkg/syscall/zsyscall_windows_amd64.go:507 +0x9f
net.(*resultSrv).Run(0xc080000240)
    C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist417694871/go/src/pkg/net/fd_windows.go:150 +0x151
created by net.startServer
    C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist417694871/go/src/pkg/net/fd_windows.go:285 +0x10f
错误: 进程退出代码 2.

数据库:mysql 5.1.63
编译环境:windows 7 64位
GO版本:1.1.2

Engine.Update方法有BUG!

thisid, err := Engine.Update(nd, &Node{Id: nid})
thisid的值始终返回1,正确应该返回被更新的字段id.希望尽快修复!

sqlite3 index problem

One of my struct attribute is "Group", and when it create index with group, it will run "CREATE INDEX xxx_group ON xxx (group);", the sqlite3 db report error.

Host is not allowed to connect to this MySQL server时,xorm没有任何提示就退出

os:win7;mysql 5.6;驱动(Go-SQL-Driver/MySQL),xorm均为最新版

今天是第一次开始使用xorm,mysql.dns是"root:123456@tcp(192.168.2.39:3306)/test?charset=utf8",xorm.NewEngine()没有提示错误,代码一运行到engine.Ping()或engine.Sycn()时,程序会没有任何提示就退出.

查了老半天代码没发现问题,最后换自己用"database/sql"创建DB连接时才发现是"192.168.2.39"这个本机ip导致不能连接mysql而引起xorm退出,换"127.0.0.1"就好了.

希望有一个方法可以提示创建的Orm引擎是否可用,而不是调用时没有提示就导致程序退出.

Cache improvements

1.composite primary key support
2.redis cache provider support
3.Cascade support

自定义主键Id()的调用

在表未定义主键之前这个代码是会通过id去更新数据的
eft, err := db.Id(id).Update(a)

在自定义主键后表结构如下
type Article struct {
Id int32 pk INT autoincr
Name string xorm:"VARCHAR(45)"
Img string xorm:"VARCHAR(100)"
Aside string XORM:"VARCHAR(200)"
Desc string XORM:"VARCHAR(200)"
Content string XORM:"TEXT"
Status int8 xorm:"TINYINT(4)"
}

eft, err := db.Id(id).Update(a)中Id(id)是无效的

xorm transfer

xorm命令行工具支持从一个数据库将数据导入到另一个数据库。

NewSimpleConnectPool 关闭异常

测试代码如下:
package main
import _ "github.com/go-sql-driver/mysql"
import "github.com/lunny/xorm"
import "fmt"
const(
dburl="root:123456@tcp(127.0.0.1:3306)/test"
dbdriver="mysql"
)

func main() {
engine,err:= xorm.NewEngine(dbdriver,dburl)
engine.SetPool(xorm.NewSimpleConnectPool())
if err!=nil {
fmt.Println(err)
}
engine.Close()
}

如果去掉
engine.SetPool(xorm.NewSimpleConnectPool())
关闭是没问题的。
运行异常如下:
database/sql.(_DB).Close(0x0, 0xc210036720, 0x0)
/usr/local/go/src/pkg/database/sql/sql.go:456 +0x46f
github.com/lunny/xorm.(_SimpleConnectPool).Close(0xc21004d180, 0xc210037d00, 0x0, 0x0)
/Users/pyc/golearn/go.demos/src/xorm.demos/src/github.com/lunny/xorm/pool.go:264 +0x97
github.com/lunny/xorm.(*Engine).Close(0xc210037d00, 0x659358, 0xc21004d180)
/Users/pyc/golearn/go.demos/src/xorm.demos/src/github.com/lunny/xorm/engine.go:175 +0x38
main.main()
/Users/pyc/golearn/go.demos/src/xorm.demos/test.go:16 +0x208

goroutine 3 [runnable]:
database/sql.(*DB).connectionOpener(0xc210051180)
/usr/local/go/src/pkg/database/sql/sql.go:573
created by database/sql.Open
/usr/local/go/src/pkg/database/sql/sql.go:436 +0x24d

ORM Cascading Proposal

Proposal:

  • new xorm tags for has_one, belongs_to, and has_many relationships
  • new Engine APIs for lazy fetch
  • new xorm tags for specifying eager or lazy fetch, 'lazy', 'eager', 'eager_select'
  • default fetch for has_one is eagerly fetched via join query, can override the default behavior conjunction of 'lazy' tag presence
  • default fetch for has_many is lazy, can override the default behavior with conjunction of 'eager' or 'eager_select' tag, using 'eager' will result join query for fetching has many datas
  • belongs_to is coupled usage with has_many, and default eager fetch

建议增加 每个映射表struct 里面的 Created 跟 Updated 字段 在插入 修改的时候 自动写入到数据库中

建议增加 每个映射表struct 里面的 Created 跟 Updated 字段 在插入 修改的时候 自动写入到数据库中

如 实例中:

// add Begin() before any action
err := session.Begin()  
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
_, err = session.Insert(&user1)
if err != nil {
    session.Rollback()
    return
}

免去 其中

Created: time.Now()

就很不错了

在非编译状态下运行会出现错误,是什么原因造成的?

if err := Engine.Sync(new(User), new(Category), new(Node), new(Topic), new(Reply), new(Kvs), new(File)); err != nil {
    fmt.Println("Database struct sync failed")
    fmt.Println("Engine.Sync ERRORS:", err)

通过go run 运行时:
go run app.go
Starting...
Database struct sync failed
Engine.Sync ERRORS: unable to open database file

Uniform database open params

在保持向前兼容性的同时,修改现有NewEngine接口,允许只提供一个参数。这个参数规则由xorm来制定(可参考sqlchamy),并转换成对应驱动的参数。

sync问题

对model增加一个列,然后sync后,这个列会在数据库中被创建。
问题是:
如果我手动对表增加了一列(这个列增加的是正确的),我做sync,会报错说"duplicate column name:"

如何解决?

建议增加函数式定义表特殊连击神技..

Define(table).PK("id").Col("college1","student1","college2","student2").Type("string").Col("old").Type("int64")

Define(table).PK(id).Str(colLen,f1,f2,f3).Int(colLen, f5, f6).Index(f1, f2).UI(f3,f2)

how to change database?

1.how to change database? but not new engine.
example for:
engine, err := xorm.NewEngine("mysql", "root:@tcp(localhost:3306)/?charset=utf8")
....("USE xx_db") ???

2.i wish add struct tag for table name
var g Group
session.Table("pp_group").Where("id = ?", 8).Get(&g)

3.感觉你这个设计很凌乱。

thanks.

Custom types can not be used in mapped structs

The problem is, that you can't map struct field with type, defined as "alias". If you'll try to run this sample:

import (
    "github.com/lunny/xorm"
    _ "github.com/mattn/go-sqlite3"
)

type MyInt int

type MyStruct struct {
   Type MyInt
   Name string
}

func main() {
   orm, err = xorm.NewEngine("sqlite3", "./int.db")
   orm.CreateTables(&MyStruct{})
   i := MyStruct{Name: "Test", Type: MyInt(1)}
   orm.Insert(&i)
   orm.Get(&i)
}

you'll get reflect panic on Engine.Get call:
panic: reflect.Set: value of type int is not assignable to type MyInt
Same problem with Find.

Problem seems to raise from this line. I guess, that you should call Value.SetInt if kind is reflect.Int and the same for other simple kinds.

建议增加对版本version的支持

update的时候,会自动检测version并且version+1。delete可以不做任何处理的,其次是更新时也把version作为条件,如:
update table set field =[value], fieldversion = fieldversion +1 where id = [id] and fieldversion = [version]

这个只是对单独记录更新,批量更新时有两种情况,
1是不使用版本了,如:
update table set field =[value], fieldversion = fieldversion +1 where field=[fieldvalue]
2是使用版本,这需要可以考虑逐条记录生成sql并执行,如:
update table set field =[value], fieldversion = fieldversion +1 where id = [id] and fieldversion = [version]
update table set field =[value], fieldversion = fieldversion +1 where id = [id] and fieldversion = [version]

xorm dump

xorm命令行支持从数据库生成SQL文件,包括结构和数据。

增加XORM命令行自动化工具

XORM命令行自动化工具(或web或gui,不过命令行相对通用一些):

命令行从数据库获取,从数据库生成Struct.自动生成模型.

可以自动生成 struct,再复制到程序里使用.

一个表一个文件,这样可以自由选取调用

生成路径的话自己指定吧,如果输入了路径,包名就是最后一层目录名,如果没有输入路径,就新建models目录,包名就models吧.

默认根据读取的数据库表名来定,struct名也可以指定.

内容像这样:
package models

import (

"time"

)

type C struct {
A string
B time.Time
}

命令行在加个参数-json,如果有这个参数生成的struct里就加上json:"id"之类

Cant save floats

Trying to save a float64/32 struct field to a MySQL DB always saves a zero-value to db

sqlite3 index recreate error

when I set a struct attribute xorm:index, the index will create every time my programme start, and it will be error after the first created.

加入低层API

简单而高效的database/sql封装,既可以单独使用,同时作为xorm的底层依赖

Engine.Delete方法bug

Engine.Delete方法当条件为全部时无法删除,环境是pgsql9.2 ,其他环境没测.

增加自动读写分离

同时连接两个数据库,建议支持不同类型数据库间主从\双主等方式,如果我读选了sqlite,写选了pgsql,希望这样也可以.

主的允许读写,从的只允许读等等..
可以提高性能,ORM内部自动切换..

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.