// dbImageGet gets an ImageBaseInfo object from the database. // The argument fingerprint will be queried with a LIKE query, means you can // pass a shortform and will get the full fingerprint. // There can never be more than one image with a given fingerprint, as it is // enforced by a UNIQUE constraint in the schema. func dbImageGet(db *sql.DB, fingerprint string, public bool, strictMatching bool) (int, *shared.ImageInfo, error) { var err error var create, expire, used, upload *time.Time // These hold the db-returned times // The object we'll actually return image := shared.ImageInfo{} id := -1 arch := -1 // These two humongous things will be filled by the call to DbQueryRowScan outfmt := []interface{}{&id, &image.Fingerprint, &image.Filename, &image.Size, &image.Cached, &image.Public, &image.AutoUpdate, &arch, &create, &expire, &used, &upload} var query string var inargs []interface{} if strictMatching { inargs = []interface{}{fingerprint} query = ` SELECT id, fingerprint, filename, size, cached, public, auto_update, architecture, creation_date, expiry_date, last_use_date, upload_date FROM images WHERE fingerprint = ?` } else { inargs = []interface{}{fingerprint + "%"} query = ` SELECT id, fingerprint, filename, size, cached, public, auto_update, architecture, creation_date, expiry_date, last_use_date, upload_date FROM images WHERE fingerprint LIKE ?` } if public { query = query + " AND public=1" } err = dbQueryRowScan(db, query, inargs, outfmt) if err != nil { return -1, nil, err // Likely: there are no rows for this fingerprint } // Some of the dates can be nil in the DB, let's process them. if create != nil { image.CreationDate = *create } else { image.CreationDate = time.Time{} } if expire != nil { image.ExpiryDate = *expire } else { image.ExpiryDate = time.Time{} } if used != nil { image.LastUsedDate = *used } else { image.LastUsedDate = time.Time{} } image.Architecture, _ = shared.ArchitectureName(arch) // The upload date is enforced by NOT NULL in the schema, so it can never be nil. image.UploadDate = *upload // Get the properties q := "SELECT key, value FROM images_properties where image_id=?" var key, value, name, desc string inargs = []interface{}{id} outfmt = []interface{}{key, value} results, err := dbQueryScan(db, q, inargs, outfmt) if err != nil { return -1, nil, err } properties := map[string]string{} for _, r := range results { key = r[0].(string) value = r[1].(string) properties[key] = value } image.Properties = properties // Get the aliases q = "SELECT name, description FROM images_aliases WHERE image_id=?" inargs = []interface{}{id} outfmt = []interface{}{name, desc} results, err = dbQueryScan(db, q, inargs, outfmt) if err != nil { return -1, nil, err } aliases := []shared.ImageAlias{} for _, r := range results { name = r[0].(string) desc = r[0].(string) a := shared.ImageAlias{Name: name, Description: desc} aliases = append(aliases, a) } image.Aliases = aliases _, source, err := dbImageSourceGet(db, id) if err == nil { image.Source = &source } return id, &image, nil }