Commit d4509066 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 52adb309
...@@ -90,6 +90,32 @@ func (r *sqliteRegistry) withConn(ctx context.Context, f func(*sqlite.Conn) erro ...@@ -90,6 +90,32 @@ func (r *sqliteRegistry) withConn(ctx context.Context, f func(*sqlite.Conn) erro
return f(conn) return f(conn)
} }
var errNoRows = errors.New("query1: empty result")
var errManyRows = errors.New("query1: multiple results")
// query1 is like sqliteutil.Exec but checks that exactly 1 row is returned.
//
// if query results in no rows - errNoRows is returned.
// if query results in more than 1 row - errManyRows is returned.
func query1(conn *sqlite.Conn, query string, resultf func(stmt *sqlite.Stmt), argv ...interface{}) error {
nrow := 0
err := sqliteutil.Exec(conn, query, func(stmt *sqlite.Stmt) error {
if nrow == 1 {
return errManyRows
}
nrow++
resultf(stmt)
return nil
}, argv...)
if err != nil {
return err
}
if nrow == 0 {
return errNoRows
}
return nil
}
func (r *sqliteRegistry) setup(ctx context.Context) (err error) { func (r *sqliteRegistry) setup(ctx context.Context) (err error) {
return r.withConn(ctx, func(conn *sqlite.Conn) error { return r.withConn(ctx, func(conn *sqlite.Conn) error {
err := sqliteutil.ExecScript(conn, ` err := sqliteutil.ExecScript(conn, `
...@@ -137,33 +163,28 @@ func (r *sqliteRegistry) Query(ctx context.Context, hostname string) (osladdr st ...@@ -137,33 +163,28 @@ func (r *sqliteRegistry) Query(ctx context.Context, hostname string) (osladdr st
defer r.regerr(&err, "query", hostname) defer r.regerr(&err, "query", hostname)
err = r.withConn(ctx, func(conn *sqlite.Conn) error { err = r.withConn(ctx, func(conn *sqlite.Conn) error {
nrow := 0 err := query1(conn, "SELECT osladdr FROM hosts WHERE hostname = ?",
err := sqliteutil.Exec(conn, "SELECT osladdr FROM hosts WHERE hostname = ?", func (stmt *sqlite.Stmt) {
func (stmt *sqlite.Stmt) error {
osladdr = stmt.ColumnText(0) osladdr = stmt.ColumnText(0)
nrow++
return nil
}, hostname) }, hostname)
if err != nil { switch err {
return err case errNoRows:
}
if nrow == 0 {
return errNoHost return errNoHost
} else if nrow > 1 {
case errManyRows:
// hostname is PK - we should not get several results // hostname is PK - we should not get several results
osladdr = "" osladdr = ""
return errRegDup return errRegDup
} }
return nil return err
}) })
return osladdr, err return osladdr, err
} }
// regerr is syntatic sugar to wrap !nil *errp into registryError. // regerr is syntactic sugar to wrap !nil *errp into registryError.
func (r *sqliteRegistry) regerr(errp *error, op string, args ...interface{}) { func (r *sqliteRegistry) regerr(errp *error, op string, args ...interface{}) {
if *errp == nil { if *errp == nil {
return return
......
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