naoina / genmai Goto Github PK
View Code? Open in Web Editor NEWSimple, better and easy-to-use ORM library for Golang
License: MIT License
Simple, better and easy-to-use ORM library for Golang
License: MIT License
type Test {
Reference string `db:"unique" column:"reference"`
Starts time.Time `column:"starts"`
Ends time.Time `column:"ends"`
}
The above stores fine but upon querying I get:
ERROR: sql: Scan error on column index 2: unsupported Scan, storing driver.Value type []uint8 into type *time.Time
When call genmei.DB.Select() after genmai.DB.Begin(), it cause SEGV inside SQLite.
In transaction, SQLiteStmt.Close() is called before SQLiteRows.Columns(). It hurts sqlite3_stmt of prepared statement, then fail to get columns names.
If remove defer stmt.Close()
in genmai.DB.query(), the fault is no longer occur. But I think it is not a correct fix.
Here is a reproduction code.
package main
import (
"github.com/naoina/genmai"
// _ "github.com/go-sql-driver/mysql"
"database/sql"
_ "github.com/mattn/go-sqlite3"
"log"
"os"
"runtime"
)
type Sample struct {
Id int64 `db:"pk"`
Name string
}
func prepare(db *genmai.DB) {
if err := db.CreateTable(&Sample{}); err != nil {
log.Panic(err)
}
sampleData := [...]Sample{
{1, "foo"},
{2, "bar"},
{3, "baz"},
{4, "hoo"},
}
db.Insert(sampleData[:])
}
type Rollback struct {
error
}
func (er Rollback) Error() string {
return "Rollback is required."
}
func doTransact(db *genmai.DB, fn func(*genmai.DB) error) (ter error) {
log.Print("Begin transaction")
err := db.Begin()
if err != nil {
log.Print(err)
return err
}
defer func() {
e := recover()
if e != nil {
db.Rollback()
if e2, ok := e.(error); ok {
if _, ok = e2.(Rollback); !ok {
ter = e2
}
}
} else {
db.Commit()
}
}()
err = fn(db)
if err != nil {
log.Print(err)
}
return err
}
func byGenmai(db *genmai.DB) error {
var r []Sample
err := db.Select(&r, db.Where("id", "=", 2))
if err != nil {
panic(err)
}
r[0].Name = "piyo"
_, err = db.Update(r[0])
if err != nil {
panic(err)
}
return nil
}
func byGoSQL(db *sql.DB) {
tx, _ := db.Begin()
var r Sample
stmt, err := tx.Prepare("SELECT * from sample WHERE id = (?)")
if err != nil {
tx.Rollback()
return
}
if rows, err := stmt.Query(2); err != nil {
tx.Rollback()
return
} else {
defer rows.Close()
cl, _ := rows.Columns()
log.Print(cl)
for rows.Next() {
rows.Scan(&(r.Id), &(r.Name))
break
}
}
r.Name = "hoge"
if stmt, err := tx.Prepare("UPDATE sample SET name = ? where id = ?"); err != nil {
tx.Rollback()
return
} else {
stmt.Exec(r.Name, r.Id)
}
tx.Commit()
}
func main() {
db, err := genmai.New(&genmai.SQLite3Dialect{}, ":memory:")
// db, err := genmai.New(&genmai.MySQLDialect{}, "someone:pass@(localhost:3306)/test")
if err != nil {
return
}
db.SetLogOutput(os.Stdout)
func() {
prepare(db)
defer db.DropTable(&Sample{})
byGoSQL(db.DB()) // It work well.
}()
func() {
prepare(db)
defer db.DropTable(&Sample{})
byGenmai(db) // It work well too.
}()
func() {
prepare(db)
defer db.DropTable(&Sample{})
doTransact(db, byGenmai) // It cause SEGV inside of SQLite.
}()
}
this project is cool, but it has bug everywhere!
I tried two function with Mysql, it has two bugs. i fixed one.
diff --git a/genmai.go b/genmai.go
index 0a2b972..19226c8 100644
--- a/genmai.go
+++ b/genmai.go
@@ -906,7 +906,7 @@ func (db *DB) defaultFromTag(field *reflect.StructField) (string, error) {
}
return fmt.Sprintf("DEFAULT %v", db.dialect.FormatBool(b)), nil
}
- return fmt.Sprintf("DEFAULT %v", def), nil
+ return fmt.Sprintf("DEFAULT '%v'", def), nil
}
then I try insert,
testing.tRunner.func1(0xc420112690)
/usr/local/go/src/testing/testing.go:742 +0x29d
panic(0x6d4b40, 0x8a2370)
/usr/local/go/src/runtime/panic.go:505 +0x229
github.com/naoina/genmai.(*DB).Insert(0x0, 0x6a9140, 0xc420102140, 0x0, 0x0, 0x0)
/home/liang/dev/src/github.com/naoina/genmai/genmai.go:368 +0x395
_/home/liang/workspace/codeLanguages/go/basic.Insert()
/home/liang/workspace/codeLanguages/go/basic/mysql.go:44 +0x80
_/home/liang/workspace/codeLanguages/go.TestInsert(0xc420112690)
/home/liang/workspace/codeLanguages/go/main_test.go:59 +0x20
testing.tRunner(0xc420112690, 0x735b88)
/usr/local/go/src/testing/testing.go:777 +0xd0
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:824 +0x2e0
exit status 2
FAIL _/home/liang/workspace/codeLanguages/go 0.092s
so still in maintaining ?
will the before or after hook method be called if the insert occours from some other connection but the present connection is still open.
package main
import (
"fmt"
_ "github.com/mattn/go-sqlite3"
"time"
// _ "github.com/go-sql-driver/mysql"
// _ "github.com/lib/pq"
"github.com/naoina/genmai"
)
type Book struct {
Id int `db: column:"id,key,auto"`
Title string `db: column:"title"`
Author string `db: column:"author"`
Published time.Time `db: column:"published"`
}
func main() {
db, err := genmai.New(&genmai.SQLite3Dialect{}, "gen.db")
// err = db.CreateTable(&Book{})
fmt.Println(err)
var book = &Book{
Title: "date right Hobbit",
Author: "time.Time for Date",
Published: time.Date(2020, 10, 13, 0, 0, 0, 0, time.UTC),
}
n, err := db.Insert(book)
if err != nil {
panic(err)
}
fmt.Printf("inserted rows: %d\n", n)
}
Id int db: column:"id,key,auto"
not implemnt autoincrement
It's really easy to use, but the reflection is really slow.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.