diff --git a/.gitignore b/.gitignore index e0f5045..1575361 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ notes web/node_modules/ +web/dist/ diff --git a/cmd/cmd.go b/cmd/cmd.go index 7e15b34..6c20330 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -2,9 +2,12 @@ package cmd import ( "reichard.io/imagini/routes" + "reichard.io/imagini/db" + "github.com/urfave/cli/v2" "net/http" "log" + "fmt" ) var CmdServe = cli.Command{ @@ -14,6 +17,13 @@ var CmdServe = cli.Command{ Action: serveWeb, } +var CmdDBTest = cli.Command{ + Name: "db", + Aliases: []string{"d"}, + Usage: "test db.", + Action: testDatabase, +} + func serveWeb(ctx *cli.Context) error { routes.RegisterRoutes() @@ -22,3 +32,9 @@ func serveWeb(ctx *cli.Context) error { } return nil } + +func testDatabase(ctx *cli.Context) error { + resp := db.ItemsFromAlbum(1, 3) + fmt.Printf("%v", resp) + return nil +} diff --git a/db/imagini.db b/db/imagini.db new file mode 100644 index 0000000..5b8aafa Binary files /dev/null and b/db/imagini.db differ diff --git a/db/schemas/imagini.db.bak b/db/schemas/imagini.db.bak new file mode 100644 index 0000000..5b8aafa Binary files /dev/null and b/db/schemas/imagini.db.bak differ diff --git a/db/schemas/sqlite-create.sql b/db/schemas/sqlite-create.sql new file mode 100644 index 0000000..c958876 --- /dev/null +++ b/db/schemas/sqlite-create.sql @@ -0,0 +1,53 @@ +CREATE TABLE IF NOT EXISTS [ServerSettings] ( + [settingID] INTEGER PRIMARY KEY, + [name] TEXT NOT NULL, + [description] TEXT NOT NULL, + [value] TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS [Users] ( + [userID] INTEGER PRIMARY KEY, + [name] TEXT NOT NULL, + [email] TEXT, + [authType] TEXT NOT NULL, + [salt] TEXT, + [hashedPWSalt] TEXT +); + +CREATE TABLE IF NOT EXISTS [MediaItems] ( + [mediaID] INTEGER PRIMARY KEY, + [userID] INTEGER NOT NULL, + [EXIFDate] TEXT NOT NULL, + [uploadDate] TEXT NOT NULL, + [latitude] TEXT, + [longitude] TEXT, + [mediaType] INTEGER, /* 0 = Photo, 1 = Video */ + [relPath] TEXT NOT NULL, + FOREIGN KEY (userID) REFERENCES Users(userID) +); + +CREATE TABLE IF NOT EXISTS [Tags] ( + [tagID] INTEGER PRIMARY KEY, + [name] TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS [MediaTags] ( + [mediaID] INTEGER NOT NULL, + [tagID] INTEGER NOT NULL, + FOREIGN KEY (mediaID) REFERENCES MediaItems(mediaID) + FOREIGN KEY (tagID) REFERENCES Tags(tagID) +); + +CREATE TABLE IF NOT EXISTS [Albums] ( + [albumID] INTEGER PRIMARY KEY, + [userID] INTEGER NOT NULL, + [name] TEXT NOT NULL, + FOREIGN KEY (userID) REFERENCES Users(userID) +); + +CREATE TABLE IF NOT EXISTS [MediaAlbums] ( + [mediaID] INTEGER NOT NULL, + [albumID] INTEGER NOT NULL, + FOREIGN KEY (mediaID) REFERENCES MediaItems(mediaID) + FOREIGN KEY (albumID) REFERENCES Albums(albumID) +); diff --git a/db/schemas/sqlite-testdata.sql b/db/schemas/sqlite-testdata.sql new file mode 100644 index 0000000..beb9574 --- /dev/null +++ b/db/schemas/sqlite-testdata.sql @@ -0,0 +1,23 @@ +INSERT INTO Users (name, email, authType, salt, hashedPWSalt) VALUES ("Evan", "evan@reichard.io", "Local", "1234", "1234"); +INSERT INTO Users (name, email, authType, salt, hashedPWSalt) VALUES ("James", "james@example.com", "Local", "1234", "1234"); +INSERT INTO Users (name, email, authType, salt, hashedPWSalt) VALUES ("Bill", "bill@example.com", "Local", "1234", "1234"); + +INSERT INTO MediaItems (userID, EXIFDate, uploadDate, latitude, longitude, mediaType, relPath) VALUES (1, "2012-03-29T10:05:45-06:00", "2012-03-29T10:05:45-06:00", "38.94141753254032", "-77.45238664604386", 0, "/image1.jpg"); +INSERT INTO MediaItems (userID, EXIFDate, uploadDate, latitude, longitude, mediaType, relPath) VALUES (2, "2013-03-29T10:05:45-06:00", "2013-03-29T10:05:45-06:00", "38.94141753254032", "-77.45238664604386", 0, "/image2.jpg"); +INSERT INTO MediaItems (userID, EXIFDate, uploadDate, latitude, longitude, mediaType, relPath) VALUES (3, "2014-03-29T10:05:45-06:00", "2014-03-29T10:05:45-06:00", "38.94141753254032", "-77.45238664604386", 0, "/image3.jpg"); + +INSERT INTO Tags (name) VALUES ("cars"); +INSERT INTO Tags (name) VALUES ("dogs"); +INSERT INTO Tags (name) VALUES ("places"); + +INSERT INTO Albums (userID, name) VALUES (1, "My Favorite Things"); +INSERT INTO Albums (userID, name) VALUES (2, "Trip 2020"); +INSERT INTO Albums (userID, name) VALUES (3, "Corona 2020"); + +INSERT INTO MediaTags (mediaID, tagID) VALUES (1, 3); +INSERT INTO MediaTags (mediaID, tagID) VALUES (2, 2); +INSERT INTO MediaTags (mediaID, tagID) VALUES (3, 1); + +INSERT INTO MediaAlbums (mediaID, albumID) VALUES (1, 3); +INSERT INTO MediaAlbums (mediaID, albumID) VALUES (2, 2); +INSERT INTO MediaAlbums (mediaID, albumID) VALUES (3, 1); diff --git a/db/sqlite.go b/db/sqlite.go new file mode 100644 index 0000000..0eb70ff --- /dev/null +++ b/db/sqlite.go @@ -0,0 +1,95 @@ +package db + +import ( + "database/sql" + "log" + + _ "github.com/mattn/go-sqlite3" +) + +type MediaItem struct { + mediaID int + userID int + EXIFDate string + uploadDate string + latitude string + longitude string + mediaType int + relPath string +} + +func init() { + // Initialize DB +} + +func ItemsFromAlbum(userID int, albumID int) []MediaItem { + database, _ := sql.Open("sqlite3", "./db/imagini.db") + rows, _ := database.Query(` + SELECT + MediaItems.* + FROM + MediaAlbums + INNER JOIN MediaItems ON MediaAlbums.mediaID = MediaItems.mediaID + WHERE MediaAlbums.albumID = ? AND MediaItems.userID = ?`, albumID, userID) + + var matchingMediaItems []MediaItem + var mi MediaItem + for rows.Next() { + err := rows.Scan(&mi.mediaID, &mi.userID, &mi.EXIFDate, &mi.uploadDate, &mi.latitude, &mi.longitude, &mi.mediaType, &mi.relPath) + if err != nil { + log.Fatal(err) + } + matchingMediaItems = append(matchingMediaItems, mi) + } + rows.Close() + return matchingMediaItems +} + +func ItemsFromTags(userID int, tagID int) []MediaItem { + database, _ := sql.Open("sqlite3", "./db/imagini.db") + rows, _ := database.Query(` + SELECT + MediaItems.* + FROM + MediaTags + INNER JOIN MediaItems ON MediaTags.mediaID = MediaItems.mediaID + WHERE MediaTags.tagID = ? AND MediaItems.userID = ?`, tagID, userID) + + var matchingMediaItems []MediaItem + var mi MediaItem + for rows.Next() { + err := rows.Scan(&mi.mediaID, &mi.userID, &mi.EXIFDate, &mi.uploadDate, &mi.latitude, &mi.longitude, &mi.mediaType, &mi.relPath) + if err != nil { + log.Fatal(err) + } + matchingMediaItems = append(matchingMediaItems, mi) + } + rows.Close() + return matchingMediaItems +} + +func IndexMediaItems(newItems []MediaItem) { + database, _ := sql.Open("sqlite3", "./db/imagini.db") + statement, _ := database.Prepare(` + INSERT INTO MediaItems ( + userID, + EXIFDate + uploadDate, + latitude, + longitude, + mediaType, + relPath + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`) + for _, s := range newItems { + statement.Exec( + &s.userID, + &s.EXIFDate, + &s.uploadDate, + &s.latitude, + &s.longitude, + &s.mediaType, + &s.relPath, + ) + } + database.Close() +} diff --git a/db/sqlite.sql b/db/sqlite.sql deleted file mode 100644 index d1a8564..0000000 --- a/db/sqlite.sql +++ /dev/null @@ -1,53 +0,0 @@ -CREATE TABLE IF NOT EXISTS [ServerSettings] ( - [SettingID] INTEGER PRIMARY KEY, - [Name] TEXT NOT NULL, - [Description] TEXT NOT NULL, - [Value] TEXT NOT NULL -); - -CREATE TABLE IF NOT EXISTS [Users] ( - [UserID] INTEGER PRIMARY KEY, - [Name] TEXT NOT NULL, - [Email] TEXT, - [AuthType] TEXT NOT NULL, - [Salt] TEXT, - [HashedPWSalt] TEXT -); - -CREATE TABLE IF NOT EXISTS [Items] ( - [ItemID] INTEGER PRIMARY KEY, - [UserID] INTEGER NOT NULL, - [EXIFDate] TEXT NOT NULL, - [UploadDate] TEXT NOT NULL, - [Latitude] TEXT, - [Longitude] TEXT, - [Type] INTEGER, /* 0 = Photo, 1 = Video */ - [RelPath] TEXT NOT NULL, - FOREIGN KEY (UserID) REFERENCES Users(UserID) -); - -CREATE TABLE IF NOT EXISTS [Tags] ( - [TagID] INTEGER PRIMARY KEY, - [TagName] TEXT NOT NULL -); - -CREATE TABLE IF NOT EXISTS [ItemTags] ( - [ItemID] INTEGER NOT NULL, - [TagID] INTEGER NOT NULL, - FOREIGN KEY (ItemID) REFERENCES Items(ItemID) - FOREIGN KEY (TagID) REFERENCES Tags(TagID) -); - -CREATE TABLE IF NOT EXISTS [Albums] ( - [AlbumID] INTEGER PRIMARY KEY, - [UserID] INTEGER NOT NULL, - [Name] TEXT NOT NULL, - FOREIGN KEY (UserID) REFERENCES Users(UserID) -); - -CREATE TABLE IF NOT EXISTS [ItemAlbums] ( - [ItemID] INTEGER NOT NULL, - [AlbumID] INTEGER NOT NULL, - FOREIGN KEY (ItemID) REFERENCES Items(ItemID) - FOREIGN KEY (AlbumID) REFERENCES Albums(AlbumID) -); diff --git a/go.mod b/go.mod index 2e17d90..8fdabfd 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module reichard.io/imagini go 1.15 require ( + github.com/mattn/go-sqlite3 v1.14.6 github.com/tus/tusd v1.4.0 github.com/urfave/cli/v2 v2.3.0 ) diff --git a/go.sum b/go.sum index a7c6ead..592ef1f 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eT github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= diff --git a/main.go b/main.go index c9ad6da..de61315 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ func main() { Usage: "A self hosted photo library.", Commands: []*cli.Command{ &cmd.CmdServe, + &cmd.CmdDBTest, }, } diff --git a/web/App.vue b/web/App.vue deleted file mode 100644 index a3741b5..0000000 --- a/web/App.vue +++ /dev/null @@ -1,3 +0,0 @@ -