diff options
author | Paul Duncan <pabs@pablotron.org> | 2022-02-05 02:37:00 -0500 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2022-02-05 02:37:00 -0500 |
commit | 22fd269069b8e47bc40fbd8681243bdd4bd61a47 (patch) | |
tree | e16bbe17d985d1d567f83926fd1b7a417948083a /internal/dbstore/dbstore.go | |
parent | 56cc399430d127cb628b3abe84bc653d2b0ce59b (diff) | |
download | cvez-22fd269069b8e47bc40fbd8681243bdd4bd61a47.tar.bz2 cvez-22fd269069b8e47bc40fbd8681243bdd4bd61a47.zip |
mv internal/dbstore dbstore
Diffstat (limited to 'internal/dbstore/dbstore.go')
-rw-r--r-- | internal/dbstore/dbstore.go | 255 |
1 files changed, 0 insertions, 255 deletions
diff --git a/internal/dbstore/dbstore.go b/internal/dbstore/dbstore.go deleted file mode 100644 index 4df9fb9..0000000 --- a/internal/dbstore/dbstore.go +++ /dev/null @@ -1,255 +0,0 @@ -// database storage -package dbstore - -import ( - "context" - db_sql "database/sql" - "embed" - "encoding/json" - "fmt" - _ "github.com/mattn/go-sqlite3" - "github.com/pablotron/cvez/cpedict" -) - -//go:embed sql -var sqlFs embed.FS - -type DbStore struct { - db *db_sql.DB -} - -// open database -func Open(path string) (DbStore, error) { - var r DbStore - // init db - if db, err := db_sql.Open("sqlite3", path); err != nil { - return r, err - } else { - r.db = db - return r, nil - } -} - -// initialized database version -const initDbVersion = 314159 - -func (me DbStore) isInitialized(ctx context.Context) (bool, error) { - sql := "PRAGMA user_version;" - // get version - var version int32 - if err := me.db.QueryRowContext(ctx, sql).Scan(&version); err != nil { - return false, err - } - - // return result - return (version == initDbVersion), nil -} - -// initialize database -func (me DbStore) Init(ctx context.Context) error { - if inited, err := me.isInitialized(ctx); err != nil { - return err - } else if inited { - // already initialized, return success - return nil - } - - // read init query - sql, err := sqlFs.ReadFile("sql/init.sql") - if err != nil { - return err - } - - // exec init query, return result - _, err = me.db.ExecContext(ctx, string(sql)) - return err -} - -// get single query from embedded filesystem -func getQuery(id string) (string, error) { - // read query - if data, err := sqlFs.ReadFile(fmt.Sprintf("sql/%s.sql", id)); err != nil { - return "", err - } else { - // return query - return string(data), nil - } -} - -// return query map -func getQueries(ids []string) (map[string]string, error) { - r := make(map[string]string) - - for _, id := range(ids) { - // read query - if sql, err := getQuery(id); err != nil { - return r, fmt.Errorf("%s: %s", id, err.Error()) - } else { - // save query - r[id] = sql - } - } - - // return success - return r, nil -} - -// import CPE dictionary -func (me DbStore) AddCpeDictionary(ctx context.Context, dict cpedict.Dictionary) error { - // lazy-init db - if err := me.Init(ctx); err != nil { - return err - } - - // build query map - queryIds := []string { "insert-cpe", "insert-title", "insert-ref" } - queries, err := getQueries(queryIds) - if err != nil { - return err - } - - // begin context - tx, err := me.db.BeginTx(ctx, nil) - if err != nil { - return err - } - - // build statements - sts := make(map[string]*db_sql.Stmt) - for id, sql := range(queries) { - if st, err := tx.PrepareContext(ctx, sql); err != nil { - return err - } else { - sts[id] = st - defer sts[id].Close() - } - } - - // add items - for _, item := range(dict.Items) { - // add cpe - rs, err := sts["insert-cpe"].ExecContext(ctx, item.CpeUri, item.Cpe23Item.Name) - if err != nil { - return err - } - - // get last row ID - id, err := rs.LastInsertId() - if err != nil { - return err - } - - // add titles - for _, title := range(item.Titles) { - _, err := sts["insert-title"].ExecContext(ctx, id, title.Lang, title.Text) - if err != nil { - return err - } - } - - // add refs - for _, ref := range(item.References) { - _, err := sts["insert-ref"].ExecContext(ctx, id, ref.Href, ref.Text) - if err != nil { - return err - } - } - } - - // commit changes, return result - return tx.Commit() -} - -//go:generate stringer -linecomment -type=CpeSearchType - -// CPE search type -type CpeSearchType byte - -const ( - CpeSearchAll CpeSearchType = iota //cpe-search-all - CpeSearchTitle // cpe-search-title - CpeSearchRef // cpe-search-ref -) - -// title search result -type CpeSearchRow struct { - // Database CPE ID - CpeId int64 `json:"cpe_id"` - - // v2.3 formatting string - Cpe23 string `json:"cpe23"` - - // titles - Titles []cpedict.Title `json:"titles"` - - // references - Refs []cpedict.Reference `json:"refs"` - - // search result rank - Rank float32 `json:"rank"` -} - -// search CPEs -func (me DbStore) CpeSearch( - ctx context.Context, - searchType CpeSearchType, - s string, -) ([]CpeSearchRow, error) { - var r []CpeSearchRow - - // lazy-init db - if err := me.Init(ctx); err != nil { - return r, err - } - - // get query - sql, err := getQuery(searchType.String()) - if err != nil { - return r, err - } - - // exec search query - rows, err := me.db.QueryContext(ctx, sql, db_sql.Named("q", s)) - if err != nil { - return r, err - } - - // walk results - for rows.Next() { - var sr CpeSearchRow - var titles string - var refs string - - // get row values - err = rows.Scan(&sr.CpeId, &sr.Cpe23, &titles, &refs, &sr.Rank) - if err != nil { - return r, err - } - - // unmarshal titles - if err = json.Unmarshal([]byte(titles), &sr.Titles); err != nil { - return r, err - } - - // unmarshal refs - if err = json.Unmarshal([]byte(refs), &sr.Refs); err != nil { - return r, err - } - - // append to results - r = append(r, sr) - } - - // close rows - if err = rows.Close(); err != nil { - return r, err - } - - // check for iteration errors - if err = rows.Err(); err != nil { - return r, err - } - - // return success - return r, nil -} |