good morning!!!!

Skip to content
Snippets Groups Projects
Commit e7146459 authored by José Carlos Nieto's avatar José Carlos Nieto
Browse files

Update ql with latest transaction changes.

parent c77c62e8
No related branches found
No related tags found
No related merge requests found
...@@ -25,8 +25,8 @@ import ( ...@@ -25,8 +25,8 @@ import (
"database/sql" "database/sql"
"upper.io/db.v2" "upper.io/db.v2"
"upper.io/db.v2/sqlbuilder"
"upper.io/db.v2/internal/sqladapter" "upper.io/db.v2/internal/sqladapter"
"upper.io/db.v2/sqlbuilder"
) )
// table is the actual implementation of a collection. // table is the actual implementation of a collection.
...@@ -63,7 +63,7 @@ func (r *resultProxy) Select(fields ...interface{}) db.Result { ...@@ -63,7 +63,7 @@ func (r *resultProxy) Select(fields ...interface{}) db.Result {
var columns []struct { var columns []struct {
Name string `db:"Name"` Name string `db:"Name"`
} }
err := r.t.d.Builder.Select("Name"). err := r.t.d.Select("Name").
From("__Column"). From("__Column").
Where("TableName", r.t.Name()). Where("TableName", r.t.Name()).
Iterator().All(&columns) Iterator().All(&columns)
......
...@@ -24,29 +24,23 @@ package ql ...@@ -24,29 +24,23 @@ package ql
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"sync"
"sync/atomic" "sync/atomic"
_ "github.com/cznic/ql/driver" // QL driver _ "github.com/cznic/ql/driver" // QL driver
"upper.io/db.v2" "upper.io/db.v2"
"upper.io/db.v2/internal/sqladapter"
"upper.io/db.v2/sqlbuilder" "upper.io/db.v2/sqlbuilder"
"upper.io/db.v2/sqlbuilder/exql" "upper.io/db.v2/sqlbuilder/exql"
"upper.io/db.v2/internal/sqladapter"
) )
// Database represents a SQL database.
type Database interface {
db.Database
builder.Builder
NewTransaction() (Tx, error)
}
// database is the actual implementation of Database // database is the actual implementation of Database
type database struct { type database struct {
sqladapter.BaseDatabase // Leveraged by sqladapter sqladapter.BaseDatabase // Leveraged by sqladapter
builder.Builder db.SQLBuilder
connURL db.ConnectionURL connURL db.ConnectionURL
txMu sync.Mutex
} }
var ( var (
...@@ -56,8 +50,7 @@ var ( ...@@ -56,8 +50,7 @@ var (
) )
var ( var (
_ = sqladapter.Database(&database{}) _ = db.SQLDatabase(&database{})
_ = db.Database(&database{})
) )
// newDatabase binds *database with sqladapter and the SQL builer. // newDatabase binds *database with sqladapter and the SQL builer.
...@@ -69,7 +62,7 @@ func newDatabase(settings db.ConnectionURL) (*database, error) { ...@@ -69,7 +62,7 @@ func newDatabase(settings db.ConnectionURL) (*database, error) {
} }
// Open stablishes a new connection to a SQL server. // Open stablishes a new connection to a SQL server.
func Open(settings db.ConnectionURL) (Database, error) { func Open(settings db.ConnectionURL) (db.SQLDatabase, error) {
d, err := newDatabase(settings) d, err := newDatabase(settings)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -93,7 +86,7 @@ func (d *database) ConnectionURL() db.ConnectionURL { ...@@ -93,7 +86,7 @@ func (d *database) ConnectionURL() db.ConnectionURL {
return d.connURL return d.connURL
} }
// Open attempts to open a connection to the database server. // Open stablishes a new connection with the SQL server.
func (d *database) Open(connURL db.ConnectionURL) error { func (d *database) Open(connURL db.ConnectionURL) error {
if connURL == nil { if connURL == nil {
return db.ErrMissingConnURL return db.ErrMissingConnURL
...@@ -102,18 +95,66 @@ func (d *database) Open(connURL db.ConnectionURL) error { ...@@ -102,18 +95,66 @@ func (d *database) Open(connURL db.ConnectionURL) error {
return d.open() return d.open()
} }
// NewTransaction starts a transaction block. // NewTx returns a transaction session.
func (d *database) NewTransaction() (Tx, error) { func NewTx(sqlTx *sql.Tx) (db.SQLTx, error) {
d, err := newDatabase(nil)
if err != nil {
return nil, err
}
// Binding with sqladapter's logic.
d.BaseDatabase = sqladapter.NewBaseDatabase(d)
// Binding with builder.
b, err := builder.New(d.BaseDatabase, template)
if err != nil {
return nil, err
}
d.SQLBuilder = b
if err := d.BaseDatabase.BindTx(sqlTx); err != nil {
return nil, err
}
newTx := sqladapter.NewTx(d)
return &tx{DatabaseTx: newTx}, nil
}
// New wraps the given *sql.DB session and creates a new db session.
func New(sess *sql.DB) (db.SQLDatabase, error) {
d, err := newDatabase(nil)
if err != nil {
return nil, err
}
// Binding with sqladapter's logic.
d.BaseDatabase = sqladapter.NewBaseDatabase(d)
// Binding with builder.
b, err := builder.New(d.BaseDatabase, template)
if err != nil {
return nil, err
}
d.SQLBuilder = b
if err := d.BaseDatabase.BindSession(sess); err != nil {
return nil, err
}
return d, nil
}
// NewTx starts a transaction block.
func (d *database) NewTx() (db.SQLTx, error) {
nTx, err := d.NewLocalTransaction() nTx, err := d.NewLocalTransaction()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &tx{Tx: nTx}, nil return &tx{DatabaseTx: nTx}, nil
} }
// Collections returns a list of non-system tables from the database. // Collections returns a list of non-system tables from the database.
func (d *database) Collections() (collections []string, err error) { func (d *database) Collections() (collections []string, err error) {
q := d.Builder.Select("Name"). q := d.Select("Name").
From("__Table") From("__Table")
iter := q.Iterator() iter := q.Iterator()
...@@ -139,7 +180,7 @@ func (d *database) open() error { ...@@ -139,7 +180,7 @@ func (d *database) open() error {
if err != nil { if err != nil {
return err return err
} }
d.Builder = b d.SQLBuilder = b
openFn := func() error { openFn := func() error {
openFiles := atomic.LoadInt32(&fileOpenCount) openFiles := atomic.LoadInt32(&fileOpenCount)
...@@ -195,7 +236,7 @@ func (d *database) Err(err error) error { ...@@ -195,7 +236,7 @@ func (d *database) Err(err error) error {
// StatementExec wraps the statement to execute around a transaction. // StatementExec wraps the statement to execute around a transaction.
func (d *database) StatementExec(stmt *sql.Stmt, args ...interface{}) (sql.Result, error) { func (d *database) StatementExec(stmt *sql.Stmt, args ...interface{}) (sql.Result, error) {
if d.BaseDatabase.Tx() == nil { if d.BaseDatabase.Transaction() == nil {
var tx *sql.Tx var tx *sql.Tx
var res sql.Result var res sql.Result
var err error var err error
...@@ -224,13 +265,22 @@ func (d *database) NewLocalCollection(name string) db.Collection { ...@@ -224,13 +265,22 @@ func (d *database) NewLocalCollection(name string) db.Collection {
return newTable(d, name) return newTable(d, name)
} }
// Tx creates a transaction and passes it to the given function, if if the
// function returns no error then the transaction is commited.
func (d *database) Tx(fn func(tx db.SQLTx) error) error {
return sqladapter.RunTx(d, fn)
}
// NewLocalTransaction allows sqladapter start a transaction block. // NewLocalTransaction allows sqladapter start a transaction block.
func (d *database) NewLocalTransaction() (sqladapter.Tx, error) { func (d *database) NewLocalTransaction() (sqladapter.DatabaseTx, error) {
clone, err := d.clone() clone, err := d.clone()
if err != nil { if err != nil {
return nil, err return nil, err
} }
clone.txMu.Lock()
defer clone.txMu.Unlock()
openFn := func() error { openFn := func() error {
sqlTx, err := clone.BaseDatabase.Session().Begin() sqlTx, err := clone.BaseDatabase.Session().Begin()
if err == nil { if err == nil {
...@@ -258,7 +308,7 @@ func (d *database) FindDatabaseName() (string, error) { ...@@ -258,7 +308,7 @@ func (d *database) FindDatabaseName() (string, error) {
// TableExists allows sqladapter check whether a table exists and returns an // TableExists allows sqladapter check whether a table exists and returns an
// error in case it doesn't. // error in case it doesn't.
func (d *database) TableExists(name string) error { func (d *database) TableExists(name string) error {
q := d.Builder.Select("Name"). q := d.SQLBuilder.Select("Name").
From("__Table"). From("__Table").
Where("Name == ?", name) Where("Name == ?", name)
......
...@@ -31,5 +31,9 @@ const sqlDriver = `ql` ...@@ -31,5 +31,9 @@ const sqlDriver = `ql`
const Adapter = sqlDriver const Adapter = sqlDriver
func init() { func init() {
db.Register(Adapter, &database{}) db.RegisterSQLAdapter(Adapter, &db.SQLAdapterFuncMap{
New: New,
NewTx: NewTx,
Open: Open,
})
} }
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
) )
func TestTemplateSelect(t *testing.T) { func TestTemplateSelect(t *testing.T) {
b := builder.NewBuilderWithTemplate(template) b := builder.NewSQLBuilder(template)
assert := assert.New(t) assert := assert.New(t)
assert.Equal( assert.Equal(
...@@ -147,7 +147,7 @@ func TestTemplateSelect(t *testing.T) { ...@@ -147,7 +147,7 @@ func TestTemplateSelect(t *testing.T) {
} }
func TestTemplateInsert(t *testing.T) { func TestTemplateInsert(t *testing.T) {
b := builder.NewBuilderWithTemplate(template) b := builder.NewSQLBuilder(template)
assert := assert.New(t) assert := assert.New(t)
assert.Equal( assert.Equal(
...@@ -189,7 +189,7 @@ func TestTemplateInsert(t *testing.T) { ...@@ -189,7 +189,7 @@ func TestTemplateInsert(t *testing.T) {
} }
func TestTemplateUpdate(t *testing.T) { func TestTemplateUpdate(t *testing.T) {
b := builder.NewBuilderWithTemplate(template) b := builder.NewSQLBuilder(template)
assert := assert.New(t) assert := assert.New(t)
assert.Equal( assert.Equal(
...@@ -231,7 +231,7 @@ func TestTemplateUpdate(t *testing.T) { ...@@ -231,7 +231,7 @@ func TestTemplateUpdate(t *testing.T) {
} }
func TestTemplateDelete(t *testing.T) { func TestTemplateDelete(t *testing.T) {
b := builder.NewBuilderWithTemplate(template) b := builder.NewSQLBuilder(template)
assert := assert.New(t) assert := assert.New(t)
assert.Equal( assert.Equal(
......
...@@ -26,22 +26,10 @@ import ( ...@@ -26,22 +26,10 @@ import (
"upper.io/db.v2/internal/sqladapter" "upper.io/db.v2/internal/sqladapter"
) )
// Tx represents a transaction.
type Tx interface {
Database
Commit() error
Rollback() error
}
type tx struct { type tx struct {
sqladapter.Tx sqladapter.DatabaseTx
} }
var ( var (
_ = db.Tx(&tx{}) _ = db.SQLTx(&tx{})
) )
func (t *tx) NewTransaction() (Tx, error) {
return t, db.ErrAlreadyWithinTransaction
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment