using Mono.Data.Sqlite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using SabreTools.Helper;
namespace SabreTools
{
///
/// Entry class for the RombaSharp application
///
public class RombaSharp
{
// General settings
private int _workers; //Number of parallel threads
private string _logdir; //Log folder location
private string _tmpdir; //Temp folder location
private string _webdir; // Web frontend location
private string _baddir; // Fail-to-unpack file folder location
private int _verbosity; // Verbosity of the output
private int _cores; // Forced CPU cores
// DatRoot settings
private string _dats; // DatRoot folder location
private string _db; // Database name
// Depot settings
private Dictionary> _depots; // Folder location, Max size
// Server settings
private int _port; // Web server port
// Other private variables
private string _config = "config.xml";
private string _connectionString;
private Logger _logger;
///
/// Create a new RombaSharp object
///
/// Logger object for file and console output
public RombaSharp(Logger logger)
{
_logger = logger;
InitializeConfiguration();
InitializeDatabase();
}
public static void Main(string[] args)
{
}
///
/// Initialize the Romba application from XML config
///
private void InitializeConfiguration()
{
// Get default values if they're not written
int workers = 4,
verbosity = 1,
cores = 4,
port = 4003;
string logdir = "logs",
tmpdir = "tmp",
webdir = "web",
baddir = "bad",
dats = "dats",
db = "db",
connectionString = "";
Dictionary> depots = new Dictionary>();
// Get the XML text reader for the configuration file, if possible
XmlTextReader xtr = DatTools.GetXmlTextReader(_config, _logger);
/* XML file structure
4
logs
tmp
web
bad
1
4
dats
db
depot
40000
true
4003
*/
// Now parse the XML file for settings
if (xtr != null)
{
xtr.MoveToContent();
while (!xtr.EOF)
{
// We only want elements
if (xtr.NodeType != XmlNodeType.Element)
{
xtr.Read();
continue;
}
switch (xtr.Name)
{
case "workers":
workers = xtr.ReadElementContentAsInt();
break;
case "logdir":
logdir = xtr.ReadElementContentAsString();
break;
case "tmpdir":
tmpdir = xtr.ReadElementContentAsString();
break;
case "webdir":
webdir = xtr.ReadElementContentAsString();
break;
case "baddir":
baddir = xtr.ReadElementContentAsString();
break;
case "verbosity":
verbosity = xtr.ReadElementContentAsInt();
break;
case "cores":
cores = xtr.ReadElementContentAsInt();
break;
case "dats":
dats = xtr.ReadElementContentAsString();
break;
case "db":
db = xtr.ReadElementContentAsString();
break;
case "depot":
XmlReader subreader = xtr.ReadSubtree();
if (subreader != null)
{
string root = "";
long maxsize = -1;
bool online = true;
while (!subreader.EOF)
{
// We only want elements
if (subreader.NodeType != XmlNodeType.Element)
{
subreader.Read();
continue;
}
switch (subreader.Name)
{
case "root":
root = subreader.ReadElementContentAsString();
break;
case "maxsize":
maxsize = subreader.ReadElementContentAsLong();
break;
case "online":
online = subreader.ReadElementContentAsBoolean();
break;
default:
subreader.Read();
break;
}
}
try
{
depots.Add(root, new Tuple(maxsize, online));
}
catch
{
// Ignore add errors
}
}
xtr.Skip();
break;
case "port":
port = xtr.ReadElementContentAsInt();
break;
default:
xtr.Read();
break;
}
}
}
// Now validate the values given
if (workers < 1)
{
workers = 1;
}
if (workers > 8)
{
workers = 8;
}
if (!Directory.Exists(logdir))
{
Directory.CreateDirectory(logdir);
}
if (!Directory.Exists(tmpdir))
{
Directory.CreateDirectory(tmpdir);
}
if (!Directory.Exists(webdir))
{
Directory.CreateDirectory(webdir);
}
if (!Directory.Exists(baddir))
{
Directory.CreateDirectory(baddir);
}
if (verbosity < 0)
{
verbosity = 0;
}
if (verbosity > 3)
{
verbosity = 3;
}
if (cores < 1)
{
cores = 1;
}
if (cores > 16)
{
cores = 16;
}
if (!Directory.Exists(dats))
{
Directory.CreateDirectory(dats);
}
db = Path.GetFileNameWithoutExtension(db) + ".sqlite";
connectionString = "Data Source=" + _db + ";Version = 3;";
foreach (string key in depots.Keys)
{
if (!Directory.Exists(key))
{
Directory.CreateDirectory(key);
}
}
if (port < 0)
{
port = 0;
}
if (port > 65535)
{
port = 65535;
}
// Finally set all of the fields
_workers = workers;
_logdir = logdir;
_tmpdir = tmpdir;
_webdir = webdir;
_baddir = baddir;
_verbosity = verbosity;
_cores = cores;
_dats = dats;
_db = db;
_connectionString = connectionString;
_depots = depots;
_port = port;
}
///
/// Initialize the Romba database
///
private void InitializeDatabase()
{
// Make sure the db is set
if (String.IsNullOrEmpty(_db))
{
_db = "db.sqlite";
_connectionString = "Data Source=" + _db + ";Version = 3;";
}
// Make sure the file exists
if (!File.Exists(_db))
{
SqliteConnection.CreateFile(_db);
}
// Connect to the file
SqliteConnection dbc = new SqliteConnection(_connectionString);
dbc.Open();
// Initialize the database schema
try
{
string query = @"
CREATE TABLE IF NOT EXISTS data (
'id' INTEGER NOT NULL
'key' TEXT NOT NULL
'value' TEXT NOT NULL
)";
SqliteCommand slc = new SqliteCommand(query, dbc);
slc.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
finally
{
// Close the database connection
dbc.Close();
}
}
///
/// Populate or refresh the database information
///
private void RefreshDatabase()
{
// Make sure the dats dir is set
if (String.IsNullOrEmpty(_dats))
{
_dats = "dats";
}
// Make sure the folder exists
if (!Directory.Exists(_dats))
{
Directory.CreateDirectory(_dats);
}
// Now parse the directory into an internal Dat then insert
foreach (string file in Directory.EnumerateFiles(_dats, "*", SearchOption.AllDirectories))
{
Dat datdata = new Dat();
datdata = DatTools.Parse(file, 0, 0, datdata, _logger);
Rom romdata = FileTools.GetSingleFileInfo(file);
}
}
///
/// Process a datfile and insert it into the database
///
/// Dat object representing the data to insert
/// Rom object representing the Dat file itself
private void InsertDatIntoDatabase(Dat datdata, Rom romdata)
{
// Make sure the db is set
if (String.IsNullOrEmpty(_db))
{
_db = "db.sqlite";
_connectionString = "Data Source=" + _db + ";Version = 3;";
}
// Make sure the file exists
if (!File.Exists(_db))
{
SqliteConnection.CreateFile(_db);
InitializeDatabase();
}
// Open a connection to the database
using (SqliteConnection slc = new SqliteConnection(_connectionString))
{
// For each key
foreach (string key in datdata.Files.Keys)
{
// For each Rom in the list
foreach (Rom file in datdata.Files[key])
{
// Try to find the hash in the set
// If it exists, see if there's any missing information
// If it doesn't exist, insert it completely
}
}
}
}
}
}