2017-06-26 23:48:42 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data.SQLite;
|
2017-07-10 04:51:02 +00:00
|
|
|
|
using NLua;
|
2017-06-26 23:48:42 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.Client.Common
|
|
|
|
|
{
|
2017-06-28 01:26:16 +00:00
|
|
|
|
[Description("A library for performing SQLite operations.")]
|
2017-06-26 23:48:42 +00:00
|
|
|
|
public sealed class SQLLuaLibrary : LuaLibraryBase
|
|
|
|
|
{
|
|
|
|
|
public SQLLuaLibrary(Lua lua)
|
|
|
|
|
: base(lua) { }
|
|
|
|
|
|
|
|
|
|
public SQLLuaLibrary(Lua lua, Action<string> logOutputCallback)
|
|
|
|
|
: base(lua, logOutputCallback) { }
|
|
|
|
|
|
|
|
|
|
public override string Name => "SQL";
|
|
|
|
|
|
|
|
|
|
SQLiteConnection m_dbConnection;
|
|
|
|
|
string connectionString;
|
|
|
|
|
|
2018-03-14 01:05:30 +00:00
|
|
|
|
[LuaMethodExample("local stSQLcre = SQL.createdatabase( \"eg_db\" );")]
|
2018-03-10 11:00:44 +00:00
|
|
|
|
[LuaMethod("createdatabase", "Creates a SQLite Database. Name should end with .db")]
|
2017-06-26 23:48:42 +00:00
|
|
|
|
public string CreateDatabase(string name)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
SQLiteConnection.CreateFile(name);
|
|
|
|
|
return "Database Created Successfully";
|
|
|
|
|
}
|
|
|
|
|
catch (SQLiteException sqlEX)
|
|
|
|
|
{
|
|
|
|
|
return sqlEX.Message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-03-14 01:05:30 +00:00
|
|
|
|
[LuaMethodExample("local stSQLope = SQL.opendatabase( \"eg_db\" );")]
|
2017-07-10 19:02:00 +00:00
|
|
|
|
[LuaMethod("opendatabase", "Opens a SQLite database. Name should end with .db")]
|
2017-06-26 23:48:42 +00:00
|
|
|
|
public string OpenDatabase(string name)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
SQLiteConnectionStringBuilder connBuilder = new SQLiteConnectionStringBuilder();
|
|
|
|
|
connBuilder.DataSource = name;
|
|
|
|
|
connBuilder.Version = 3; //SQLite version
|
|
|
|
|
connBuilder.JournalMode = SQLiteJournalModeEnum.Wal; //Allows for reads and writes to happen at the same time
|
|
|
|
|
connBuilder.DefaultIsolationLevel = System.Data.IsolationLevel.ReadCommitted; //This only helps make the database lock left. May be pointless now
|
|
|
|
|
connBuilder.SyncMode = SynchronizationModes.Off; //This shortens the delay for do synchronous calls.
|
|
|
|
|
m_dbConnection = new SQLiteConnection(connBuilder.ToString());
|
|
|
|
|
connectionString = connBuilder.ToString();
|
|
|
|
|
m_dbConnection.Open();
|
|
|
|
|
m_dbConnection.Close();
|
|
|
|
|
return "Database Opened Successfully";
|
|
|
|
|
}
|
2018-03-10 11:00:44 +00:00
|
|
|
|
catch (SQLiteException sqlEX)
|
2017-06-26 23:48:42 +00:00
|
|
|
|
{
|
|
|
|
|
return sqlEX.Message;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-14 01:05:30 +00:00
|
|
|
|
[LuaMethodExample("local stSQLwri = SQL.writecommand( \"CREATE TABLE eg_tab ( eg_tab_id integer PRIMARY KEY, eg_tab_row_name text NOT NULL ); INSERT INTO eg_tab ( eg_tab_id, eg_tab_row_name ) VALUES ( 1, 'Example table row' );\" );")]
|
2017-07-10 19:02:00 +00:00
|
|
|
|
[LuaMethod("writecommand", "Runs a SQLite write command which includes CREATE,INSERT, UPDATE. " +
|
2017-06-26 23:48:42 +00:00
|
|
|
|
"Ex: create TABLE rewards (ID integer PRIMARY KEY, action VARCHAR(20)) ")]
|
2018-03-10 11:00:44 +00:00
|
|
|
|
public string WriteCommand(string query = "")
|
2017-06-26 23:48:42 +00:00
|
|
|
|
{
|
|
|
|
|
if (query == "")
|
|
|
|
|
{
|
|
|
|
|
return "query is empty";
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
m_dbConnection.Open();
|
|
|
|
|
string sql = query;
|
|
|
|
|
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
|
|
|
|
|
command.ExecuteNonQuery();
|
|
|
|
|
m_dbConnection.Close();
|
|
|
|
|
|
|
|
|
|
return "Command ran successfully";
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (NullReferenceException nullEX)
|
|
|
|
|
{
|
|
|
|
|
return "Database not open.";
|
|
|
|
|
}
|
2018-03-10 11:00:44 +00:00
|
|
|
|
catch (SQLiteException sqlEX)
|
2017-06-26 23:48:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_dbConnection.Close();
|
|
|
|
|
return sqlEX.Message;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-14 01:05:30 +00:00
|
|
|
|
[LuaMethodExample("local obSQLrea = SQL.readcommand( \"SELECT * FROM eg_tab WHERE eg_tab_id = 1;\" );")]
|
2017-07-10 19:02:00 +00:00
|
|
|
|
[LuaMethod("readcommand", "Run a SQLite read command which includes Select. Returns all rows into a LuaTable." +
|
2017-06-26 23:48:42 +00:00
|
|
|
|
"Ex: select * from rewards")]
|
2018-03-10 11:00:44 +00:00
|
|
|
|
public dynamic ReadCommand(string query = "")
|
2017-06-26 23:48:42 +00:00
|
|
|
|
{
|
2018-03-10 11:00:44 +00:00
|
|
|
|
if (query == "")
|
2017-06-26 23:48:42 +00:00
|
|
|
|
{
|
|
|
|
|
return "query is empty";
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var table = Lua.NewTable();
|
|
|
|
|
m_dbConnection.Open();
|
2018-03-10 11:00:44 +00:00
|
|
|
|
string sql = "PRAGMA read_uncommitted =1;" + query;
|
2017-06-26 23:48:42 +00:00
|
|
|
|
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
|
|
|
|
|
SQLiteDataReader reader = command.ExecuteReader();
|
2018-03-10 11:00:44 +00:00
|
|
|
|
bool rows = reader.HasRows;
|
2017-06-26 23:48:42 +00:00
|
|
|
|
long rowCount = 0;
|
|
|
|
|
var columns = new List<string>();
|
|
|
|
|
for (int i = 0; i < reader.FieldCount; ++i) //Add all column names into list
|
|
|
|
|
{
|
|
|
|
|
columns.Add(reader.GetName(i));
|
|
|
|
|
}
|
|
|
|
|
while (reader.Read())
|
2018-03-10 11:00:44 +00:00
|
|
|
|
{
|
2017-06-26 23:48:42 +00:00
|
|
|
|
for (int i = 0; i < reader.FieldCount; ++i)
|
|
|
|
|
{
|
2018-03-10 11:00:44 +00:00
|
|
|
|
table[columns[i] + " " + rowCount.ToString()] = reader.GetValue(i);
|
2017-06-26 23:48:42 +00:00
|
|
|
|
}
|
|
|
|
|
rowCount += 1;
|
|
|
|
|
}
|
|
|
|
|
reader.Close();
|
|
|
|
|
m_dbConnection.Close();
|
2018-03-10 11:00:44 +00:00
|
|
|
|
if (rows == false)
|
2017-06-26 23:48:42 +00:00
|
|
|
|
{
|
|
|
|
|
return "No rows found";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return table;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (NullReferenceException)
|
|
|
|
|
{
|
|
|
|
|
return "Database not opened.";
|
|
|
|
|
}
|
|
|
|
|
catch (SQLiteException sqlEX)
|
|
|
|
|
{
|
|
|
|
|
m_dbConnection.Close();
|
|
|
|
|
return sqlEX.Message;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|