Skip to content

Instantly share code, notes, and snippets.

@mcnemesis
Created August 16, 2013 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mcnemesis/6250972 to your computer and use it in GitHub Desktop.
Save mcnemesis/6250972 to your computer and use it in GitHub Desktop.
A Simple, 1-class non-obtrusive No-SQL DB for Windows Phone 8, Windows Store + (RT)
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
namespace MyCHILD
{
class DataDictionary
{
public delegate void StoreInitiatedCallback();
/// <summary>
/// Name of the root folder containing the store items
/// </summary>
private const String DICTIONARY_ROOT = "DATA_DICTIONARY";
private List<String> _keys = new List<string>();
private const String _keyKEYS = ".KEYS";
//keys others are not allowed to use (for internal usage only)
private String[] _restrictedKeys = new String[] { _keyKEYS };
private StorageFolder rootFolder;
/// <summary>
/// All the KEYs in the Dictionary
/// </summary>
List<String> KEYS { get { return _keys; } }
internal async Task init(StoreInitiatedCallback callback) {
await _initRoot();
await loadKeys();
callback();
}
private async Task _initRoot()
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
try
{
await folder.CreateFolderAsync(DICTIONARY_ROOT, CreationCollisionOption.FailIfExists);
}
catch (Exception e) {
}
rootFolder = await folder.GetFolderAsync(DICTIONARY_ROOT);
}
private async Task loadKeys()
{
String jKEYS = await ReadString(_keyKEYS);
_keys = JsonConvert.DeserializeObject<List<String>>(jKEYS);
_keys = (_keys == null) ? new List<String>() : _keys;
}
public bool Exists(String KEY)
{
return _keys.Contains(_getSafeKey(KEY));
}
/// <summary>
/// Write a string to the Dictionary
/// Doesn't try to secure the key -- useful for writting meta-data
/// </summary>
/// <param name="KEY"></param>
/// <param name="DATA"></param>
/// <returns></returns>
async private Task<bool> _WriteString(string KEY, string DATA)
{
byte[] data = Encoding.UTF8.GetBytes(DATA);
try
{
StorageFile file = await rootFolder.CreateFileAsync(KEY, CreationCollisionOption.ReplaceExisting);
using (Stream s = await file.OpenStreamForWriteAsync())
{
await s.WriteAsync(data, 0, data.Length);
if (!Exists(KEY))
await _saveKEY(KEY);
}
return true;
}
catch (Exception e)
{
return false;
}
}
/// <summary>
/// Safely write a string to the Dictionary
/// </summary>
/// <param name="KEY"></param>
/// <param name="DATA"></param>
/// <returns></returns>
async public Task<bool> WriteString(string KEY, string DATA)
{
return await _WriteString(_getSafeKey(KEY), DATA);
}
async private Task<bool> _saveKEY(string KEY)
{
if (!_keys.Contains(KEY))
{
_keys.Add(KEY);
await _saveKEYS();
}
return true;
}
async private Task<bool> _saveKEYS()
{
String jKEYS = JsonConvert.SerializeObject(_keys, Formatting.Indented);
await _WriteString(_keyKEYS, jKEYS); //uses the internal/meta-data version of WriteString, which doesn't secure the key
return true;
}
private string _getSafeKey(string KEY)
{
if (_restrictedKeys.Contains(KEY))
return String.Format("_{0}_", KEY);
else
return KEY;
}
async public Task<string> ReadString(string KEY)
{
byte[] data;
try
{
StorageFile file = await rootFolder.GetFileAsync(KEY);
using (Stream s = await file.OpenStreamForReadAsync())
{
data = new byte[s.Length];
await s.ReadAsync(data, 0, (int)s.Length);
}
return Encoding.UTF8.GetString(data, 0, data.Length);
}
catch (Exception e)
{
}
return "";
}
async private Task<bool> _Delete(String KEY)
{
try
{
StorageFile file = await rootFolder.GetFileAsync(KEY);
await file.DeleteAsync();
return true;
}
catch (Exception e)
{
return false;
}
}
async public Task<bool> Delete(String KEY)
{
if (Exists(KEY))
{
return await _Delete(_getSafeKey(KEY));
}
else
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment