blob: 749d16caa572ee97ffc04f95a83eb723a8ad9c3c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Data;
using System.Data.SQLite;
using Apache.Geode.Client;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace Apache.Geode.Plugins.SQLite
{
public class SqLiteImpl<TKey, TValue> : IPersistenceManager<TKey, TValue>
{
#region Factory Method
public static SqLiteImpl<TKey, TValue> Create()
{
return new SqLiteImpl<TKey, TValue>();
}
#endregion //Factory Method
#region IPersistenceManager<TKey,TValue> Members
public void Init(IRegion<TKey, TValue> region, Properties<string, string> diskProperties)
{
try
{
string pageSize, maxPageCount, persistenceDir;
m_tableName = region.Name;
if (diskProperties == null)
{
persistenceDir = DefaultPersistenceDir;
pageSize = DefaultPageSize;
maxPageCount = DefaultMaxPageCount;
}
else
{
persistenceDir = string.IsNullOrEmpty(diskProperties.Find(PersistenceDir)) ? DefaultPersistenceDir : diskProperties.Find(PersistenceDir);
pageSize = string.IsNullOrEmpty(diskProperties.Find(PageSize)) ? DefaultPageSize : diskProperties.Find(PageSize);
maxPageCount = string.IsNullOrEmpty(diskProperties.Find(MaxPageCount)) ? DefaultMaxPageCount : diskProperties.Find(MaxPageCount);
}
// create region db file
m_persistenceDir = Path.Combine(Directory.GetCurrentDirectory(), persistenceDir);
m_regionDir = Path.Combine(m_persistenceDir, m_tableName);
Directory.CreateDirectory(m_regionDir);
//create sqlite connection string
m_connectionString = string.Format("Data Source={0};Version=3;Page Size={1};Max Page Count={2};",
Path.Combine(m_regionDir, m_tableName + ".db"), pageSize, maxPageCount);
SqliteHelper.InitalizeSqLite(m_tableName, m_connectionString);
}
catch (Exception)
{
throw;
}
}
public TValue Read(TKey key)
{
try
{
return (TValue)SqliteHelper.GetValue(key, m_tableName, m_connectionString);
}
catch (Exception)
{
throw;
}
}
public void Write(TKey key, TValue value)
{
try
{
SqliteHelper.InsertKeyValue(key, value, m_tableName, m_connectionString);
}
catch (Exception)
{
throw;
}
}
public bool WriteAll()
{
throw new NotImplementedException();
}
public bool ReadAll()
{
throw new NotImplementedException();
}
public void Destroy(TKey key)
{
try
{
SqliteHelper.RemoveKey(key, m_tableName, m_connectionString);
}
catch (Exception)
{
throw;
}
}
public void Close()
{
try
{
SqliteHelper.CloseSqlite();
Directory.Delete(m_regionDir, true);
Directory.Delete(m_persistenceDir);
}
catch (Exception)
{
}
}
#endregion //IPersistenceManager<TKey,TValue> Members
#region Data Members
private string m_connectionString;
private string m_tableName;
private string m_persistenceDir;
private string m_regionDir;
#endregion
#region Constants
public static readonly string PersistenceDir = "PersistenceDirectory";
public static readonly string MaxPageCount = "max_page_count";
public static readonly string PageSize = "page_size";
public static readonly string DefaultPersistenceDir = "GeodeRegionData";
public static readonly string DefaultMaxPageCount = "2147483646";
public static readonly string DefaultPageSize = "65536";
#endregion
}
internal static class SqliteHelper
{
public static byte[] GetBytes(object obj)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
public static object GetObject(byte[] bytes)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream(bytes);
return bf.Deserialize(ms);
}
public static void InitalizeSqLite(string tableName, string connectionString)
{
//construct create table query for this region
string query = string.Format("CREATE TABLE IF NOT EXISTS {0}(key BLOB PRIMARY KEY,value BLOB);", tableName);
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
using (SQLiteCommand command = new SQLiteCommand(query, conn))
{
command.ExecuteNonQuery();
}
}
}
public static void ExecutePragma(string pragmaName, string pragmaValue, string connectionString)
{
string pragmaQuery = string.Format("PRAGMA {0} = {1};", pragmaName, pragmaValue);
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
using (SQLiteCommand command = new SQLiteCommand(pragmaQuery, conn))
{
command.ExecuteNonQuery();
}
}
}
public static void InsertKeyValue(object key, object value, string tableName, string connectionString)
{
//construct query
string query = string.Format("REPLACE INTO {0} VALUES(@key,@value);", tableName);
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
using (SQLiteCommand command = new SQLiteCommand(query, conn))
{
command.Parameters.Add(new SQLiteParameter("@key", key));
command.Parameters.Add(new SQLiteParameter("@value", GetBytes(value)));
command.ExecuteNonQuery();
}
}
}
public static object GetValue(object key, string tableName, string connectionString)
{
//construct query
string query = string.Format("SELECT value FROM {0} WHERE key=@key;", tableName);
object retValue;
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
using (SQLiteCommand command = new SQLiteCommand(query, conn))
{
// create parameters and execute
command.Parameters.Add(new SQLiteParameter("@key", key));
retValue = SqliteHelper.GetObject((byte[])command.ExecuteScalar());
}
}
return retValue;
}
public static void RemoveKey(object key, string tableName, string connectionString)
{
//construct query
string query = string.Format("DELETE FROM {0} WHERE key=@key;", tableName);
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
using (SQLiteCommand command = new SQLiteCommand(query, conn))
{
// create parameters and execute
command.Parameters.Add(new SQLiteParameter("@key", key));
command.ExecuteNonQuery();
}
}
}
public static void CloseSqlite()
{
// remove the region db files
//Directory.Delete(m_persistenceDir, true);
}
}
}