187 lines
5.7 KiB
C#
187 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using oodb.descriptor;
|
|
using oodb.mapping;
|
|
using oodb.persistence;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Xml;
|
|
using System.CodeDom;
|
|
using System.ComponentModel;
|
|
using System.Reflection;
|
|
using oodb.mapping.collections;
|
|
namespace oodb
|
|
{
|
|
public class OODB
|
|
{
|
|
|
|
public PersistenceCache PersistenceCache { get; }
|
|
public StorageAdapter StorageAdapter { get; }
|
|
|
|
internal Dictionary<Type, Descriptor> descriptors = new Dictionary<Type, Descriptor>();
|
|
internal Dictionary<Type, FlatTypeMapping> flatTypeMappings = new Dictionary<Type, FlatTypeMapping>();
|
|
|
|
|
|
public OODB(String storagePath)
|
|
:this(new DirectoryInfo(storagePath))
|
|
{
|
|
}
|
|
|
|
public OODB(DirectoryInfo storageDirectory)
|
|
{
|
|
PersistenceCache = new PersistenceCache(this);
|
|
StorageAdapter = new StorageAdapter(this,storageDirectory);
|
|
|
|
PopulateFlatMappings();
|
|
|
|
AppDomain.CurrentDomain.ProcessExit += (sender, e) => this.Close();
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
StorageAdapter.Close();
|
|
}
|
|
|
|
public void Prepare()
|
|
{
|
|
foreach (Descriptor descriptor in descriptors.Values)
|
|
{
|
|
descriptor.Initialize();
|
|
}
|
|
}
|
|
|
|
|
|
public OODB Add<T>() where T : Persistent => Add(typeof(T));
|
|
public OODB Add(Type type)
|
|
{
|
|
GetDescriptor(type);
|
|
return this;
|
|
}
|
|
|
|
public void Save(IEnumerable<Persistent> persistents)
|
|
{
|
|
foreach (Persistent persistent in persistents)
|
|
Save(persistent);
|
|
}
|
|
public void Save(Persistent o)
|
|
{
|
|
PersistenceCache.Touch(o);
|
|
StorageAdapter.Save(o);
|
|
}
|
|
|
|
public void Ensure(Persistent o)
|
|
{
|
|
if (!StorageAdapter.Knows(o.GetType(), o.PersistenceID))
|
|
Save(o);
|
|
}
|
|
|
|
public T Load<T>(Guid persistenceID) where T: Persistent
|
|
{
|
|
return (T)Load(typeof(T), persistenceID);
|
|
}
|
|
public Persistent Load(Type type,Guid persistenceID)
|
|
{
|
|
if (persistenceID.Equals(Guid.Empty))
|
|
return null;
|
|
|
|
try {
|
|
return PersistenceCache.Get(type, persistenceID);
|
|
} catch (KeyNotFoundException)
|
|
{
|
|
Type realType = StorageAdapter.GetDiscriminator(type, persistenceID);
|
|
Persistent persistent = Activator.CreateInstance(type,true) as Persistent;
|
|
|
|
persistent.PersistenceID = persistenceID;
|
|
PersistenceCache.Touch(persistent);
|
|
|
|
GetDescriptor(realType).Attach(persistent);
|
|
|
|
StorageAdapter.Restore(persistent);
|
|
|
|
return persistent;
|
|
}
|
|
}
|
|
|
|
public IEnumerable<T> List<T>() where T:Persistent => List(typeof(T)).Select((x) => (T)x);
|
|
public IEnumerable<Persistent> List(Type type)
|
|
{
|
|
return ListIdentities(type).Select((x) => Load(x.Value, x.Key));
|
|
}
|
|
|
|
private IEnumerable<KeyValuePair<Guid,Type>> ListIdentities(Type type)
|
|
{
|
|
return StorageAdapter.List(GetDescriptor(type));
|
|
}
|
|
|
|
|
|
|
|
public Type LookupType(string fullName)
|
|
{
|
|
foreach (Type t in descriptors.Keys)
|
|
if (t.FullName.Equals(fullName))
|
|
return t;
|
|
throw new KeyNotFoundException(fullName);
|
|
}
|
|
|
|
public Descriptor GetDescriptor(Type type)
|
|
{
|
|
if (!descriptors.ContainsKey(type))
|
|
{
|
|
descriptors[type] = new Descriptor(this, type);
|
|
}
|
|
return descriptors[type];
|
|
}
|
|
public Descriptor GetDescriptor<T>() => GetDescriptor(typeof(T));
|
|
|
|
public FlatTypeMapping GetFlatTypeMapping(Type type)
|
|
{
|
|
if (!flatTypeMappings.ContainsKey(type))
|
|
{
|
|
if (type.IsArray)
|
|
{
|
|
flatTypeMappings[type] = new ArrayMapping(this, type);
|
|
}
|
|
else if (type.IsSubclassOf(typeof(Persistent)))
|
|
{
|
|
Add(type);
|
|
}
|
|
else if (type.IsGenericType && ((type.GetGenericTypeDefinition() == typeof(List<>)) || (type.GetGenericTypeDefinition() == typeof(IList<>))))
|
|
{
|
|
FlatTypeMapping elementMapping = GetFlatTypeMapping(type.GetGenericArguments()[0]);
|
|
flatTypeMappings[type] = new ListMapping(this, type);
|
|
} else {
|
|
throw new KeyNotFoundException();
|
|
}
|
|
}
|
|
return flatTypeMappings[type];
|
|
}
|
|
|
|
public ExtendedFieldHandling CreateExtendedFieldHandling(FieldInfo fieldInfo)
|
|
{
|
|
if (fieldInfo.FieldType.IsGenericType){
|
|
Type genericTypeDefinition = fieldInfo.FieldType.GetGenericTypeDefinition();
|
|
|
|
if (genericTypeDefinition == typeof(ISet<>))
|
|
{
|
|
return new ISetExtendedHandling(this, fieldInfo);
|
|
}
|
|
|
|
}
|
|
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
|
|
private void PopulateFlatMappings()
|
|
{
|
|
flatTypeMappings[typeof(string)] = new StringMapping(this);
|
|
flatTypeMappings[typeof(int)] = new IntegerMapping(this);
|
|
flatTypeMappings[typeof(short)] = new IntegerMapping(this);
|
|
flatTypeMappings[typeof(byte)] = new IntegerMapping(this);
|
|
flatTypeMappings[typeof(float)] = new DoubleMapping(this);
|
|
flatTypeMappings[typeof(double)] = new DoubleMapping(this);
|
|
}
|
|
|
|
}
|
|
}
|