Commit 52adb309 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 306294ae
...@@ -74,8 +74,10 @@ func (r *sqliteRegistry) Close() (err error) { ...@@ -74,8 +74,10 @@ func (r *sqliteRegistry) Close() (err error) {
return r.dbpool.Close() return r.dbpool.Close()
} }
func (r *sqliteRegistry) setup(ctx context.Context) (err error) { // withConn runs f on a dbpool connection.
// XXX dup //
// connection is first allocated from dbpool and put back after call to f.
func (r *sqliteRegistry) withConn(ctx context.Context, f func(*sqlite.Conn) error) error {
conn := r.dbpool.Get(ctx.Done()) conn := r.dbpool.Get(ctx.Done())
if conn == nil { if conn == nil {
// either ctx cancel or dbpool close // either ctx cancel or dbpool close
...@@ -85,50 +87,48 @@ func (r *sqliteRegistry) setup(ctx context.Context) (err error) { ...@@ -85,50 +87,48 @@ func (r *sqliteRegistry) setup(ctx context.Context) (err error) {
return errRegistryDown // db closed return errRegistryDown // db closed
} }
defer r.dbpool.Put(conn) defer r.dbpool.Put(conn)
return f(conn)
}
err = sqliteutil.ExecScript(conn, ` func (r *sqliteRegistry) setup(ctx context.Context) (err error) {
CREATE TABLE IF NOT EXISTS hosts ( return r.withConn(ctx, func(conn *sqlite.Conn) error {
hostname TEXT NON NULL PRIMARY KEY, err := sqliteutil.ExecScript(conn, `
osladdr TEXT NON NULL CREATE TABLE IF NOT EXISTS hosts (
); hostname TEXT NON NULL PRIMARY KEY,
osladdr TEXT NON NULL
CREATE TABLE IF NOT EXISTS meta ( );
name TEXT NON NULL PRIMARY KEY,
value TEXT NON NULL CREATE TABLE IF NOT EXISTS meta (
); name TEXT NON NULL PRIMARY KEY,
`) value TEXT NON NULL
if err != nil { );
return err `)
} if err != nil {
return err
}
// XXX check schemaver // XXX check schemaver
// XXX check network name // XXX check network name
return nil return nil
})
} }
func (r *sqliteRegistry) Announce(ctx context.Context, hostname, osladdr string) (err error) { func (r *sqliteRegistry) Announce(ctx context.Context, hostname, osladdr string) (err error) {
defer r.regerr(&err, "announce", hostname, osladdr) defer r.regerr(&err, "announce", hostname, osladdr)
// XXX dup return r.withConn(ctx, func(conn *sqlite.Conn) error {
conn := r.dbpool.Get(ctx.Done()) err := sqliteutil.Exec(conn,
if conn == nil { "INSERT INTO hosts (hostname, osladdr) VALUES (?, ?)", nil,
// either ctx cancel or dbpool close hostname, osladdr)
if ctx.Err() != nil {
return ctx.Err()
}
return errRegistryDown // db closed
}
defer r.dbpool.Put(conn)
err = sqliteutil.Exec(conn, "INSERT INTO hosts (hostname, osladdr) VALUES (?, ?)", nil, hostname, osladdr) switch sqlite.ErrCode(err) {
case sqlite.SQLITE_CONSTRAINT_UNIQUE: // XXX test
switch sqlite.ErrCode(err) { err = errHostDup
case sqlite.SQLITE_CONSTRAINT_UNIQUE: // XXX test }
err = errHostDup
}
return err return err
})
} }
var errRegDup = errors.New("registry broken: duplicate host entries") var errRegDup = errors.New("registry broken: duplicate host entries")
...@@ -136,34 +136,29 @@ var errRegDup = errors.New("registry broken: duplicate host entries") ...@@ -136,34 +136,29 @@ var errRegDup = errors.New("registry broken: duplicate host entries")
func (r *sqliteRegistry) Query(ctx context.Context, hostname string) (osladdr string, err error) { func (r *sqliteRegistry) Query(ctx context.Context, hostname string) (osladdr string, err error) {
defer r.regerr(&err, "query", hostname) defer r.regerr(&err, "query", hostname)
// XXX dup err = r.withConn(ctx, func(conn *sqlite.Conn) error {
conn := r.dbpool.Get(ctx.Done()) nrow := 0
if conn == nil { err := sqliteutil.Exec(conn, "SELECT osladdr FROM hosts WHERE hostname = ?",
// either ctx cancel or dbpool close func (stmt *sqlite.Stmt) error {
if ctx.Err() != nil { osladdr = stmt.ColumnText(0)
return "", ctx.Err() nrow++
return nil
}, hostname)
if err != nil {
return err
} }
return "", errRegistryDown // db closed
}
defer r.dbpool.Put(conn)
nrow := 0
err = sqliteutil.Exec(conn, "SELECT osladdr FROM hosts WHERE hostname = ?", func (stmt *sqlite.Stmt) error {
osladdr = stmt.ColumnText(0)
nrow++
return nil
}, hostname)
if err != nil { if nrow == 0 {
return "", err return errNoHost
} } else if nrow > 1 {
// hostname is PK - we should not get several results
osladdr = ""
return errRegDup
}
if nrow == 0 { return nil
return "", errNoHost })
} else if nrow > 1 {
// hostname is PK - we should not get several results
return "", errRegDup
}
return osladdr, err return osladdr, err
} }
......
...@@ -42,7 +42,7 @@ func TestRegistrySQLite(t *testing.T) { ...@@ -42,7 +42,7 @@ func TestRegistrySQLite(t *testing.T) {
r, err := openRegistrySQLite(ctx, dbpath) r, err := openRegistrySQLite(ctx, dbpath)
X(err) X(err)
// quert checks that result of Query(hostname) is as expect // query checks that result of Query(hostname) is as expected.
// //
// if expect is error - it checks that Query returns error with cause == expect. // if expect is error - it checks that Query returns error with cause == expect.
// otherwise expect must be string and it will check that Query // otherwise expect must be string and it will check that Query
...@@ -54,7 +54,7 @@ func TestRegistrySQLite(t *testing.T) { ...@@ -54,7 +54,7 @@ func TestRegistrySQLite(t *testing.T) {
osladdr, err := r.Query(ctx, hostname) osladdr, err := r.Query(ctx, hostname)
if ewant, iserr := expect.(error); iserr { if ewant, iserr := expect.(error); iserr {
// error expected // error expected
// XXX construct full registry error around ewant + reflect.DeepCompare // XXX construct full registry error around ewant + reflect.DeepCompare?
e, ok := err.(*registryError) e, ok := err.(*registryError)
if !(ok && e.Err == ewant && osladdr == "") { if !(ok && e.Err == ewant && osladdr == "") {
t.Fatalf("%s: query %q:\nwant: \"\", %v\nhave: %q, %v", t.Fatalf("%s: query %q:\nwant: \"\", %v\nhave: %q, %v",
...@@ -70,7 +70,7 @@ func TestRegistrySQLite(t *testing.T) { ...@@ -70,7 +70,7 @@ func TestRegistrySQLite(t *testing.T) {
} }
} }
// announce checks that result of Announce(hostname, osladdr) is as expected // announce checks that result of Announce(hostname, osladdr) is as expected.
// //
// if len(errv) == 1 - it checks that Announce returns error with cause == errv[0]. // if len(errv) == 1 - it checks that Announce returns error with cause == errv[0].
// otherwise it will check that Announce succeeds and returns nil error. // otherwise it will check that Announce succeeds and returns nil error.
...@@ -86,7 +86,7 @@ func TestRegistrySQLite(t *testing.T) { ...@@ -86,7 +86,7 @@ func TestRegistrySQLite(t *testing.T) {
} }
if ewant != nil { if ewant != nil {
// error expected // error expected
// XXX construct full registry error around ewant + reflect.DeepCompare // XXX construct full registry error around ewant + reflect.DeepCompare?
e, ok := err.(*registryError) e, ok := err.(*registryError)
if (!ok && e.Err == ewant) { if (!ok && e.Err == ewant) {
t.Fatalf("%s: announce %q %q:\nwant %v\nhave: %v", t.Fatalf("%s: announce %q %q:\nwant %v\nhave: %v",
...@@ -128,5 +128,9 @@ func TestRegistrySQLite(t *testing.T) { ...@@ -128,5 +128,9 @@ func TestRegistrySQLite(t *testing.T) {
announce(r, "γ", "gamma:qqq", errRegistryDown) announce(r, "γ", "gamma:qqq", errRegistryDown)
query(r, "γ", errRegistryDown) query(r, "γ", errRegistryDown)
query(r2, "α", "alpha:1234")
X(r2.Close()) X(r2.Close())
query(r2, "α", errRegistryDown)
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment