Split off CDataBase into individual classes (more to come)

This commit is contained in:
Flamefire committed 2014-05-07 00:37:23 +02:00
1 parent fda3541e47
commit cc08e01590
6 files changed
+1663 -1483

No files matched your search

+39 -1483
View File
File diff suppressed because it is too large. Load diff
+234
View File
@@ -0,0 +1,234 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using Vocaluxe.Base;
using VocaluxeLib.Draw;
#if WIN
using System.Data.SQLite;
#else
using Mono.Data.Sqlite;
#endif
namespace Vocaluxe.Lib.Database
{
public class CCoverDB : CDatabaseBase
{
//You have to lock all actions using cover connection or transaction, otherwhise order is not guaranted
private readonly object _CoverMutex = new object();
private SQLiteTransaction _TransactionCover;
public CCoverDB(string filePath) : base(filePath) {}
public override bool Init()
{
if (!base.Init())
return false;
if (_Version < 0)
return _CreateCoverDB();
if (_Version < CSettings.DatabaseCoverVersion)
throw new NotImplementedException("Upgrading of cover DB not implemented");
return true;
}
public override void Close()
{
//Do commit and close atomicly otherwhise we may loose changes
lock (_CoverMutex)
{
_CommitCovers();
base.Close();
}
}
public bool GetCover(string coverPath, ref CTexture tex, int maxSize)
{
if (_Connection == null)
return false;
if (!File.Exists(coverPath))
{
CLog.LogError("Can't find File: " + coverPath);
return false;
}
lock (_CoverMutex)
{
//Double check here because we may have just closed our connection
if (_Connection == null)
return false;
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "SELECT id, width, height FROM Cover WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
SQLiteDataReader reader = command.ExecuteReader();
if (reader != null && reader.HasRows)
{
reader.Read();
int id = reader.GetInt32(0);
int w = reader.GetInt32(1);
int h = reader.GetInt32(2);
reader.Close();
command.CommandText = "SELECT Data FROM CoverData WHERE CoverID = @id";
command.Parameters.Add("@id", DbType.Int32).Value = id;
reader = command.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
byte[] data = _GetBytes(reader);
reader.Dispose();
tex = CDraw.EnqueueTexture(w, h, data);
return true;
}
}
else
{
if (reader != null)
reader.Close();
if (_TransactionCover == null)
_TransactionCover = _Connection.BeginTransaction();
Bitmap origin;
try
{
origin = new Bitmap(coverPath);
}
catch (Exception)
{
CLog.LogError("Error loading Texture: " + coverPath);
return false;
}
int w = maxSize;
int h = maxSize;
byte[] data;
try
{
if (origin.Width >= origin.Height && origin.Width > w)
h = (int)Math.Round((float)w / origin.Width * origin.Height);
else if (origin.Height > origin.Width && origin.Height > h)
w = (int)Math.Round((float)h / origin.Height * origin.Width);
using (var bmp = new Bitmap(w, h))
{
using (Graphics g = Graphics.FromImage(bmp))
g.DrawImage(origin, new Rectangle(0, 0, w, h));
data = new byte[w * h * 4];
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bmpData.Scan0, data, 0, w * h * 4);
bmp.UnlockBits(bmpData);
}
}
finally
{
origin.Dispose();
}
tex = CDraw.EnqueueTexture(w, h, data);
command.CommandText = "INSERT INTO Cover (Path, width, height) VALUES (@path, @w, @h)";
command.Parameters.Add("@w", DbType.Int32).Value = w;
command.Parameters.Add("@h", DbType.Int32).Value = h;
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
command.ExecuteNonQuery();
command.CommandText = "SELECT id FROM Cover WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
reader = command.ExecuteReader();
if (reader != null)
{
reader.Read();
int id = reader.GetInt32(0);
reader.Dispose();
command.CommandText = "INSERT INTO CoverData (CoverID, Data) VALUES (@id, @data)";
command.Parameters.Add("@id", DbType.Int32).Value = id;
command.Parameters.Add("@data", DbType.Binary, 20).Value = data;
command.ExecuteReader();
return true;
}
}
}
}
return false;
}
public void CommitCovers()
{
lock (_CoverMutex)
{
_CommitCovers();
}
}
/// <summary>
/// You have to hold the CoverMutex when calling this!
/// </summary>
private void _CommitCovers()
{
if (_TransactionCover == null)
return;
_TransactionCover.Commit();
_TransactionCover.Dispose();
_TransactionCover = null;
}
private bool _CreateCoverDB()
{
try
{
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "CREATE TABLE IF NOT EXISTS Version (Value INTEGER NOT NULL);";
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO Version (Value) VALUES(@Value)";
command.Parameters.Add("@Value", DbType.Int32).Value = CSettings.DatabaseCoverVersion;
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE IF NOT EXISTS Cover ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
"Path TEXT NOT NULL, width INTEGER NOT NULL, height INTEGER NOT NULL);";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE IF NOT EXISTS CoverData ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
"CoverID INTEGER NOT NULL, Data BLOB NOT NULL);";
command.ExecuteNonQuery();
}
}
catch (Exception e)
{
CLog.LogError("Error creating Cover DB " + e);
return false;
}
return true;
}
}
}
+112
View File
@@ -0,0 +1,112 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.IO;
using Vocaluxe.Base;
#if WIN
using System.Data.SQLite;
#else
using Mono.Data.Sqlite;
#endif
namespace Vocaluxe.Lib.Database
{
public class CDatabaseBase
{
protected readonly string _FilePath;
protected SQLiteConnection _Connection;
protected int _Version; //Version of the database (value of row "Value" in table "Version") or -1 if none
public CDatabaseBase(string filePath)
{
_FilePath = filePath;
}
public virtual bool Init()
{
_Connection = new SQLiteConnection("Data Source=" + _FilePath);
try
{
_Connection.Open();
}
catch (Exception)
{
_Connection.Dispose();
_Connection = null;
return false;
}
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "SELECT Value FROM Version";
SQLiteDataReader reader = null;
try
{
reader = command.ExecuteReader();
}
catch (Exception) {}
if (reader == null || !reader.Read() || reader.FieldCount == 0)
_Version = -1;
else
_Version = reader.GetInt32(0);
if (reader != null)
reader.Dispose();
}
return true;
}
public virtual void Close()
{
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
protected static long _UnixTimeToTicks(int unixTime)
{
var t70 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
t70 = t70.AddSeconds(unixTime);
return t70.Ticks;
}
protected static byte[] _GetBytes(SQLiteDataReader reader, int field = 0)
{
const int chunkSize = 2 * 1024;
var buffer = new byte[chunkSize];
long fieldOffset = 0;
using (var stream = new MemoryStream())
{
int bytesRead;
while ((bytesRead = (int)reader.GetBytes(field, fieldOffset, buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, bytesRead);
fieldOffset += bytesRead;
}
return stream.ToArray();
}
}
}
}
File diff suppressed because it is too large. Load diff
+253
View File
@@ -0,0 +1,253 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using Vocaluxe.Base;
using VocaluxeLib.Draw;
#if WIN
using System.Data.SQLite;
#else
using Mono.Data.Sqlite;
#endif
namespace Vocaluxe.Lib.Database
{
public class CResourceDB : CDatabaseBase
{
#if DEBUG
private readonly string[] _FilesV1 = new string[]
{
"Logo_voc.png", "PerfectNoteStar.png", "redDot.png", "blueDot.png", "brunzel.png", "Darkice.png", "flokuep.png", "flamefire.png", "bohning.png", "mesand.png",
"babene03.png", "pantero.png", "Pinky007.png"
};
#endif
public CResourceDB(string filePath) : base(filePath) {}
public override bool Init()
{
if (!base.Init())
return false;
if (_Version < 0)
{
CLog.LogError("Can't find Ressource-DB!");
return false;
}
if (_Version < CSettings.DatabaseCreditsRessourcesVersion)
{
#if DEBUG
return _CreateDB() && _UpdateV1();
#else
CLog.LogError("Upgrading Ressource-DB not possible");
return false;
#endif
}
return true;
}
public bool GetCreditsRessource(string fileName, ref CTexture tex)
{
if (_Connection == null)
return false;
bool result = false;
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "SELECT id, width, height FROM Images WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String, 0).Value = fileName;
SQLiteDataReader reader = command.ExecuteReader();
if (reader != null && reader.HasRows)
{
reader.Read();
int id = reader.GetInt32(0);
int w = reader.GetInt32(1);
int h = reader.GetInt32(2);
reader.Close();
command.CommandText = "SELECT Data FROM ImageData WHERE ImageID = @id";
command.Parameters.Add("@id", DbType.Int32).Value = id;
reader = command.ExecuteReader();
if (reader.HasRows)
{
result = true;
reader.Read();
byte[] data = _GetBytes(reader);
tex = CDraw.AddTexture(w, h, data);
}
}
if (reader != null)
reader.Dispose();
}
return result;
}
#if DEBUG
//Update from V0 (empty) to V1
private bool _UpdateV1()
{
if (_Connection == null || _Version >= 1)
return false;
using (SQLiteTransaction transaction = _Connection.BeginTransaction())
{
try
{
foreach (string file in _FilesV1)
{
string filePath = Path.Combine(Environment.CurrentDirectory, file);
if (!_AddImageToCreditsDB(filePath, transaction))
{
transaction.Rollback();
return false;
}
}
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.Transaction = transaction;
command.CommandText = "Update Version SET Value=@Value)";
command.Parameters.Add("@Value", DbType.Int32).Value = 1;
command.ExecuteNonQuery();
}
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
return false;
}
}
return true;
}
//If you want to add an image to db, call this method!
private bool _AddImageToCreditsDB(string imagePath, SQLiteTransaction transaction)
{
if (_Connection == null || !File.Exists(imagePath))
return false;
Bitmap origin;
try
{
origin = new Bitmap(imagePath);
}
catch (Exception)
{
CLog.LogError("Error loading image: " + imagePath);
return false;
}
try
{
int w = origin.Width;
int h = origin.Height;
byte[] data = new byte[w * h * 4];
BitmapData bmpData = origin.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bmpData.Scan0, data, 0, w * h * 4);
origin.UnlockBits(bmpData);
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.Transaction = transaction;
command.CommandText = "INSERT INTO Images (Path, width, height) VALUES (@path, @w, @h)";
command.Parameters.Add("@path", DbType.String).Value = Path.GetFileName(imagePath);
command.Parameters.Add("@w", DbType.Int32).Value = w;
command.Parameters.Add("@h", DbType.Int32).Value = h;
command.ExecuteNonQuery();
}
int id = -1;
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.Transaction = transaction;
command.CommandText = "SELECT id FROM Images WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String, 0).Value = Path.GetFileName(imagePath);
using (SQLiteDataReader reader = command.ExecuteReader())
{
if (reader != null)
{
reader.Read();
id = reader.GetInt32(0);
}
}
}
if (id < 0)
return false;
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.Transaction = transaction;
command.CommandText = "INSERT INTO ImageData (ImageID, Data) VALUES (@id, @data)";
command.Parameters.Add("@id", DbType.Int32).Value = id;
command.Parameters.Add("@data", DbType.Binary).Value = data;
command.ExecuteNonQuery();
return true;
}
}
catch (Exception)
{
return false;
}
finally
{
origin.Dispose();
}
}
private bool _CreateDB()
{
if (_Connection == null)
return false;
try
{
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.CommandText = "CREATE TABLE IF NOT EXISTS Version (Value INTEGER NOT NULL);";
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO Version (Value) VALUES(0)";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE IF NOT EXISTS Images ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
"Path TEXT NOT NULL, width INTEGER NOT NULL, height INTEGER NOT NULL);";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE IF NOT EXISTS ImageData ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
"ImageID INTEGER NOT NULL, Data BLOB NOT NULL);";
command.ExecuteNonQuery();
}
}
catch (Exception e)
{
CLog.LogError("Error creating Ressource DB " + e);
return false;
}
return true;
}
#endif
}
}
+4
View File
@@ -219,6 +219,10 @@
<Compile Include="Base\CPlaylistElement.cs" />
<Compile Include="Base\CRecord.cs" />
<Compile Include="COSFunctions.cs" />
<Compile Include="Lib\Database\CCoverDB.cs" />
<Compile Include="Lib\Database\CDatabaseBase.cs" />
<Compile Include="Lib\Database\CHighscoreDB.cs" />
<Compile Include="Lib\Database\CResourceDB.cs" />
<Compile Include="Lib\Sound\Playback\CAudioStreamBase.cs" />
<Compile Include="Lib\Sound\Playback\CPlaybackBase.cs" />
<Compile Include="Lib\Sound\Playback\CRingBuffer.cs" />