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

.

parent 306294ae
......@@ -74,8 +74,10 @@ func (r *sqliteRegistry) Close() (err error) {
return r.dbpool.Close()
}
func (r *sqliteRegistry) setup(ctx context.Context) (err error) {
// XXX dup
// withConn runs f on a dbpool connection.
//
// 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())
if conn == nil {
// either ctx cancel or dbpool close
......@@ -85,50 +87,48 @@ func (r *sqliteRegistry) setup(ctx context.Context) (err error) {
return errRegistryDown // db closed
}
defer r.dbpool.Put(conn)
return f(conn)
}
err = sqliteutil.ExecScript(conn, `
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
);
`)
if err != nil {
return err
}
func (r *sqliteRegistry) setup(ctx context.Context) (err error) {
return r.withConn(ctx, func(conn *sqlite.Conn) error {
err := sqliteutil.ExecScript(conn, `
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
);
`)
if err != nil {
return err
}
// XXX check schemaver
// XXX check network name
// XXX check schemaver
// XXX check network name
return nil
return nil
})
}
func (r *sqliteRegistry) Announce(ctx context.Context, hostname, osladdr string) (err error) {
defer r.regerr(&err, "announce", hostname, osladdr)
// XXX dup
conn := r.dbpool.Get(ctx.Done())
if conn == nil {
// either ctx cancel or dbpool close
if ctx.Err() != nil {
return ctx.Err()
}
return errRegistryDown // db closed
}
defer r.dbpool.Put(conn)
return r.withConn(ctx, func(conn *sqlite.Conn) error {
err := sqliteutil.Exec(conn,
"INSERT INTO hosts (hostname, osladdr) VALUES (?, ?)", nil,
hostname, osladdr)
err = sqliteutil.Exec(conn, "INSERT INTO hosts (hostname, osladdr) VALUES (?, ?)", nil, hostname, osladdr)
switch sqlite.ErrCode(err) {
case sqlite.SQLITE_CONSTRAINT_UNIQUE: // XXX test
err = errHostDup
}
switch sqlite.ErrCode(err) {
case sqlite.SQLITE_CONSTRAINT_UNIQUE: // XXX test
err = errHostDup
}
return err
return err
})
}
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) {
defer r.regerr(&err, "query", hostname)
// XXX dup
conn := r.dbpool.Get(ctx.Done())
if conn == nil {
// either ctx cancel or dbpool close
if ctx.Err() != nil {
return "", ctx.Err()
err = r.withConn(ctx, func(conn *sqlite.Conn) error {
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 {
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 {
return "", err
}
if nrow == 0 {
return errNoHost
} else if nrow > 1 {
// hostname is PK - we should not get several results
osladdr = ""
return errRegDup
}
if nrow == 0 {
return "", errNoHost
} else if nrow > 1 {
// hostname is PK - we should not get several results
return "", errRegDup
}
return nil
})
return osladdr, err
}
......
......@@ -42,7 +42,7 @@ func TestRegistrySQLite(t *testing.T) {
r, err := openRegistrySQLite(ctx, dbpath)
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.
// otherwise expect must be string and it will check that Query
......@@ -54,7 +54,7 @@ func TestRegistrySQLite(t *testing.T) {
osladdr, err := r.Query(ctx, hostname)
if ewant, iserr := expect.(error); iserr {
// error expected
// XXX construct full registry error around ewant + reflect.DeepCompare
// XXX construct full registry error around ewant + reflect.DeepCompare?
e, ok := err.(*registryError)
if !(ok && e.Err == ewant && osladdr == "") {
t.Fatalf("%s: query %q:\nwant: \"\", %v\nhave: %q, %v",
......@@ -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].
// otherwise it will check that Announce succeeds and returns nil error.
......@@ -86,7 +86,7 @@ func TestRegistrySQLite(t *testing.T) {
}
if ewant != nil {
// error expected
// XXX construct full registry error around ewant + reflect.DeepCompare
// XXX construct full registry error around ewant + reflect.DeepCompare?
e, ok := err.(*registryError)
if (!ok && e.Err == ewant) {
t.Fatalf("%s: announce %q %q:\nwant %v\nhave: %v",
......@@ -128,5 +128,9 @@ func TestRegistrySQLite(t *testing.T) {
announce(r, "γ", "gamma:qqq", errRegistryDown)
query(r, "γ", errRegistryDown)
query(r2, "α", "alpha:1234")
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