static string sortIndex(this iTypeSerializer ser, MemberInfo mi, out bool indexDirectionPositive, out bool multi) { IndexForColumn[] indices = ser.indicesFromColumn(mi); IndexForColumn found = null; foreach (var i in indices) { if (0 != i.columnIndex) { continue; // For sorting, the column have to be the first on the index } if (i.primary) { // Primary indices should be the best for performance found = i; break; } if (null == found) { found = i; } } if (null == found) { throw new ArgumentException("No sort index found for the column {0}".formatWith(mi.Name)); } indexDirectionPositive = found.indexDirectionPositive; multi = mi.getColumnAttribute().isMultiValued; return(found.indexName); }
static SearchQuery <tRow> queryWithParamsArray <tRow>(iTypeSerializer ser, LambdaExpression exp) where tRow : new() { ConvertParamsToArray cpa = new ConvertParamsToArray(exp.Parameters); Expression newBody = cpa.Visit(exp.Body); return(queryImpl <tRow>(ser, newBody, cpa.pRecord, cpa.pArray, exp.Parameters.Count - 1)); }
static SearchQuery <tRow> fullTextQuery <tRow>(iTypeSerializer ser, ParameterExpression eRecord, ParameterExpression eArgument, Expression eLeft, Expression eRight, int argsCount) where tRow : new() { HasParam hp = new HasParam(eRecord); bool leftParam = hp.hasParameter(eLeft); if (!leftParam) { throw new NotSupportedException("Full-text queries must have column as the first argument"); } MemberInfo column = parseColumn(eRecord, eLeft); bool rightParam = hp.hasParameter(eRight); if (rightParam) { throw new NotSupportedException("Full-text queries can't include column in the second argument"); } Func <object, object> arg = parseConstant(eArgument, eRight); IndexForColumn[] inds = ser.indicesFromColumn(column); IndexForColumn ind = inds.FirstOrDefault(i => i.columnIndex == 0 && i.attrib is Attributes.EseTupleIndexAttribute); if (null == ind) { throw new NotSupportedException("Failed to parse full-text search query: no suitable index found"); } string indName = ind.indexName; Action <Recordset <tRow>, object> act = (rs, a) => rs.filterFindSubstring(indName, arg(a)); return(new SearchQuery <tRow>(act, argsCount, true)); }
public static SearchQuery <tRow> query <tRow>(iTypeSerializer ser, Expression <Func <tRow, bool> > exp) where tRow : new() { ParameterExpression eRecord = exp.Parameters[0]; ParameterExpression eArgument = Expression.Parameter(typeof(object), "unused"); return(queryImpl <tRow>(ser, exp.Body, eRecord, eArgument, 0)); }
/// <summary>Construct a detached cursor.</summary> /// <param name="session"></param> /// <param name="serializer"></param> /// <param name="idTable"></param> /// <param name="bReadonly"></param> protected EseCursorBase(iSerializerSession session, iTypeSerializer serializer, JET_TABLEID idTable, bool bReadonly) { m_session = session; m_serializer = serializer; m_idTable = idTable; m_bOwnsTable = false; m_bReadOnly = bReadonly; }
protected ImportExport(iSerializerSession _sess, JET_TABLEID _idTable, iTypeSerializer _serializer) { sess = _sess; idTable = _idTable; serializer = _serializer as TypeSerializer; // Ensure the column IDs were lookup serializer.LookupColumnIDs(sess.idSession, idTable); schema = serializer.getColumnsSchema().ToList(); }
public Service(SessionPool sessionsPool) { this.sessionPool = sessionsPool; using (var sess = sessionPool.GetSession()) { iTypeSerializer ser = sess.serializer.FindSerializerForType(typeof(Person)); orderBySex = Queries.sort <Person, Person.eSex>(ser, p => p.sex, false); filterBySex = Queries.filter(ser, (Person p, Person.eSex arg) => p.sex == arg); } }
public void AddType(Type tRecord) { iTypeSerializer ts = m_serializer.FindSerializerForType(tRecord); if (null == ts) { m_serializer.AddSerializedType(tRecord); ts = m_serializer.FindSerializerForType(tRecord); } this.addType(ts as TypeSerializer, false); }
// For mode then 1 parameter, see this: // http://stackoverflow.com/a/11160067/126995 static SearchQuery <tRow> queryImpl <tRow>(iTypeSerializer ser, Expression query, ParameterExpression eRecord, ParameterExpression eArgument, int nArguments) where tRow : new() { // Full text search queries are handled differently: the only case where MethodCallExpression is allowed on the top level var mce = query as MethodCallExpression; if (null != mce && mce.Method == miStringContains) { return(fullTextQuery <tRow>(ser, eRecord, eArgument, mce.Object, mce.Arguments[0], nArguments)); } expression[] experessions = parseQuery(eRecord, eArgument, query).ToArray(); if (experessions.Length <= 0) { throw new NotSupportedException("Failed to parse query {0}".formatWith(query)); } HashSet <string> hsInds = null; foreach (var e in experessions) { e.lookupIndices(ser); IEnumerable <string> indNames = e.indices.Select(ifc => ifc.indexName); if (null == hsInds) { hsInds = new HashSet <string>(indNames); } else { hsInds.IntersectWith(indNames); } } if (hsInds.Count <= 0) { throw new NotSupportedException("Failed to parse query {0}: no single index covers all referenced columns".formatWith(query)); } bool multi = experessions.Any(e => e.multivalued); foreach (string i in hsInds) { var res = tryIndex <tRow>(experessions, multi, i, nArguments); if (null != res) { return(res); } } throw new NotSupportedException("Failed to parse query {0}: no suitable index found".formatWith(query)); }
public void AddType(Type tRecord) { if (isInTransaction) { throw new NotSupportedException("Can't add serialized types from within a transaction."); // Because the DB engine will close tables when the transaction ends } iTypeSerializer ts = m_serializer.FindSerializerForType(tRecord); if (null == ts) { m_serializer.AddSerializedType(tRecord); ts = m_serializer.FindSerializerForType(tRecord); } this.addType(ts as TypeSerializer, false); }
public static SearchQuery <tRow> query <tRow, tArg1>(iTypeSerializer ser, Expression <Func <tRow, tArg1, bool> > exp) where tRow : new() { if (typeof(tArg1) == typeof(object)) { ParameterExpression eRecord = exp.Parameters[0]; ParameterExpression eArgument = exp.Parameters[1]; return(queryImpl <tRow>(ser, exp.Body, eRecord, eArgument, 1)); } ParameterExpression r = exp.Parameters[0]; ParameterExpression arg = exp.Parameters[1]; ConvertParamType cpt = new ConvertParamType(arg); Expression <Func <tRow, object, bool> > inv = Expression.Lambda <Func <tRow, object, bool> >(cpt.Visit(exp.Body), r, cpt.newParam); return(query <tRow, object>(ser, inv)); }
/// <summary>Compile query to sort the table by the index.</summary> public static SortQuery <tRow> sort <tRow, tKey>(iTypeSerializer ser, Expression <Func <tRow, tKey> > exp, bool descending) where tRow : new() { var me = exp.Body as MemberExpression; if (null == me) { throw new NotSupportedException("Currently, orderBy[Descending] only supports ordering by a single column."); } IndexForColumn[] indices = ser.indicesFromColumn(me.Member); bool indexDirectionPositive, multi; string ind = ser.sortIndex(me.Member, out indexDirectionPositive, out multi); bool shouldInvert = descending ^ (!indexDirectionPositive); return(new SortQuery <tRow>(r => r.filterSort(ind, shouldInvert), multi)); }
/// <summary>Construct the cursor.</summary> public Cursor(iSerializerSession session, iTypeSerializer serializer, JET_TABLEID idTable, bool isReadOnly) : base(session, serializer, idTable, isReadOnly) { }
/// <summary>Compile query to filter the table by index, where query has three parameter.</summary> public static SearchQuery <tRow> filter <tRow, tArg1, tArg2, tArg3>(iTypeSerializer ser, Expression <Func <tRow, tArg1, tArg2, tArg3, bool> > exp) where tRow : new() { return(FilterQuery.query(ser, exp)); }
/// <summary>Look up the ESENT indices</summary> public void lookupIndices(iTypeSerializer ser) { indices = ser.indicesFromColumn(column); }
public static SearchQuery <tRow> query <tRow, tArg1, tArg2, tArg3>(iTypeSerializer ser, Expression <Func <tRow, tArg1, tArg2, tArg3, bool> > exp) where tRow : new() { return(queryWithParamsArray <tRow>(ser, exp)); }