Skip to content

Commit b360b44

Browse files
committed
Adding support for PostgreSQL as database
This adds support for a second database backend: PostgreSQL (in addition to sqlite3). This allows externailzing the database used by gonic.
1 parent 5e3b8da commit b360b44

File tree

10 files changed

+95
-31
lines changed

10 files changed

+95
-31
lines changed

cmd/gonic/gonic.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"time"
1717

1818
"github.com/google/shlex"
19+
_ "github.com/jinzhu/gorm/dialects/postgres"
1920
_ "github.com/jinzhu/gorm/dialects/sqlite"
2021
"github.com/oklog/run"
2122
"github.com/peterbourgon/ff"
@@ -47,7 +48,12 @@ func main() {
4748

4849
confPlaylistsPath := set.String("playlists-path", "", "path to your list of new or existing m3u playlists that gonic can manage")
4950

50-
confDBPath := set.String("db-path", "gonic.db", "path to database (optional)")
51+
confSqlitePath := set.String("db-path", "gonic.db", "path to database (optional, default: gonic.db)")
52+
confPostgresHost := set.String("postgres-host", "", "name of the PostgreSQL gonicServer (optional)")
53+
confPostgresPort := set.Int("postgres-port", 5432, "port to use for PostgreSQL connection (optional, default: 5432)")
54+
confPostgresName := set.String("postgres-db", "gonic", "name of the PostgreSQL database (optional, default: gonic)")
55+
confPostgresUser := set.String("postgres-user", "gonic", "name of the PostgreSQL user (optional, default: gonic)")
56+
confPostgresSslModel := set.String("postgres-ssl-mode", "verify-full", "the ssl mode used for connecting to the PostreSQL instance (optional, default: verify-full)")
5157

5258
confScanIntervalMins := set.Int("scan-interval", 0, "interval (in minutes) to automatically scan music (optional)")
5359
confScanAtStart := set.Bool("scan-at-start-enabled", false, "whether to perform an initial scan at startup (optional)")
@@ -113,7 +119,12 @@ func main() {
113119
log.Fatalf("couldn't create covers cache path: %v\n", err)
114120
}
115121

116-
dbc, err := db.New(*confDBPath, db.DefaultOptions())
122+
var dbc *db.DB
123+
if len(*confPostgresHost) > 0 {
124+
dbc, err = db.NewPostgres(*confPostgresHost, *confPostgresPort, *confPostgresName, *confPostgresUser, os.Getenv("GONIC_POSTGRES_PW"), *confPostgresSslModel)
125+
} else {
126+
dbc, err = db.NewSqlite3(*confSqlitePath, db.DefaultOptions())
127+
}
117128
if err != nil {
118129
log.Fatalf("error opening database: %v\n", err)
119130
}

db/db.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type DB struct {
3434
*gorm.DB
3535
}
3636

37-
func New(path string, options url.Values) (*DB, error) {
37+
func NewSqlite3(path string, options url.Values) (*DB, error) {
3838
// https://github.com/mattn/go-sqlite3#connection-string
3939
url := url.URL{
4040
Scheme: "file",
@@ -45,13 +45,26 @@ func New(path string, options url.Values) (*DB, error) {
4545
if err != nil {
4646
return nil, fmt.Errorf("with gorm: %w", err)
4747
}
48+
return newDB(db)
49+
}
50+
51+
func NewPostgres(host string, port int, databaseName string, username string, password string, sslmode string) (*DB, error) {
52+
pathAndArgs := fmt.Sprintf("host=%s port=%d user=%s dbname=%s password=%s sslmode=%s", host, port, username, databaseName, password, sslmode)
53+
db, err := gorm.Open("postgres", pathAndArgs)
54+
if err != nil {
55+
return nil, fmt.Errorf("with gorm: %w", err)
56+
}
57+
return newDB(db)
58+
}
59+
60+
func newDB(db *gorm.DB) (*DB, error) {
4861
db.SetLogger(log.New(os.Stdout, "gorm ", 0))
4962
db.DB().SetMaxOpenConns(1)
5063
return &DB{DB: db}, nil
5164
}
5265

5366
func NewMock() (*DB, error) {
54-
return New(":memory:", mockOptions())
67+
return NewSqlite3(":memory:", mockOptions())
5568
}
5669

5770
func (db *DB) GetSetting(key string) (string, error) {
@@ -80,10 +93,11 @@ func (db *DB) InsertBulkLeftMany(table string, head []string, left int, col []in
8093
rows = append(rows, "(?, ?)")
8194
values = append(values, left, c)
8295
}
83-
q := fmt.Sprintf("INSERT OR IGNORE INTO %q (%s) VALUES %s",
96+
q := fmt.Sprintf("INSERT INTO %q (%s) VALUES %s ON CONFLICT (%s) DO NOTHING",
8497
table,
8598
strings.Join(head, ", "),
8699
strings.Join(rows, ", "),
100+
strings.Join(head, ", "),
87101
)
88102
return db.Exec(q, values...).Error
89103
}

db/migrations.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,15 @@ func construct(ctx MigrationContext, id string, f func(*gorm.DB, MigrationContex
8282
func migrateInitSchema(tx *gorm.DB, _ MigrationContext) error {
8383
return tx.AutoMigrate(
8484
Genre{},
85+
Artist{},
86+
Album{},
87+
Track{},
8588
TrackGenre{},
8689
AlbumGenre{},
87-
Track{},
88-
Artist{},
8990
User{},
9091
Setting{},
9192
Play{},
92-
Album{},
93+
Playlist{},
9394
PlayQueue{},
9495
).
9596
Error
@@ -155,12 +156,18 @@ func migrateAddGenre(tx *gorm.DB, _ MigrationContext) error {
155156

156157
func migrateUpdateTranscodePrefIDX(tx *gorm.DB, _ MigrationContext) error {
157158
var hasIDX int
158-
tx.
159-
Select("1").
160-
Table("sqlite_master").
161-
Where("type = ?", "index").
162-
Where("name = ?", "idx_user_id_client").
163-
Count(&hasIDX)
159+
if tx.Dialect().GetName() == "sqlite3" {
160+
tx.Select("1").
161+
Table("sqlite_master").
162+
Where("type = ?", "index").
163+
Where("name = ?", "idx_user_id_client").
164+
Count(&hasIDX)
165+
} else if tx.Dialect().GetName() == "postgres" {
166+
tx.Select("1").
167+
Table("pg_indexes").
168+
Where("indexname = ?", "idx_user_id_client").
169+
Count(&hasIDX)
170+
}
164171
if hasIDX == 1 {
165172
// index already exists
166173
return nil
@@ -437,9 +444,15 @@ func migratePlaylistsQueuesToFullID(tx *gorm.DB, _ MigrationContext) error {
437444
if err := step.Error; err != nil {
438445
return fmt.Errorf("step migrate play_queues to full id: %w", err)
439446
}
440-
step = tx.Exec(`
447+
if tx.Dialect().GetName() == "postgres" {
448+
step = tx.Exec(`
449+
UPDATE play_queues SET newcurrent=('tr-' || current)::varchar[200];
450+
`)
451+
} else {
452+
step = tx.Exec(`
441453
UPDATE play_queues SET newcurrent=('tr-' || CAST(current AS varchar(10)));
442454
`)
455+
}
443456
if err := step.Error; err != nil {
444457
return fmt.Errorf("step migrate play_queues to full id: %w", err)
445458
}

go.sum

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
cloud.google.com/go v0.33.1 h1:fmJQWZ1w9PGkHR1YL/P7HloDvqlmKQ4Vpb7PC2e+aCk=
12
cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3+
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
24
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
35
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
46
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
@@ -12,6 +14,8 @@ github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJs
1214
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
1315
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
1416
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
17+
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
18+
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
1519
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
1620
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1721
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -42,11 +46,15 @@ github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/e
4246
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
4347
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
4448
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
49+
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
4550
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
4651
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
4752
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
53+
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
4854
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
4955
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
56+
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
57+
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
5058
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
5159
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
5260
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
@@ -84,7 +92,9 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
8492
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
8593
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
8694
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
95+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
8796
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
97+
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
8898
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
8999
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
90100
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -104,6 +114,7 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp
104114
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
105115
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
106116
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
117+
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
107118
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
108119
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
109120
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
@@ -128,6 +139,7 @@ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
128139
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
129140
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
130141
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
142+
github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
131143
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
132144
github.com/peterbourgon/ff v1.7.1 h1:xt1lxTG+Nr2+tFtysY7abFgPoH3Lug8CwYJMOmJRXhk=
133145
github.com/peterbourgon/ff v1.7.1/go.mod h1:fYI5YA+3RDqQRExmFbHnBjEeWzh9TrS8rnRpEq7XIg0=
@@ -137,17 +149,22 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
137149
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
138150
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ=
139151
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q=
152+
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
140153
github.com/sentriz/gormstore v0.0.0-20220105134332-64e31f7f6981 h1:sLILANWN76ja66/K4k/mBqJuCjDZaM67w+Ru6rEB0s0=
141154
github.com/sentriz/gormstore v0.0.0-20220105134332-64e31f7f6981/go.mod h1:Rx8XB1ck+so+41uu9VY1gMKs1CPQ2NTq0pzf+OCCQHo=
155+
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
142156
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
143157
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
158+
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
144159
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
145160
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
146161
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
147162
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
148163
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
149164
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
150165
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
166+
github.com/urfave/cli v1.22.3 h1:FpNT6zq26xNpHZy08emi755QwzLPs6Pukqjlc7RfOMU=
167+
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
151168
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
152169
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
153170
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -162,6 +179,7 @@ golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+o
162179
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
163180
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
164181
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
182+
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
165183
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
166184
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
167185
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -174,6 +192,7 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
174192
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
175193
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
176194
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
195+
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
177196
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
178197
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
179198
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -188,6 +207,7 @@ golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
188207
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
189208
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
190209
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
210+
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
191211
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
192212
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
193213
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -198,8 +218,10 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
198218
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
199219
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
200220
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
221+
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
201222
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
202223
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
224+
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
203225
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
204226
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
205227
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

mockfs/mockfs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ func (m *MockFS) DumpDB(suffix ...string) {
292292
p = append(p, suffix...)
293293

294294
destPath := filepath.Join(os.TempDir(), strings.Join(p, "-"))
295-
dest, err := db.New(destPath, url.Values{})
295+
dest, err := db.NewSqlite3(destPath, url.Values{})
296296
if err != nil {
297297
m.t.Fatalf("create dest db: %v", err)
298298
}

scanner/scanner_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ func TestMultiFolderWithSharedArtist(t *testing.T) {
411411

412412
sq := func(db *gorm.DB) *gorm.DB {
413413
return db.
414-
Select("*, count(sub.id) child_count, sum(sub.length) duration").
414+
Select("albums.*, count(sub.id) child_count, sum(sub.length) duration").
415415
Joins("LEFT JOIN tracks sub ON albums.id=sub.album_id").
416416
Group("albums.id")
417417
}

server/ctrlsubsonic/handlers_by_folder.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ func (c *Controller) ServeGetIndexes(r *http.Request) *spec.Response {
3131
}
3232
var folders []*db.Album
3333
c.DB.
34-
Select("*, count(sub.id) child_count").
34+
Select("albums.*, count(sub.id) child_count").
3535
Preload("AlbumStar", "user_id=?", user.ID).
3636
Preload("AlbumRating", "user_id=?", user.ID).
3737
Joins("LEFT JOIN albums sub ON albums.id=sub.parent_id").
3838
Where("albums.parent_id IN ?", rootQ.SubQuery()).
3939
Group("albums.id").
40-
Order("albums.right_path COLLATE NOCASE").
40+
Order("albums.right_path").
4141
Find(&folders)
4242
// [a-z#] -> 27
4343
indexMap := make(map[string]*spec.Index, 27)
@@ -80,7 +80,7 @@ func (c *Controller) ServeGetMusicDirectory(r *http.Request) *spec.Response {
8080
Where("parent_id=?", id.Value).
8181
Preload("AlbumStar", "user_id=?", user.ID).
8282
Preload("AlbumRating", "user_id=?", user.ID).
83-
Order("albums.right_path COLLATE NOCASE").
83+
Order("albums.right_path").
8484
Find(&childFolders)
8585
for _, ch := range childFolders {
8686
childrenObj = append(childrenObj, spec.NewTCAlbumByFolder(ch))

server/ctrlsubsonic/handlers_by_tags.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ func (c *Controller) ServeGetArtists(r *http.Request) *spec.Response {
2323
user := r.Context().Value(CtxUser).(*db.User)
2424
var artists []*db.Artist
2525
q := c.DB.
26-
Select("*, count(sub.id) album_count").
26+
Select("artists.*, count(sub.id) album_count").
2727
Joins("LEFT JOIN albums sub ON artists.id=sub.tag_artist_id").
2828
Preload("ArtistStar", "user_id=?", user.ID).
2929
Preload("ArtistRating", "user_id=?", user.ID).
3030
Group("artists.id").
31-
Order("artists.name COLLATE NOCASE")
31+
Order("artists.name")
3232
if m := getMusicFolder(c.MusicPaths, params); m != "" {
3333
q = q.Where("sub.root_dir=?", m)
3434
}
@@ -67,7 +67,7 @@ func (c *Controller) ServeGetArtist(r *http.Request) *spec.Response {
6767
c.DB.
6868
Preload("Albums", func(db *gorm.DB) *gorm.DB {
6969
return db.
70-
Select("*, count(sub.id) child_count, sum(sub.length) duration").
70+
Select("albums.*, count(sub.id) child_count, sum(sub.length) duration").
7171
Joins("LEFT JOIN tracks sub ON albums.id=sub.album_id").
7272
Preload("AlbumStar", "user_id=?", user.ID).
7373
Preload("AlbumRating", "user_id=?", user.ID).
@@ -98,6 +98,7 @@ func (c *Controller) ServeGetAlbum(r *http.Request) *spec.Response {
9898
err = c.DB.
9999
Select("albums.*, count(tracks.id) child_count, sum(tracks.length) duration").
100100
Joins("LEFT JOIN tracks ON tracks.album_id=albums.id").
101+
Group("albums.id").
101102
Preload("TagArtist").
102103
Preload("Genres").
103104
Preload("Tracks", func(db *gorm.DB) *gorm.DB {
@@ -162,14 +163,14 @@ func (c *Controller) ServeGetAlbumListTwo(r *http.Request) *spec.Response {
162163
case "frequent":
163164
user := r.Context().Value(CtxUser).(*db.User)
164165
q = q.Joins("JOIN plays ON albums.id=plays.album_id AND plays.user_id=?", user.ID)
165-
q = q.Order("plays.count DESC")
166+
q = q.Order("SUM(plays.count) DESC")
166167
case "newest":
167168
q = q.Order("created_at DESC")
168169
case "random":
169170
q = q.Order(gorm.Expr("random()"))
170171
case "recent":
171172
q = q.Joins("JOIN plays ON albums.id=plays.album_id AND plays.user_id=?", user.ID)
172-
q = q.Order("plays.time DESC")
173+
q = q.Order("MAX(plays.time) DESC")
173174
case "starred":
174175
q = q.Joins("JOIN album_stars ON albums.id=album_stars.album_id AND album_stars.user_id=?", user.ID)
175176
q = q.Order("tag_title")
@@ -217,7 +218,7 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response {
217218
// search artists
218219
var artists []*db.Artist
219220
q := c.DB.
220-
Select("*, count(albums.id) album_count").
221+
Select("artists.*, count(albums.id) album_count").
221222
Group("artists.id").
222223
Where("name LIKE ? OR name_u_dec LIKE ?", query, query).
223224
Joins("JOIN albums ON albums.tag_artist_id=artists.id").

0 commit comments

Comments
 (0)