97 lines
3.3 KiB
D
97 lines
3.3 KiB
D
|
import std.stdio;
|
||
|
import std.csv;
|
||
|
import std.algorithm;
|
||
|
import std.typecons;
|
||
|
import etc.c.sqlite3;
|
||
|
import std.string : toStringz, fromStringz, empty;
|
||
|
import std.exception;
|
||
|
import std.conv : to;
|
||
|
|
||
|
private class SQLiteException : Exception {
|
||
|
this(int code, string msg1, string msg2, string file = __FILE__, size_t line = __LINE__) {
|
||
|
super("SQLite3 error " ~ to!string(code) ~ (msg1.empty ? "" : " ") ~ msg1 ~ ": " ~ msg, file, line);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern(C) private int callback(void */*NotUsed*/, int /*argc*/, char **/*argv*/, char **/*azColName*/) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
private int version_to_int (string ver) pure {
|
||
|
switch(ver) {
|
||
|
case "pal":
|
||
|
return 0;
|
||
|
case "ntsc_j":
|
||
|
return 1;
|
||
|
case "ntsc_u":
|
||
|
return 2;
|
||
|
default:
|
||
|
return 3;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void insert_into_sqlite(sqlite3* db, string path, string ver) {
|
||
|
auto file = File(path, "r");
|
||
|
sqlite3_stmt* statement;
|
||
|
scope(exit) {sqlite3_finalize(statement);}
|
||
|
|
||
|
{
|
||
|
string sql = "INSERT INTO GameList(Name, Serial, Languages, Version) VALUES(?, ?, ?, ?);";
|
||
|
const int prepare_ret = sqlite3_prepare_v2(db, sql.ptr, cast(int)sql.length, &statement, null);
|
||
|
if (prepare_ret)
|
||
|
throw new SQLiteException(prepare_ret, "", sqlite3_errstr(prepare_ret).fromStringz.idup);
|
||
|
}
|
||
|
|
||
|
foreach (record; file.byLine.joiner("\n").csvReader!(Tuple!(string, string, string))) {
|
||
|
sqlite3_bind_text(statement, 1, record[0].ptr, cast(int)record[0].length, SQLITE_STATIC);
|
||
|
sqlite3_bind_text(statement, 2, record[1].ptr, cast(int)record[1].length, SQLITE_STATIC);
|
||
|
sqlite3_bind_text(statement, 3, record[2].ptr, cast(int)record[2].length, SQLITE_STATIC);
|
||
|
sqlite3_bind_int(statement, 4, version_to_int(ver));
|
||
|
|
||
|
stderr.writefln("insert into: \"%s\", \"%s\", \"%s\", \"%d\"", record[0], record[1], record[2], version_to_int(ver));
|
||
|
const int step_ret = sqlite3_step(statement);
|
||
|
if (step_ret && SQLITE_DONE != step_ret)
|
||
|
throw new SQLiteException(step_ret, "", sqlite3_errstr(step_ret).fromStringz.idup);
|
||
|
sqlite3_reset(statement);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main(string[] argv) {
|
||
|
//input parameters should be csv files in this order: pal, ntsc_j, ntsc_u
|
||
|
|
||
|
stderr.writefln("got %s params: \"%s\", \"%s\", \"%s\", \"%s\"", argv.length, argv[1], argv[2], argv[3], argv[4]);
|
||
|
|
||
|
if (argv.length != 5) {
|
||
|
stderr.writefln("Expected 4 parameters: <pal.csv> <ntsc_j.csv> <ntsc_u.csv> <output.sqlite3>, but %s were received", argv.length - 1);
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
sqlite3* db = null;
|
||
|
scope(exit) { if (db) {sqlite3_close(db);} }
|
||
|
{
|
||
|
const int open_ret = sqlite3_open_v2(argv[4].toStringz(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, null);
|
||
|
if (open_ret)
|
||
|
throw new SQLiteException(open_ret, "opening database \"" ~ argv[4] ~ "\"", sqlite3_errmsg(db).fromStringz.idup);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
string sql = "DROP TABLE IF EXISTS GameList; CREATE TABLE GameList(Serial VARCHAR(10) PRIMARY KEY NOT NULL, Name TEXT NOT NULL, Languages TEXT NOT NULL, Version TINYINT NOT NULL);";
|
||
|
char* error_msg = null;
|
||
|
const int query_ret = sqlite3_exec(db, sql.toStringz(), &callback, null, &error_msg);
|
||
|
if (query_ret)
|
||
|
throw new SQLiteException(query_ret, "creating GameList table", error_msg.fromStringz.idup);
|
||
|
}
|
||
|
|
||
|
insert_into_sqlite(db, argv[1], "pal");
|
||
|
insert_into_sqlite(db, argv[2], "ntsc_j");
|
||
|
insert_into_sqlite(db, argv[3], "ntsc_u");
|
||
|
}
|
||
|
catch (Exception err) {
|
||
|
stderr.writeln(err);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|