use sqlc for database queries
1 file changed, 20 insertions(+), 68 deletions(-)
changed files
M internal/storage/sqlite/reader.go → internal/storage/sqlite/reader.go
@@ -1,62 +1,28 @@ package sqlite import ( + "context" "database/sql" "strings" "time" - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" "alin.ovh/homestead/internal/buffer" "alin.ovh/homestead/internal/storage" + "alin.ovh/homestead/internal/storage/sqlite/db" "alin.ovh/x/log" + "github.com/Southclaws/fault" + "github.com/Southclaws/fault/fmsg" ) type Reader struct { - db *sql.DB log *log.Logger - queries struct { - getFile *sql.Stmt - checkPath *sql.Stmt - } + queries *db.Queries } -func NewReader(db *sql.DB, log *log.Logger) (*Reader, error) { +func NewReader(conn *sql.DB, log *log.Logger) (*Reader, error) { r := &Reader{ - log: log, - db: db, - } - var err error - r.queries.getFile, err = r.db.Prepare(` - SELECT - file.content_type, - file.last_modified, - file.etag, - file.title, - file.style_hash, - content.encoding, - content.body - FROM url - INNER JOIN file - USING (url_id) - INNER JOIN content - USING (file_id) - WHERE - url.path = ? - `) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("preparing select statement")) - } - - r.queries.checkPath, err = r.db.Prepare(` - SELECT EXISTS( - SELECT 1 - FROM url - WHERE path = ? - ) AS differs -`) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("preparing check path statement")) + log: log, + queries: db.New(conn), } return r, nil@@ -66,41 +32,25 @@ func (r *Reader) GetFile(filename string) (*storage.File, error) { file := &storage.File{ Encodings: make(map[string]*buffer.Buffer, 1), } - var unixTime int64 - var encoding string - var content []byte r.log.Debug("querying db for file", "filename", filename) - rows, err := r.queries.getFile.Query(filename) + rows, err := r.queries.GetFile(context.TODO(), filename) if err != nil { return nil, fault.Wrap(err, fmsg.With("querying database")) } - defer rows.Close() count := 0 - for rows.Next() { + for _, row := range rows { count++ - err = rows.Scan( - &file.ContentType, - &unixTime, - &file.Etag, - &file.Title, - &file.StyleHash, - &encoding, - &content, - ) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("querying database")) - } - - file.LastModified = time.Unix(unixTime, 0) - file.Encodings[encoding] = buffer.NewBuffer(content) + file.ContentType = row.File.ContentType + file.LastModified = time.Unix(row.File.LastModified, 0) + file.Etag = row.File.Etag + file.Title = row.File.Title + file.StyleHash = row.File.StyleHash + file.Encodings[row.Content.Encoding] = buffer.NewBuffer(row.Content.Body) } if count == 0 { return nil, nil - } - if err := rows.Err(); err != nil { - return nil, fault.Wrap(err, fmsg.With("error iterating rows")) } return file, nil@@ -116,23 +66,25 @@ cPath, differs = strings.TrimSuffix(path, "index.xml")+"atom.xml", true case strings.HasSuffix(path, "/index.html"): cPath, differs = strings.CutSuffix(path, "index.html") case !strings.HasSuffix(path, "/"): - err := r.queries.checkPath.QueryRow(cPath + "/").Scan(&differs) + d, err := r.queries.CheckPath(context.TODO(), cPath+"/") if err != nil { r.log.Warn("error canonicalising path", "path", path, "error", err) return } + differs = d == 1 if differs { cPath += "/" } case strings.HasSuffix(path, "/"): tmp := strings.TrimSuffix(path, "/") - err := r.queries.checkPath.QueryRow(tmp).Scan(&differs) + d, err := r.queries.CheckPath(context.TODO(), tmp) if err != nil { r.log.Warn("error canonicalising path", "path", path, "error", err) return } + differs = d == 1 if differs { cPath = tmp }