update schema, use new Hibiki
This commit is contained in:
parent
f1fde99d40
commit
fd326df5e5
14
METANOIA.go
14
METANOIA.go
|
@ -282,7 +282,21 @@ func main() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
dbGcTicker := time.NewTicker(15 * time.Minute)
|
||||
go func() {
|
||||
for range dbGcTicker.C {
|
||||
for printDb.RunGarbageCollection() == nil {
|
||||
|
||||
}
|
||||
}
|
||||
}()
|
||||
defer printDb.Close()
|
||||
defer func() {
|
||||
for printDb.RunGarbageCollection() == nil {
|
||||
|
||||
}
|
||||
}()
|
||||
defer dbGcTicker.Stop()
|
||||
|
||||
//TODO: check if mutex is correct!
|
||||
printStrategy = panako.NewStrategy(printDb, true)
|
||||
|
|
126
database/artist.go
Normal file
126
database/artist.go
Normal file
|
@ -0,0 +1,126 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type Artist struct {
|
||||
DatabaseType
|
||||
id int64
|
||||
metadata []byte
|
||||
}
|
||||
|
||||
func InsertArtistToDatabase(db *Database, names map[string]string) *Artist {
|
||||
|
||||
//TODO: do it in single tx
|
||||
|
||||
rows, err := db.Query("INSERT INTO artist DEFAULT VALUES RETURNING id;")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer rows.Close()
|
||||
rows.Next()
|
||||
var id int64
|
||||
err = rows.Scan(&id)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
artist := GetArtistFromDatabase(db, id)
|
||||
if artist == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for k, n := range names {
|
||||
artist.AddName(k, n)
|
||||
}
|
||||
|
||||
return artist
|
||||
}
|
||||
|
||||
func GetArtistsFromDatabaseByName(db *Database, name string) (artists []*Artist) {
|
||||
rows, err := db.Query("SELECT id, metadata FROM artists WHERE id IN(SELECT artist FROM artists_names WHERE name ILIKE $1);", name)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
artist, err := GetArtistFromRow(db, rows)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
artists = append(artists, artist)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetArtistFromDatabase(db *Database, id int64) *Artist {
|
||||
rows, err := db.Query("SELECT id, metadata FROM artists WHERE id = $1;", id)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer rows.Close()
|
||||
rows.Next()
|
||||
r, err := GetArtistFromRow(db, rows)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func GetArtistFromRow(db *Database, row *sql.Rows) (*Artist, error) {
|
||||
r := &Artist{
|
||||
DatabaseType: DatabaseType{
|
||||
db: db,
|
||||
},
|
||||
}
|
||||
err := row.Scan(&r.id, &r.metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (r *Artist) GetId() int64 {
|
||||
return r.id
|
||||
}
|
||||
|
||||
func (r *Artist) GetNames() map[string]string {
|
||||
|
||||
result := make(map[string]string)
|
||||
|
||||
rows, err := r.db.Query("SELECT kind, name FROM artists_names WHERE id $1;", r.id)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var kind string
|
||||
var name string
|
||||
err = rows.Scan(&kind, &name)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
result[kind] = name
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *Artist) RemoveName(kind string) {
|
||||
r.db.Exec("DELETE FROM artists_names WHERE id = $1 AND kind = $2;", r.id, kind)
|
||||
}
|
||||
|
||||
func (r *Artist) AddName(kind, name string) {
|
||||
r.db.Exec("INSERT INTO artists_names (artist, kind, name) VALUES ($1, $2, $3) ON CONFLICT (artist, kind) DO UPDATE SET name = $3;", r.id, kind, name)
|
||||
}
|
||||
|
||||
func (r *Artist) GetMetadata() (result map[string]interface{}) {
|
||||
json.Unmarshal(r.metadata, &result)
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *Artist) SetMetadata(value map[string]interface{}) {
|
||||
r.metadata, _ = json.Marshal(value)
|
||||
r.db.Exec("UPDATE artists SET metadata = $2::jsonb WHERE id = $1;", r.id, r.metadata)
|
||||
}
|
|
@ -41,7 +41,7 @@ func GetReleasesFromDatabaseByIdentifier(db *Database, identifier string) (relea
|
|||
}
|
||||
releases = append(releases, release)
|
||||
}
|
||||
return releases
|
||||
return
|
||||
}
|
||||
|
||||
func GetReleaseFromDatabase(db *Database, id int64) *Release {
|
||||
|
@ -71,26 +71,26 @@ func GetReleaseFromRow(db *Database, row *sql.Rows) (*Release, error) {
|
|||
return r, nil
|
||||
}
|
||||
|
||||
func (r Release) GetId() int64 {
|
||||
func (r *Release) GetId() int64 {
|
||||
return r.id
|
||||
}
|
||||
|
||||
func (r Release) GetIdentifiers() []string {
|
||||
func (r *Release) GetIdentifiers() []string {
|
||||
return r.identifiers
|
||||
}
|
||||
|
||||
func (r Release) SetIdentifiers(identifiers []string) {
|
||||
func (r *Release) SetIdentifiers(identifiers []string) {
|
||||
r.identifiers = identifiers
|
||||
|
||||
r.db.Exec("UPDATE releases SET identifiers = $2 WHERE id = $1;", r.id, pq.Array(r.identifiers))
|
||||
}
|
||||
|
||||
func (r Release) GetMetadata() (result map[string]interface{}) {
|
||||
func (r *Release) GetMetadata() (result map[string]interface{}) {
|
||||
json.Unmarshal(r.metadata, &result)
|
||||
return result
|
||||
}
|
||||
|
||||
func (r Release) SetMetadata(value map[string]interface{}) {
|
||||
func (r *Release) SetMetadata(value map[string]interface{}) {
|
||||
r.metadata, _ = json.Marshal(value)
|
||||
r.db.Exec("UPDATE releases SET metadata = $2::jsonb WHERE id = $1;", r.id, r.metadata)
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ func (r *Resource) GetReleases() (releases []*Release) {
|
|||
}
|
||||
releases = append(releases, release)
|
||||
}
|
||||
return releases
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Resource) AddRelease(release *Release) {
|
||||
|
|
4
go.mod
4
go.mod
|
@ -3,7 +3,7 @@ module git.gammaspectra.live/S.O.N.G/METANOIA
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
git.gammaspectra.live/S.O.N.G/Hibiki v0.0.0-20220130030711-030193fa3726
|
||||
git.gammaspectra.live/S.O.N.G/Hibiki v0.0.0-20220130170252-8689f79eb0cd
|
||||
github.com/dhowden/tag v0.0.0-20201120070457-d52dcb253c63
|
||||
github.com/ipfs/go-cid v0.1.0
|
||||
github.com/lib/pq v1.10.4
|
||||
|
@ -13,7 +13,7 @@ require (
|
|||
|
||||
require (
|
||||
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220130003320-c9b07c6bec7a // indirect
|
||||
git.gammaspectra.live/S.O.N.G/goborator v0.0.0-20220130014715-837c1db0113a // indirect
|
||||
git.gammaspectra.live/S.O.N.G/goborator v0.0.0-20220130143007-b0d46ec375ac // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cocoonlife/goflac v0.0.0-20170210142907-50ea06ed5a9d // indirect
|
||||
|
|
8
go.sum
8
go.sum
|
@ -1,10 +1,10 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
git.gammaspectra.live/S.O.N.G/Hibiki v0.0.0-20220130030711-030193fa3726 h1:Sobaj0pXvyKKS+CLHG0HLoNF6ye1lmcqt4U5tCOdqfM=
|
||||
git.gammaspectra.live/S.O.N.G/Hibiki v0.0.0-20220130030711-030193fa3726/go.mod h1:N46fIbI6SZ/VHdSf/aAWBl02UkdOdTJ3xtXvy7BdzyQ=
|
||||
git.gammaspectra.live/S.O.N.G/Hibiki v0.0.0-20220130170252-8689f79eb0cd h1:3xlFX6pwteLvMMJE7XW5fqPG+mu2slPvkYwcxeZLpos=
|
||||
git.gammaspectra.live/S.O.N.G/Hibiki v0.0.0-20220130170252-8689f79eb0cd/go.mod h1:o1NqDI9/1EwqL0FPHKOrZmQSeRXnzVBLJPxdpwrNqHM=
|
||||
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220130003320-c9b07c6bec7a h1:LxrTp9gf4w5KnFHRPFLXYfoxC58GCSEmZrHI6Ogtrm0=
|
||||
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220130003320-c9b07c6bec7a/go.mod h1:vkoHSHVM9p6vAUmXAik0gvaLcIfiQYrD6bQqVpOulUk=
|
||||
git.gammaspectra.live/S.O.N.G/goborator v0.0.0-20220130014715-837c1db0113a h1:xVEXo4qTGZK/6O0KVvoPH9XTdGbUQfb7jP/itO8kykk=
|
||||
git.gammaspectra.live/S.O.N.G/goborator v0.0.0-20220130014715-837c1db0113a/go.mod h1:ySjuueqe5HUqvf7lWS51Cy5UP2tgJWsezOv8UIm2arA=
|
||||
git.gammaspectra.live/S.O.N.G/goborator v0.0.0-20220130143007-b0d46ec375ac h1:UcWeLjW7963Cpd4cB7TOn5OZPl73goxQ5WhIFO0DIdU=
|
||||
git.gammaspectra.live/S.O.N.G/goborator v0.0.0-20220130143007-b0d46ec375ac/go.mod h1:ySjuueqe5HUqvf7lWS51Cy5UP2tgJWsezOv8UIm2arA=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
|
|
50
schema.sql
50
schema.sql
|
@ -2,7 +2,8 @@ CREATE EXTENSION IF NOT EXISTS hstore;
|
|||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
CREATE EXTENSION IF NOT EXISTS btree_gin;
|
||||
|
||||
CREATE TYPE artist_kind AS ENUM ('main', 'performer', 'composer', 'arranger');
|
||||
CREATE TYPE name_kind AS ENUM ('main', 'original', 'romaji', 'kanji', 'english');
|
||||
CREATE TYPE artist_kind AS ENUM ('main', 'original', 'performer', 'composer', 'arranger');
|
||||
|
||||
|
||||
-- groups resources in specific releases / groupings
|
||||
|
@ -12,7 +13,7 @@ CREATE TABLE releases (
|
|||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
CREATE INDEX idx_releases_identifiers_gin ON releases USING GIN (identifiers);
|
||||
CREATE INDEX idx_releases_identifiers_gin ON releases USING GIN (identifiers) INCLUDE (id);
|
||||
|
||||
CREATE TABLE resources (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
|
@ -24,7 +25,7 @@ CREATE TABLE resources (
|
|||
|
||||
CREATE INDEX idx_resources_hash ON resources USING BTREE (hash); -- TODO: check if you can do partial prefix queries
|
||||
CREATE INDEX idx_resources_path ON resources USING BTREE (path);
|
||||
CREATE INDEX idx_resources_path_gin ON resources USING GIN (path); -- Allows for partial path queries
|
||||
CREATE INDEX idx_resources_path_gin ON resources USING GIN (path gin_trgm_ops); -- Allows for partial path queries
|
||||
|
||||
CREATE TABLE resource_alternate_identifiers (
|
||||
resource BIGINT NOT NULL,
|
||||
|
@ -51,36 +52,46 @@ CREATE INDEX idx_resource_releases_release ON resource_releases USING BTREE (rel
|
|||
|
||||
CREATE TABLE albums (
|
||||
id SERIAL PRIMARY KEY,
|
||||
main_name TEXT NOT NULL,
|
||||
cover BIGINT, -- can be null if not available
|
||||
names hstore NOT NULL, -- key -> value where keys are language / kinds
|
||||
identifiers TEXT[] NOT NULL DEFAULT '{}'::TEXT[], -- array of "semi-unique" identifiers, like catalog number
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
|
||||
CONSTRAINT fk_cover FOREIGN KEY (cover) REFERENCES resources(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_albums_main_name ON albums USING BTREE (main_name);
|
||||
CREATE INDEX idx_albums_names_gin ON albums USING GIN (names);
|
||||
CREATE INDEX idx_albums_identifiers_gin ON albums USING GIN (identifiers);
|
||||
|
||||
|
||||
CREATE TABLE albums_names (
|
||||
album INTEGER NOT NULL,
|
||||
kind name_kind NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
CONSTRAINT idx_albums_names UNIQUE (album, kind),
|
||||
CONSTRAINT fk_album FOREIGN KEY (album) REFERENCES albums(id)
|
||||
);
|
||||
CREATE INDEX idx_albums_names_album ON albums_names USING BTREE (album);
|
||||
CREATE INDEX idx_albums_names_name_gin ON albums_names USING GIN (name gin_trgm_ops) INCLUDE (album);
|
||||
|
||||
|
||||
CREATE TABLE artists (
|
||||
id SERIAL PRIMARY KEY,
|
||||
main_name TEXT NOT NULL,
|
||||
names hstore NOT NULL, -- key -> value where keys are language / kinds
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
CREATE INDEX idx_artists_main_name ON artists USING BTREE (main_name);
|
||||
CREATE INDEX idx_artists_names_gin ON artists USING GIN (names);
|
||||
CREATE TABLE artists_names (
|
||||
artist INTEGER NOT NULL,
|
||||
kind name_kind NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
CONSTRAINT idx_artists_names UNIQUE (artist, kind),
|
||||
CONSTRAINT fk_artist FOREIGN KEY (artist) REFERENCES artists(id)
|
||||
);
|
||||
CREATE INDEX idx_artists_names_artist ON artists_names USING BTREE (artist);
|
||||
CREATE INDEX idx_artists_names_name_gin ON artists_names USING GIN (name gin_trgm_ops) INCLUDE (artist);
|
||||
|
||||
CREATE TABLE songs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
resource BIGINT NOT NULL,
|
||||
cover BIGINT, -- set to override album cover. can be null if not available
|
||||
album INTEGER, -- can be null
|
||||
main_name TEXT NOT NULL,
|
||||
names hstore NOT NULL, -- key -> value where keys are language / kinds
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
|
||||
CONSTRAINT fk_resource FOREIGN KEY (resource) REFERENCES resources(id),
|
||||
|
@ -89,9 +100,16 @@ CREATE TABLE songs (
|
|||
);
|
||||
CREATE INDEX idx_songs_resource ON songs USING BTREE (resource);
|
||||
CREATE INDEX idx_songs_album ON songs USING BTREE (album);
|
||||
CREATE INDEX idx_songs_main_name ON songs USING BTREE (main_name);
|
||||
CREATE INDEX idx_songs_names_gin ON albums USING GIN (names);
|
||||
|
||||
CREATE TABLE songs_names (
|
||||
song INTEGER NOT NULL,
|
||||
kind name_kind NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
CONSTRAINT idx_songs_names UNIQUE (song, kind),
|
||||
CONSTRAINT fk_song FOREIGN KEY (song) REFERENCES songs(id)
|
||||
);
|
||||
CREATE INDEX idx_songs_names_song ON songs_names USING BTREE (song);
|
||||
CREATE INDEX idx_songs_names_name_gin ON songs_names USING GIN (name gin_trgm_ops) INCLUDE (song);
|
||||
|
||||
-- extra mapping table of artists <-> song
|
||||
CREATE TABLE album_artists (
|
||||
|
|
Loading…
Reference in a new issue