📄 sqlitefunction.cs
字号:
namespace Imps.Client.Data
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
public abstract class SQLiteFunction : IDisposable
{
private SQLiteBase _base;
private SQLiteCollation _CompareFunc;
private Dictionary<long, object> _contextDataList = new Dictionary<long, object>();
private SQLiteCallback _FinalFunc;
private IntPtr _interopCookie;
private SQLiteCallback _InvokeFunc;
private static List<SQLiteFunctionAttribute> _registeredFunctions = new List<SQLiteFunctionAttribute>();
private SQLiteCallback _StepFunc;
static SQLiteFunction()
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
int length = assemblies.Length;
AssemblyName name = Assembly.GetCallingAssembly().GetName();
for (int i = 0; i < length; i++)
{
Type[] types;
bool flag = false;
try
{
AssemblyName[] referencedAssemblies = assemblies[i].GetReferencedAssemblies();
int num3 = referencedAssemblies.Length;
for (int j = 0; j < num3; j++)
{
if (referencedAssemblies[j].Name == name.Name)
{
flag = true;
break;
}
}
if (!flag)
{
continue;
}
types = assemblies[i].GetTypes();
}
catch (ReflectionTypeLoadException exception)
{
types = exception.Types;
}
int num5 = types.Length;
for (int k = 0; k < num5; k++)
{
if (types[k] != null)
{
object[] customAttributes = types[k].GetCustomAttributes(typeof(SQLiteFunctionAttribute), false);
int num7 = customAttributes.Length;
for (int m = 0; m < num7; m++)
{
SQLiteFunctionAttribute attribute = customAttributes[m] as SQLiteFunctionAttribute;
if (attribute != null)
{
attribute._instanceType = types[k];
_registeredFunctions.Add(attribute);
}
}
}
}
}
}
protected SQLiteFunction()
{
}
internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase)
{
List<SQLiteFunction> list = new List<SQLiteFunction>();
List<SQLiteFunctionAttribute>.Enumerator enumerator = _registeredFunctions.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
SQLiteFunctionAttribute attribute = enumerator.get_Current();
SQLiteFunction function = (SQLiteFunction) Activator.CreateInstance(attribute._instanceType);
function._base = sqlbase;
function._InvokeFunc = (attribute.FuncType == FunctionType.Scalar) ? new SQLiteCallback(function.ScalarCallback) : null;
function._StepFunc = (attribute.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(function.StepCallback) : null;
function._FinalFunc = (attribute.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(function.FinalCallback) : null;
function._CompareFunc = (attribute.FuncType == FunctionType.Collation) ? new SQLiteCollation(function.CompareCallback) : null;
if (attribute.FuncType != FunctionType.Collation)
{
function._interopCookie = sqlbase.CreateFunction(attribute.Name, attribute.Arguments, function._InvokeFunc, function._StepFunc, function._FinalFunc);
}
else
{
function._interopCookie = sqlbase.CreateCollation(attribute.Name, function._CompareFunc);
}
list.Add(function);
}
}
finally
{
enumerator.Dispose();
}
SQLiteFunction[] functionArray = new SQLiteFunction[list.get_Count()];
list.CopyTo(functionArray, 0);
return functionArray;
}
public virtual int Compare(string param1, string param2)
{
return 0;
}
internal int CompareCallback(int len1, IntPtr ptr1, int len2, IntPtr ptr2)
{
return this.Compare(this._base.ToString(ptr1, len1), this._base.ToString(ptr2, len2));
}
internal object[] ConvertParams(int nArgs, IntPtr argsptr)
{
object[] objArray = new object[nArgs];
IntPtr[] ptrArray = new IntPtr[nArgs];
Marshal.Copy(argsptr, ptrArray, 0, nArgs);
for (int i = 0; i < nArgs; i++)
{
switch (this._base.GetParamValueType(ptrArray[i]))
{
case TypeAffinity.Int64:
objArray[i] = this._base.GetParamValueInt64(ptrArray[i]);
break;
case TypeAffinity.Double:
objArray[i] = this._base.GetParamValueDouble(ptrArray[i]);
break;
case TypeAffinity.Text:
objArray[i] = this._base.GetParamValueText(ptrArray[i]);
break;
case TypeAffinity.Blob:
{
int nLength = (int) this._base.GetParamValueBytes(ptrArray[i], 0, null, 0, 0);
byte[] bDest = new byte[nLength];
this._base.GetParamValueBytes(ptrArray[i], 0, bDest, 0, nLength);
objArray[i] = bDest;
break;
}
case TypeAffinity.Null:
objArray[i] = DBNull.Value;
break;
case TypeAffinity.DateTime:
objArray[i] = this._base.ToDateTime(this._base.GetParamValueText(ptrArray[i]));
break;
}
}
return objArray;
}
public void Dispose()
{
this.Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Dictionary<long, object>.Enumerator enumerator = this._contextDataList.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
IDisposable disposable = enumerator.get_Current().get_Value() as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
finally
{
enumerator.Dispose();
}
this._contextDataList.Clear();
this._InvokeFunc = null;
this._StepFunc = null;
this._FinalFunc = null;
this._CompareFunc = null;
this._base = null;
this._contextDataList = null;
}
}
public virtual object Final(object contextData)
{
return null;
}
internal void FinalCallback(IntPtr context, int nArgs, IntPtr argsptr)
{
long num = (long) this._base.AggregateContext(context);
object contextData = null;
if (this._contextDataList.ContainsKey(num))
{
contextData = this._contextDataList.get_Item(num);
this._contextDataList.Remove(num);
}
this.SetReturnValue(context, this.Final(contextData));
IDisposable disposable = contextData as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
public virtual object Invoke(object[] args)
{
return null;
}
internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr)
{
this.SetReturnValue(context, this.Invoke(this.ConvertParams(nArgs, argsptr)));
}
private void SetReturnValue(IntPtr context, object returnValue)
{
if ((returnValue == null) || (returnValue == DBNull.Value))
{
this._base.ReturnNull(context);
}
else
{
Type typ = returnValue.GetType();
if (typ == typeof(DateTime))
{
this._base.ReturnText(context, this._base.ToString((DateTime) returnValue));
}
else
{
Exception exception = returnValue as Exception;
if (exception != null)
{
this._base.ReturnError(context, exception.Message);
}
else
{
switch (Imps.Client.Data.SQLiteConvert.TypeToAffinity(typ))
{
case TypeAffinity.Int64:
this._base.ReturnInt64(context, Convert.ToInt64(returnValue, CultureInfo.CurrentCulture));
return;
case TypeAffinity.Double:
this._base.ReturnDouble(context, Convert.ToDouble(returnValue, CultureInfo.CurrentCulture));
return;
case TypeAffinity.Text:
this._base.ReturnText(context, returnValue.ToString());
return;
case TypeAffinity.Blob:
this._base.ReturnBlob(context, (byte[]) returnValue);
return;
case TypeAffinity.Null:
this._base.ReturnNull(context);
return;
}
}
}
}
}
public virtual void Step(object[] args, int stepNumber, ref object contextData)
{
}
internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr)
{
int stepNumber = this._base.AggregateCount(context);
object contextData = null;
long num2 = (long) this._base.AggregateContext(context);
if (stepNumber > 1)
{
contextData = this._contextDataList.get_Item(num2);
}
this.Step(this.ConvertParams(nArgs, argsptr), stepNumber, ref contextData);
this._contextDataList.set_Item(num2, contextData);
}
internal static void UnbindFunctions(SQLiteBase sqlbase, SQLiteFunction[] ar)
{
if (ar != null)
{
int length = ar.Length;
for (int i = 0; i < length; i++)
{
sqlbase.FreeFunction(ar[i]._interopCookie);
ar[i].Dispose();
}
}
}
public Imps.Client.Data.SQLiteConvert SQLiteConvert
{
get
{
return this._base;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -