diff --git a/gradle.properties b/gradle.properties index a1037e3..2aa8374 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,9 @@ ## Project Configurations +## +## project sekia-scores # Proj Metadata -projVersion = 0.8.1 +projVersion = 0.9 # Dependencies diff --git a/sekai-cli/gradle.properties b/sekai-cli/gradle.properties index 51ec46a..2f4b4cc 100644 --- a/sekai-cli/gradle.properties +++ b/sekai-cli/gradle.properties @@ -1,7 +1,10 @@ ## Project Configurations +# +# for subproject sekai-cli +# belongs to sekai-scores # Proj Metadata -moduleVersion = 0.5.4 +moduleVersion = 0.5.5 # dependencies lib_postgres_driver = 42.5.1 diff --git a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/client/Database.java b/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/client/Database.java index e6c3264..fe4cb8f 100644 --- a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/client/Database.java +++ b/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/client/Database.java @@ -29,6 +29,12 @@ public class Database { final List $args = new ArrayList<>(List.of(args)); + if ($args.size() < 1) { + System.out.println(""" + usage of database: + import - import song/difficulty data to database + """); + } final String subcommand = $args.remove(0); if (subcommand.equals("import")) { diff --git a/sekai-database/src/main/java/cc/sukazyo/sekai_db/Util.java b/sekai-database/src/main/java/cc/sukazyo/sekai_db/Util.java new file mode 100644 index 0000000..7f71af5 --- /dev/null +++ b/sekai-database/src/main/java/cc/sukazyo/sekai_db/Util.java @@ -0,0 +1,14 @@ +package cc.sukazyo.sekai_db; + +public class Util { + + public static int[] arraysShortToInt (final Short[] source) { + if (source == null) return null; + final int[] result = new int[source.length]; + for (int i = 0; i < source.length; i++) { + result[i] = source[i]; + } + return result; + } + +} diff --git a/sekai-database/src/main/java/cc/sukazyo/sekai_db/table/SekaiSongDifficulties.java b/sekai-database/src/main/java/cc/sukazyo/sekai_db/table/SekaiSongDifficulties.java index 1ebfa15..40f372b 100644 --- a/sekai-database/src/main/java/cc/sukazyo/sekai_db/table/SekaiSongDifficulties.java +++ b/sekai-database/src/main/java/cc/sukazyo/sekai_db/table/SekaiSongDifficulties.java @@ -13,6 +13,25 @@ import java.sql.Types; public class SekaiSongDifficulties { + public static final String TABLE_DDL = """ + create table sekai_song_difficulties + ( + song_id integer not null, + difficulty sekai.sekai_difficulties not null, + level smallint not null, + notes smallint not null, + "lvl+" smallint, + "flvl+" smallint, + "plvl+" smallint + ); + + create index sekai_songs_difficulties_song_id_difficulty_name_index + on sekai_song_difficulties (song_id, difficulty); + + create index sekai_songs_difficulties_notes_index + on sekai_song_difficulties (notes); + """; + public record DatabaseStruct ( int songId, @Nonnull SekaiDifficulties difficulty, @@ -28,6 +47,10 @@ public class SekaiSongDifficulties { private SekaiSongDifficulties (PostgresSession session) { this.session = session; } public static SekaiSongDifficulties as (PostgresSession session) { return new SekaiSongDifficulties(session); } + public int create () throws SQLException { + return session.session.prepareStatement(TABLE_DDL).executeUpdate(); + } + public boolean contains (int songId) throws SQLException { final PreparedStatement check = session.session.prepareStatement(""" select song_id, difficulty from sekai_song_difficulties diff --git a/sekai-database/src/main/java/cc/sukazyo/sekai_db/table/SekaiSongs.java b/sekai-database/src/main/java/cc/sukazyo/sekai_db/table/SekaiSongs.java index 3fc83bf..2882a4b 100644 --- a/sekai-database/src/main/java/cc/sukazyo/sekai_db/table/SekaiSongs.java +++ b/sekai-database/src/main/java/cc/sukazyo/sekai_db/table/SekaiSongs.java @@ -1,17 +1,54 @@ package cc.sukazyo.sekai_db.table; import cc.sukazyo.sekai_db.PostgresSession; +import cc.sukazyo.sekai_scores.DifficultiesEmpty; import cc.sukazyo.sekai_scores.Difficulty; import cc.sukazyo.sekai_scores.Song; +import cc.sukazyo.sekai_scores.SongUnit; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.sql.Types; +import java.sql.*; +import java.time.Duration; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.util.Arrays; +import static cc.sukazyo.sekai_db.Util.arraysShortToInt; + public class SekaiSongs { + public static final String TABLE_DDL = """ + create table sekai_songs + ( + id integer not null + constraint sekai_songs_pk + primary key, + name text not null + constraint sekai_songs_pk_name + unique, + producer text, + arranger text, + composer text, + bpm smallint[], + duration interval(1), + release_date timestamp(3) with time zone, + name_alias text[], + lyricist text, + unit_seq smallint + ); + + comment on column sekai_songs.name_alias is + 'the alias/tags for this song, + it usually is a unofficial name of this song. + + used to search songs.'; + + create index sekai_songs_name_alias_index + on sekai_songs (name_alias); + + create index sekai_songs_producer_index + on sekai_songs (producer); + """; + private final PostgresSession session; private SekaiSongs(PostgresSession session) { @@ -21,6 +58,10 @@ public class SekaiSongs { return new SekaiSongs(session); } + public int create () throws SQLException { + return session.session.prepareStatement(TABLE_DDL).executeUpdate(); + } + public boolean hasSong(int songId) throws SQLException { final PreparedStatement statement = session.session.prepareStatement(""" select id from sekai_songs @@ -30,6 +71,33 @@ public class SekaiSongs { return statement.executeQuery().next(); } + public Song getSong (int songId) throws SQLException { + final PreparedStatement getById = session.session.prepareStatement(""" + select + id, unit_seq, name, producer, arranger, composer, lyricist, bpm, duration, release_date, name_alias + from sekai_songs + where id = ? + """); + getById.setInt(1, songId); + final ResultSet data = getById.executeQuery(); + if (!data.next()) return null; + final Timestamp _release_date = data.getTimestamp("release_date"); + return new Song( + data.getInt("id"), + data.getString("name"), + SongUnit.getBySeq(data.getInt("unit_seq")), + new DifficultiesEmpty(), + data.getString("producer"), + data.getString("arranger"), + data.getString("composer"), + data.getString("lyricist"), + arraysShortToInt((Short[])data.getArray("bpm").getArray()), + Duration.parse("PT0s"), // todo + _release_date == null ? null : ZonedDateTime.ofInstant(_release_date.toInstant(), ZoneOffset.UTC), + (String[])data.getArray("name_alias").getArray() + ); + } + public int insert (Song song) throws SQLException { int updated = 0; diff --git a/sekai-meta/gradle.properties b/sekai-meta/gradle.properties index c0e1d0e..1f01728 100644 --- a/sekai-meta/gradle.properties +++ b/sekai-meta/gradle.properties @@ -1,4 +1,7 @@ ## Project Configurations +# +# for subproject sekai-meta +# belongs to sekai-scores # Proj Metadata moduleVersion = 0.3