Skip to content

Commit

Permalink
Update Multiple Database Support
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleYang0531 committed Jun 14, 2024
1 parent eaf8c67 commit a5f94a5
Show file tree
Hide file tree
Showing 35 changed files with 311 additions and 417 deletions.
124 changes: 61 additions & 63 deletions api/database.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
addToLibrary({
__builtin_emscripten_query: (sql) => {
__builtin_emscripten_prepare: (config) => {
let configJson = UTF8ToString(config)
let appConfig = JSON.parse(configJson)
if (ENVIRONMENT_IS_NODE) {
if (appConfig["database"] == "sqlite") {
let sqlite3 = require("../api/node_modules/better-sqlite3/lib");
Module.db = new sqlite3(__dirname + "/../public/" + appConfig["sqlite.dbfile"])
} else if (appConfig['database'] == "mysql") {
let mysql = require("../api/node_modules/mysql")
Module.connection = mysql.createConnection({
host: appConfig["mysql.hostname"],
user: appConfig["mysql.username"],
password: appConfig["mysql.password"],
database: appConfig["mysql.database"],
port: appConfig["mysql.port"]
})
Module.connection.connect();
}
} else {
console.error("Database function is only supported in node environment")
}
},
__builtin_emscripten_query: (sql, config) => {
return Asyncify.handleAsync(async () => {
let configJson = FS.readFile("/config/config.json", { encoding: "utf8" }).toString()
let configJson = UTF8ToString(config)
let appConfig = JSON.parse(configJson)
sql = UTF8ToString(sql)
sql = sql.replace(/\'/g, "\'\'")
sql = sql.replace(/\"/g, "'")
if (ENVIRONMENT_IS_NODE) {
if (appConfig["database"] == "sqlite") {
let sqlite3 = require("../api/node_modules/better-sqlite3/lib");
let db = new sqlite3(__dirname + "/../public/" + appConfig["sqlite.dbfile"], { readonly: true })
let result = db.prepare(sql).all()
db.close()
let result = Module.db.prepare(sql).all()
return stringToNewUTF8(JSON.stringify(result))
} else if (appConfig['database'] == "mysql") {
let mysql = require("../api/node_modules/mysql")
let connection = mysql.createConnection({
host: appConfig["mysql.hostname"],
user: appConfig["mysql.username"],
password: appConfig["mysql.password"],
database: appConfig["mysql.database"],
port: appConfig["mysql.port"]
})
connection.connect();
await new Promise((resolve, reject) => {
connection.query("set sql_mode=\"NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\";", (err) => {
Module.connection.query("set sql_mode=\"NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\";", (err) => {
if (err) {
reject(err)
}
resolve()
})
});
let result = await new Promise((resolve, reject) => {
connection.query(sql, (err, result) => {
Module.connection.query(sql, (err, result) => {
if (err) {
reject(err)
} else {
resolve(result)
}
})
})
connection.end()
return stringToNewUTF8(JSON.stringify(result))
}
} else {
Expand All @@ -50,53 +59,42 @@ addToLibrary({
return stringToNewUTF8("[]")
})
},
__builtin_emscripten_execute: async (sql) => {
let configJson = FS.readFile("/config/config.json", { encoding: "utf8" }).toString()
let appConfig = JSON.parse(configJson)
sql = UTF8ToString(sql)
sql = sql.replace(/\'/g, "\'\'")
sql = sql.replace(/\"/g, "'")
if (ENVIRONMENT_IS_NODE) {
if (appConfig["database"] == "sqlite") {
let sqlite3 = require("../api/node_modules/better-sqlite3/lib");
let db = new sqlite3(__dirname + "/../public/" + appConfig["sqlite.dbfile"])
db.exec(sql)
db.close()
return 1
} else if (appConfig['database'] == "mysql") {
let mysql = require("../api/node_modules/mysql")
let connection = mysql.createConnection({
host: appConfig["mysql.hostname"],
user: appConfig["mysql.username"],
password: appConfig["mysql.password"],
database: appConfig["mysql.database"],
port: appConfig["mysql.port"]
})
connection.connect();
await new Promise((resolve, reject) => {
connection.query("set sql_mode=\"NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\";", (err) => {
if (err) {
reject(err)
}
resolve()
})
});
let result = await new Promise((resolve, reject) => {
connection.query(sql, (err, result) => {
if (err) {
reject(err)
} else {
resolve(result)
}
__builtin_emscripten_execute: (sql, config) => {
return Asyncify.handleAsync(async () => {
let configJson = UTF8ToString(config)
let appConfig = JSON.parse(configJson)
sql = UTF8ToString(sql)
sql = sql.replace(/\'/g, "\'\'")
sql = sql.replace(/\"/g, "'")
if (ENVIRONMENT_IS_NODE) {
if (appConfig["database"] == "sqlite") {
Module.db.exec(sql)
return 1
} else if (appConfig['database'] == "mysql") {
await new Promise((resolve, reject) => {
Module.connection.query("set sql_mode=\"NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\";", (err) => {
if (err) {
reject(err)
}
resolve()
})
});
let result = await new Promise((resolve, reject) => {
Module.connection.query(sql, (err, result) => {
if (err) {
reject(err)
} else {
resolve(result)
}
})
})
})
connection.end()
return stringToNewUTF8(JSON.stringify(result))
return stringToNewUTF8(JSON.stringify(result))
}
} else {
console.error("Database query is only supported in node environment")
return 0
}
} else {
console.error("Database query is only supported in node environment")
return 0
}
return 0
})
}
})
8 changes: 8 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
const express = require('express');
const fs = require('fs');
function getFiles(path) {
return fs.readdirSync(path);
}
console.log(__dirname, getFiles(__dirname));
console.log(__dirname + "/../public", getFiles(__dirname + "/../public"));
let wasm = fs.readFileSync(__dirname + '/../public/libsonolus.wasm');
console.log(wasm.length);
var bodyParser = require('body-parser')
const factory = require('../public/libsonolus.js');
const app = express();
Expand Down
25 changes: 17 additions & 8 deletions config/config.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
{
"database": "sqlite",
"mysql.hostname": "127.0.0.1",
"mysql.port": 3306,
"mysql.username": "root",
"mysql.password": "root",
"mysql.database": "sonolus",
"sqlite.dbfile": "sonolus.db",
"sqlite.sqlfile": "sonolus.sql",
"tables": {
"Level": 0,
"Skin": 0,
"Background": 0,
"Effect": 0,
"Particle": 0,
"Engine": 0,
"Replay": 0,
"Post": 0,
"Playlist": 0,
"UserProfile": 0,
"UserSession": 0,
"Room": 0,
"LikeTable": 0,
"Comment": 0,
"Rating": 0
},
"server.listenHost": "0.0.0.0",
"server.listenPort": 8080,
"server.enableSSL": false,
Expand Down
14 changes: 14 additions & 0 deletions config/database.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"database": "sqlite",
"sqlite.dbfile": "sonolus.db"
},
{
"database": "mysql",
"mysql.hostname": "127.0.0.1",
"mysql.port": 3306,
"mysql.username": "root",
"mysql.password": "root",
"mysql.database": "sonolus"
}
]
12 changes: 6 additions & 6 deletions core/singleplayer/BackgroundItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ class BackgroundItem {

int backgroundsNumber(string filter) {
itemNumberTemplate(Background, filter);
dbres res = db.query(sql.c_str());
dbres res = db.query(sql.c_str(), "Background");
return atoi(res[0]["sum"].c_str());
}

vector<BackgroundItem> backgroundsList(string filter, string order, int st = 1, int en = 20) {
itemListTemplate(Background, filter, order, st, en);

auto res = db.query(sql.c_str());
auto res = db.query(sql.c_str(), "Background");
vector<BackgroundItem> list = {};

for (int i = 0; i < res.size(); i++) {
Expand All @@ -123,8 +123,8 @@ vector<BackgroundItem> backgroundsList(string filter, string order, int st = 1,

int backgroundsCreate(BackgroundItem item, string localization = "default") {
stringstream sqlbuffer;
auto res = db.query("SELECT id FROM Background WHERE id = " + to_string(item.id));
if (res.size() == 0) res = db.query("SELECT id FROM Background WHERE name = \"" + item.name + "\" AND localization = \"" + localization + "\"");
auto res = db.query("SELECT id FROM Background WHERE id = " + to_string(item.id), "Background");
if (res.size() == 0) res = db.query("SELECT id FROM Background WHERE name = \"" + item.name + "\" AND localization = \"" + localization + "\"", "Background");
if (res.size() != 0) {
int id = atoi(res[0]["id"].c_str());
sqlbuffer << "UPDATE Background SET name = \"" << item.name << "\", version = " << item.version << ", title = \"" << item.title << "\", ";
Expand All @@ -133,14 +133,14 @@ int backgroundsCreate(BackgroundItem item, string localization = "default") {
sqlbuffer << "tags=\"" << serializeTagString(item.tags) << "\", ";
sqlbuffer << "description = \"" << str_replace("\n", "\\n", item.description) << "\", localization = \"" << localization << "\" WHERE id = " << id << ";";
} else {
int id = atoi(db.query("SELECT COUNT(*) AS sum FROM Background;")[0]["sum"].c_str()) + 1;
int id = atoi(db.query("SELECT COUNT(*) AS sum FROM Background;", "Background")[0]["sum"].c_str()) + 1;
sqlbuffer << "INSERT INTO Background (id, name, version, title, subtitle, author, thumbnail, data, image, configuration, tags, description, localization) VALUES (";
sqlbuffer << id << ", \"" << item.name << "\", " << item.version << ", \"" << item.title << "\", ";
sqlbuffer << "\"" << item.subtitle << "\", \"" << item.author << "\", \"" << item.thumbnail.hash << "\", ";
sqlbuffer << "\"" << item.data.hash << "\", \"" << item.image.hash << "\", \"" << item.configuration.hash << "\", ";
sqlbuffer << "\"" << serializeTagString(item.tags) << "\", ";
sqlbuffer << "\"" << str_replace("\n", "\\n", item.description) << "\", \"" << localization << "\");";
} return db.execute(sqlbuffer.str());
} return db.execute(sqlbuffer.str(), "Background");
}

#endif
12 changes: 6 additions & 6 deletions core/singleplayer/EffectItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ class EffectItem {

int effectsNumber(string filter) {
itemNumberTemplate(Effect, filter);
dbres res = db.query(sql.c_str());
dbres res = db.query(sql.c_str(), "Effect");
return atoi(res[0]["sum"].c_str());
}

vector<EffectItem> effectsList(string filter, string order, int st = 1, int en = 20) {
itemListTemplate(Effect, filter, order, st, en);

auto res = db.query(sql.c_str());
auto res = db.query(sql.c_str(), "Effect");
vector<EffectItem> list = {};

for (int i = 0; i < res.size(); i++) {
Expand All @@ -118,8 +118,8 @@ vector<EffectItem> effectsList(string filter, string order, int st = 1, int en =

int effectsCreate(EffectItem item, string localization = "default") {
stringstream sqlbuffer;
auto res = db.query("SELECT id FROM Effect WHERE id = " + to_string(item.id));
if (res.size() == 0) res = db.query("SELECT id FROM Effect WHERE name = \"" + item.name + "\" AND localization = \"" + localization + "\"");
auto res = db.query("SELECT id FROM Effect WHERE id = " + to_string(item.id), "Effect");
if (res.size() == 0) res = db.query("SELECT id FROM Effect WHERE name = \"" + item.name + "\" AND localization = \"" + localization + "\"", "Effect");
if (res.size() != 0) {
int id = atoi(res[0]["id"].c_str());
sqlbuffer << "UPDATE Effect SET name = \"" << item.name << "\", version = " << item.version << ", ";
Expand All @@ -129,13 +129,13 @@ int effectsCreate(EffectItem item, string localization = "default") {
sqlbuffer << "tags=\"" << serializeTagString(item.tags) << "\", ";
sqlbuffer << "description = \"" << str_replace("\n", "\\n", item.description) << "\", localization = \"" << localization << "\" WHERE id = " << id;
} else {
int id = atoi(db.query("SELECT COUNT(*) AS sum FROM Effect;")[0]["sum"].c_str()) + 1;
int id = atoi(db.query("SELECT COUNT(*) AS sum FROM Effect;", "Effect")[0]["sum"].c_str()) + 1;
sqlbuffer << "INSERT INTO Effect (id, name, version, title, subtitle, author, thumbnail, tags, data, audio, description, localization) VALUES (";
sqlbuffer << id << ", \"" << item.name << "\", " << item.version << ", \"" << item.title << "\", ";
sqlbuffer << "\"" << item.subtitle << "\", \"" << item.author << "\", \"" << item.thumbnail.hash << "\", ";
sqlbuffer << "\"" << serializeTagString(item.tags) << "\", ";
sqlbuffer << "\"" << item.data.hash << "\", \"" << item.audio.hash << "\", \"" << str_replace("\n", "\\n", item.description) << "\", \"" << localization << "\")";
} return db.execute(sqlbuffer.str());
} return db.execute(sqlbuffer.str(), "Effect");
}

#endif
20 changes: 10 additions & 10 deletions core/singleplayer/EngineItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,14 @@ class EngineItem {

int enginesNumber(string filter) {
itemNumberTemplate(Engine, filter);
dbres res = db.query(sql.c_str());
dbres res = db.query(sql.c_str(), "Engine");
return atoi(res[0]["sum"].c_str());
}

vector<EngineItem> enginesList(string filter, string order, int st = 1, int en = 20) {
itemListTemplate(Engine, filter, order, st, en);

dbres res = db.query(sql.c_str());
dbres res = db.query(sql.c_str(), "Engine");
vector<EngineItem> list = {};

for (int i = 0; i < res.size(); i++) {
Expand Down Expand Up @@ -167,12 +167,12 @@ vector<EngineItem> enginesList(string filter, string order, int st = 1, int en =

int enginesCreate(EngineItem item, string localization = "default") {
stringstream sqlbuffer;
auto res = db.query("SELECT id FROM Engine WHERE id = " + to_string(item.id));
if (res.size() == 0) res = db.query("SELECT id FROM Engine WHERE name = \"" + item.name + "\" AND localization = \"" + localization + "\"");
int skinId = atoi(db.query("SELECT id FROM Skin WHERE name = \"" + item.skin.name + "\";")[0]["id"].c_str());
int backgroundId = atoi(db.query("SELECT id FROM Background WHERE name = \"" + item.background.name + "\";")[0]["id"].c_str());
int effectId = atoi(db.query("SELECT id FROM Effect WHERE name = \"" + item.effect.name + "\";")[0]["id"].c_str());
int particleId = atoi(db.query("SELECT id FROM Particle WHERE name = \"" + item.particle.name + "\";")[0]["id"].c_str());
auto res = db.query("SELECT id FROM Engine WHERE id = " + to_string(item.id), "Engine");
if (res.size() == 0) res = db.query("SELECT id FROM Engine WHERE name = \"" + item.name + "\" AND localization = \"" + localization + "\"", "Engine");
int skinId = atoi(db.query("SELECT id FROM Skin WHERE name = \"" + item.skin.name + "\";", "Skin")[0]["id"].c_str());
int backgroundId = atoi(db.query("SELECT id FROM Background WHERE name = \"" + item.background.name + "\";", "Background")[0]["id"].c_str());
int effectId = atoi(db.query("SELECT id FROM Effect WHERE name = \"" + item.effect.name + "\";", "Effect")[0]["id"].c_str());
int particleId = atoi(db.query("SELECT id FROM Particle WHERE name = \"" + item.particle.name + "\";", "Particle")[0]["id"].c_str());
if (res.size() != 0) {
int id = atoi(res[0]["id"].c_str());
sqlbuffer << "UPDATE Engine SET name = \"" << item.name << "\", version = " << item.version << ", title = \"" << item.title << "\", ";
Expand All @@ -181,14 +181,14 @@ int enginesCreate(EngineItem item, string localization = "default") {
sqlbuffer << "tags=\"" << serializeTagString(item.tags) << "\", ";
sqlbuffer << "configuration = \"" << item.configuration.hash << "\", rom = \"" << item.rom.hash << "\", description = \"" << str_replace("\n", "\\n", item.description) << "\", localization = \"" << localization << "\" WHERE id = " << id << ";";
} else {
int id = atoi(db.query("SELECT COUNT(*) AS sum FROM Engine;")[0]["sum"].c_str()) + 1;
int id = atoi(db.query("SELECT COUNT(*) AS sum FROM Engine;", "Engine")[0]["sum"].c_str()) + 1;
sqlbuffer << "INSERT INTO Engine (id, name, version, title, subtitle, author, skin, background, effect, particle, thumbnail, data, configuration, tags, rom, description, localization, tutorialData, previewData, watchData) VALUES (";
sqlbuffer << id << ", \"" << item.name << "\", " << item.version << ", \"" << item.title << "\", ";
sqlbuffer << "\"" << item.subtitle << "\", \"" << item.author << "\", " << skinId << ", " << backgroundId << ", " << effectId << ", " << particleId << ", ";
sqlbuffer << "\"" << item.thumbnail.hash << "\", \"" << item.data.hash << "\", \"" << item.configuration.hash << "\", ";
sqlbuffer << "\"" << serializeTagString(item.tags) << "\", ";
sqlbuffer << "\"" << item.rom.hash << "\", \"" << str_replace("\n", "\\n", item.description) << "\", \"" << localization << "\", \"" << item.tutorialData.hash << "\", \"" << item.previewData.hash << "\", \"" << item.watchData.hash << "\");";
} return db.execute(sqlbuffer.str());
} return db.execute(sqlbuffer.str(), "Engine");
}

#endif
4 changes: 2 additions & 2 deletions core/singleplayer/ItemCommunityComment.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ class ItemCommunityComment {

int commentsNumber(string filter) {
string sql = "SELECT COUNT(*) AS sum FROM Comment WHERE (" + filter + ")";
dbres res = db.query(sql.c_str());
dbres res = db.query(sql.c_str(), "Comment");
return atoi(res[0]["sum"].c_str());
}

vector<ItemCommunityComment> commentsList(string filter, string order, int st = 1, int en = 20) {
string sql = "SELECT * FROM Comment WHERE (" + filter + ") ORDER BY " + order + " LIMIT " + to_string(st - 1) + ", " + to_string(en - st + 1);

auto res = db.query(sql.c_str());
auto res = db.query(sql.c_str(), "Comment");
vector<ItemCommunityComment> list;

for (int i = 0; i < res.size(); i++) {
Expand Down
Loading

0 comments on commit a5f94a5

Please sign in to comment.