mirror of
https://github.com/Eyre-S/sekai-scores.git
synced 2024-11-25 04:27:43 +08:00
complete cli import song from sekai-master-db
- and added database struct can execute some postgres sekai database action - now can insert a Song (without its Difficulties) - now can search if a Song exists(by id) - added a SekaiDifficulties type struct targeting to database type - added a struct SekaiSongDifficulties.DatabaseStruct targeting to database its table struct - added a class PostgresSession for manager a database action flow - and reforged PostgresConfig#connect() to implement it
This commit is contained in:
parent
944b57c012
commit
7d503f3723
@ -1,7 +1,7 @@
|
|||||||
## Project Configurations
|
## Project Configurations
|
||||||
|
|
||||||
# Proj Metadata
|
# Proj Metadata
|
||||||
projVersion = 0.7
|
projVersion = 0.8
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
## Project Configurations
|
## Project Configurations
|
||||||
|
|
||||||
# Proj Metadata
|
# Proj Metadata
|
||||||
moduleVersion = 0.5.3
|
moduleVersion = 0.5.4
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
lib_postgres_driver = 42.5.1
|
lib_postgres_driver = 42.5.1
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package cc.sukazyo.sekai_cli.client;
|
package cc.sukazyo.sekai_cli.client;
|
||||||
|
|
||||||
|
import cc.sukazyo.sekai_cli.ClientMain;
|
||||||
import cc.sukazyo.sekai_cli.data_tool.sekai_master_db.Music;
|
import cc.sukazyo.sekai_cli.data_tool.sekai_master_db.Music;
|
||||||
|
import cc.sukazyo.sekai_db.PostgresSession;
|
||||||
|
import cc.sukazyo.sekai_db.table.SekaiSongs;
|
||||||
import cc.sukazyo.sekai_scores.Song;
|
import cc.sukazyo.sekai_scores.Song;
|
||||||
import com.google.gson.JsonIOException;
|
import com.google.gson.JsonIOException;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
@ -11,6 +14,7 @@ import java.nio.charset.IllegalCharsetNameException;
|
|||||||
import java.nio.charset.UnsupportedCharsetException;
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -60,10 +64,27 @@ public class Database {
|
|||||||
}
|
}
|
||||||
switch ($args.remove(0)) {
|
switch ($args.remove(0)) {
|
||||||
case "song" -> {
|
case "song" -> {
|
||||||
try {
|
try (final PostgresSession session = ClientMain.config().db().connect()) {
|
||||||
final Song[] songs = Music.toSongArray(Music.readFrom(file.toFile(), charset));
|
final Song[] songs = Music.toSongArray(Music.readFrom(file.toFile(), charset));
|
||||||
|
for (Song i : songs) {
|
||||||
|
_user(String.format("db_import: start insertion for song #%d (%s)", i.id(), i.name()));
|
||||||
|
try {
|
||||||
|
if (SekaiSongs.as(session).hasSong(i.id()))
|
||||||
|
_user(String.format("db_import: song #%d already exists, skipped.", i.id()));
|
||||||
|
else {
|
||||||
|
final int changes = SekaiSongs.as(session).insert(i);
|
||||||
|
_user(String.format("db_import: song #%d insert succeed: %d row updated.", i.id(), changes));
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
_user("db_import: song #"+i.id()+": data insert failed: " + e.getMessage());
|
||||||
|
_debug(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (IOException | JsonIOException | JsonSyntaxException e) {
|
} catch (IOException | JsonIOException | JsonSyntaxException e) {
|
||||||
_user("error while parsing song file: " + e.getMessage());
|
_user("db_import: error while parsing song file: " + e.getMessage());
|
||||||
|
_debug(e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
_user("db_import: error while connecting to database: " + e.getMessage());
|
||||||
_debug(e);
|
_debug(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package cc.sukazyo.sekai_cli.data_tool.sekai_master_db;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonIOException;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
public class MusicDifficulty {
|
||||||
|
|
||||||
|
public int id;
|
||||||
|
public int musicId;
|
||||||
|
public String musicDifficulty;
|
||||||
|
public int playLevel;
|
||||||
|
public int releaseConditionId;
|
||||||
|
public int noteCount;
|
||||||
|
|
||||||
|
public static MusicDifficulty[] readFrom (File sekaiMusicDifficultiesFile, Charset charset)
|
||||||
|
throws IOException, JsonIOException, JsonSyntaxException {
|
||||||
|
return new Gson().fromJson(new FileReader(sekaiMusicDifficultiesFile, charset), MusicDifficulty[].class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,6 +13,8 @@ dependencies {
|
|||||||
|
|
||||||
compileOnly "com.github.spotbugs:spotbugs-annotations:${lib_spotbugs_v}"
|
compileOnly "com.github.spotbugs:spotbugs-annotations:${lib_spotbugs_v}"
|
||||||
|
|
||||||
|
implementation rootProject
|
||||||
|
|
||||||
testImplementation "org.junit.jupiter:junit-jupiter-api:${lib_junit_v}"
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${lib_junit_v}"
|
||||||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${lib_junit_v}"
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${lib_junit_v}"
|
||||||
|
|
||||||
|
@ -38,7 +38,11 @@ public class PostgresConfig {
|
|||||||
return (schema == null ? "" : '"' + schema() + '"' + ".") + '"' + table + '"';
|
return (schema == null ? "" : '"' + schema() + '"' + ".") + '"' + table + '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
public Connection connect () throws SQLException {
|
public PostgresSession connect () throws SQLException {
|
||||||
|
return PostgresSession.as(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection getConnection () throws SQLException {
|
||||||
return DriverManager.getConnection(this.toString(), user, token);
|
return DriverManager.getConnection(this.toString(), user, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package cc.sukazyo.sekai_db;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class PostgresSession implements AutoCloseable {
|
||||||
|
|
||||||
|
public final Connection session;
|
||||||
|
private final PostgresConfig config;
|
||||||
|
private PostgresSession (Connection session, PostgresConfig config) {
|
||||||
|
this.config = config;
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
static PostgresSession as (PostgresConfig config) throws SQLException {
|
||||||
|
final PostgresSession $this = new PostgresSession(config.getConnection(), config);
|
||||||
|
$this.session.setAutoCommit(false);
|
||||||
|
$this.session.beginRequest();
|
||||||
|
$this.session.setSchema($this.config.schema);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close () throws SQLException {
|
||||||
|
session.commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package cc.sukazyo.sekai_db.table;
|
||||||
|
|
||||||
|
import cc.sukazyo.sekai_db.PostgresSession;
|
||||||
|
import cc.sukazyo.sekai_db.type.SekaiDifficulties;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class SekaiSongDifficulties {
|
||||||
|
|
||||||
|
public record DatabaseStruct (
|
||||||
|
int songId,
|
||||||
|
@Nonnull SekaiDifficulties difficulty,
|
||||||
|
int level,
|
||||||
|
int notes,
|
||||||
|
int lvlp,
|
||||||
|
int flvlp,
|
||||||
|
int plvlp
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private final PostgresSession session;
|
||||||
|
|
||||||
|
private SekaiSongDifficulties (PostgresSession session) { this.session = session; }
|
||||||
|
static SekaiSongDifficulties as (PostgresSession session) { return new SekaiSongDifficulties(session); }
|
||||||
|
|
||||||
|
// public boolean contains (int songId, SekaiDifficulties difficulty) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public int insertDatabaseStructData (DatabaseStruct data) {
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package cc.sukazyo.sekai_db.table;
|
||||||
|
|
||||||
|
import cc.sukazyo.sekai_db.PostgresSession;
|
||||||
|
import cc.sukazyo.sekai_scores.Song;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class SekaiSongs {
|
||||||
|
|
||||||
|
private final PostgresSession session;
|
||||||
|
|
||||||
|
private SekaiSongs(PostgresSession session) {
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
public static SekaiSongs as (PostgresSession session) {
|
||||||
|
return new SekaiSongs(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSong(int songId) throws SQLException {
|
||||||
|
final PreparedStatement statement = session.session.prepareStatement("""
|
||||||
|
select id from sekai_songs
|
||||||
|
where id = ?
|
||||||
|
""");
|
||||||
|
statement.setInt(1, songId);
|
||||||
|
return statement.executeQuery().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int insert (Song song) throws SQLException {
|
||||||
|
final PreparedStatement statement = session.session.prepareStatement("""
|
||||||
|
insert into sekai_songs
|
||||||
|
(id, unit_seq, name, producer, arranger, composer, lyricist, bpm, duration, release_date, name_alias)
|
||||||
|
values (?, ?, ?, ?, ?, ?, ?, ?, cast(? AS interval), ?, ?)
|
||||||
|
""");
|
||||||
|
statement.setInt(1, song.id());
|
||||||
|
statement.setInt(2, song.unit().seq);
|
||||||
|
statement.setString(3, song.name());
|
||||||
|
statement.setString(4, song.producer());
|
||||||
|
statement.setString(5, song.arranger());
|
||||||
|
statement.setString(6, song.composer());
|
||||||
|
statement.setString(7, song.lyricist());
|
||||||
|
if (song.bpm() == null) statement.setNull(8, Types.ARRAY);
|
||||||
|
else statement.setArray(8, session.session.createArrayOf("smallint", Arrays.stream(song.bpm()).boxed().toArray()));
|
||||||
|
if (song.duration() == null) statement.setNull(9, Types.VARCHAR);
|
||||||
|
else statement.setString(9, song.duration().toString());
|
||||||
|
if (song.releaseDate() == null) statement.setNull(10, Types.TIMESTAMP_WITH_TIMEZONE);
|
||||||
|
else statement.setTimestamp(10, Timestamp.from(song.releaseDate().toInstant()));
|
||||||
|
statement.setArray(11, session.session.createArrayOf("text", song.nameAlias()));
|
||||||
|
return statement.executeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package cc.sukazyo.sekai_db.type;
|
||||||
|
|
||||||
|
public enum SekaiDifficulties {
|
||||||
|
EASY,
|
||||||
|
NORMAL,
|
||||||
|
HARD,
|
||||||
|
EXPERT,
|
||||||
|
MASTER
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user