You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel.SqLite/UserCacheRepository.cs

171 lines
4.6 KiB

using SQLite;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using ZeroLevel.Services.Serialization;
namespace ZeroLevel.SqLite
{
public sealed class DataRecord
{
[PrimaryKey, AutoIncrement]
public long Id { get; set; }
[Indexed]
public string Key { get; set; }
public byte[] Data { get; set; }
}
public sealed class UserCacheRepository<T>
: BaseSqLiteDB<DataRecord>
where T : IBinarySerializable
{
#region Fields
private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
#endregion Fields
#region Ctor
public UserCacheRepository()
: base(typeof(T).Name)
{
CreateTable();
}
#endregion Ctor
#region API
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private string KEY(long userId, string name) => $"{userId}.{name}";
public bool AddOrUpdate(long userid, string name, T data)
{
var key = KEY(userid, name);
bool update = false;
_rwLock.EnterReadLock();
try
{
var count_obj = Count(r => r.Key == key);
if (count_obj > 0)
{
update = true;
}
}
catch (Exception ex)
{
Log.Error(ex, $"[UserCacheRepository] Fault search existing records by name ({name})");
// no return!
}
finally
{
_rwLock.ExitReadLock();
}
_rwLock.EnterWriteLock();
try
{
var body = MessageSerializer.Serialize(data);
if (update)
{
var r = Single(r => r.Key == key);
r.Data = body;
Update(r);
}
else
{
Append(new DataRecord
{
Data = body,
Key = key
});
}
return true;
}
catch (Exception ex)
{
Log.Error(ex, $"[UserCacheRepository] Fault insert record in storage. UserId: {userid}. Name '{name}'. Data: {typeof(T).Name}.");
}
finally
{
_rwLock.ExitWriteLock();
}
return false;
}
public void Remove(long userid, string name)
{
var key = KEY(userid, name);
_rwLock.EnterWriteLock();
try
{
Delete(r => r.Key == key);
}
catch (Exception ex)
{
Log.Error(ex, $"[UserCacheRepository] Fault remove record from db by name '{name}'. UserId: {userid}. Data: {typeof(T).Name}.");
}
finally
{
_rwLock.ExitWriteLock();
}
}
public long Count(long userid, string name)
{
var key = KEY(userid, name);
_rwLock.EnterWriteLock();
try
{
return Count(r => r.Key == key);
}
catch (Exception ex)
{
Log.Error(ex, $"[UserCacheRepository] Fault get count record from db by name '{name}'. UserId: {userid}. Data: {typeof(T).Name}.");
}
finally
{
_rwLock.ExitWriteLock();
}
return 0;
}
public IEnumerable<T> GetAll(long userid, string name)
{
var key = KEY(userid, name);
var result = new List<T>();
_rwLock.EnterReadLock();
try
{
foreach (var r in SelectBy(r=>r.Key == key))
{
var data = r.Data;
if (data != null)
{
result.Add(MessageSerializer.Deserialize<T>(data));
}
}
}
catch (Exception ex)
{
Log.Error(ex, $"[UserCacheRepository] Fault read all records by name: {name}. UserId: {userid}. Data: {typeof(T).Name}.");
}
finally
{
_rwLock.ExitReadLock();
}
return result;
}
#endregion API
#region IDisposable
protected override void DisposeStorageData()
{
}
#endregion IDisposable
}
}

Powered by TurnKey Linux.