public CacheKey(ISqlQuery query) { // The key must always be made from a clone - otherwise, if the original query is changed & rerun, it will still // match the cached value (being the same object) Query = SqlQueryUtility.QueryAsSql(query.GetQuery(), query.Parameters); ISqlQueryMaker comp = query as ISqlQueryMaker; if (comp != null) { TableName = comp.TableName; } }
public void Constructors() { TestObjectConstructor test = new TestObjectConstructor(); var classInfo = IQ.MapperCache.GetClassInfo(test.GetType()); Assert.AreEqual("testTableConstructor", classInfo.Query.TableName); ISqlQueryMaker query = classInfo.GetQuery(); Assert.AreEqual("testTableConstructorView", query.From); try { test = IQ.From <TestObjectConstructor>(12345).First(); } catch { } Assert.AreEqual("SELECT TOP 1 PK,FirstName,HowMuch FROM testTableConstructorView WHERE (defaultWhere=1) AND pk=@pk", TC.Controller.LastQuery.GetQuery()); // TODO: Add tests for complex queries based on the oroginal query object }
protected ISqlQuery ParseComplexQuery(object query, IEnumerable <object> parms) { ISqlQuery outputQuery = null; // We always want to parse the parameters. But if the thing passed to us as "query" is not a string, then // just assume that all the parms are option type parameters and don't pass a query to ParameterParser string querySource = query is string? (string)query: ""; ParameterParser pp = new ParameterParser(querySource, parms); if (Types.IsNumericType(query)) { // It's a single numeric value - assume it's a primary key ExpectNoParameters(pp.Parameters); var classInfo = IQ.ClassInfo <T>(); ISqlQueryMaker queryPK = classInfo.GetQuery(); queryPK.Where.Add(classInfo.PrimaryKeyField.Name, query); outputQuery = queryPK; } else if (query is string) { bool isMappable = Types.IsMappable(typeof(T)); // First check if its a single named field if (isMappable) { var classInfo = IQ.ClassInfo <T>(); // Try to create a valid raw query.. if it's not valid, assume it's a where if (QueryType == QueryType.Where || pp.QueryType == QueryType.Invalid) { ISqlQueryMaker queryPK = classInfo.GetQuery(); //var whereString = new WhereString(pp.Query, // pp.Parameters.Count > 0 ? // pp.Parameters.ToArray(): // null); queryPK.Where.Add(pp.GetWhereClause()); outputQuery = queryPK; } else { outputQuery = new SqlQueryDef(pp.GetQuery(QueryType), pp.Parameters); } } else { // it's mapped to a primitive type - outputQuery = new SqlQueryDef(pp.GetQuery(QueryType), pp.Parameters); } } if (outputQuery.QueryType != QueryType) { throw new IQException("Wrong type of query passed to method: was " + outputQuery.ToString() + ", expected " + QueryType.ToString()); } return(outputQuery); }
/// <summary> /// options may include: an IDbConnection, an IDbTransaction, CommandBehavior. Save queries should not /// include any other parameters /// </summary> /// <param name="obj"></param> /// <param name="options"></param> /// <returns></returns> public bool Save(object obj, IQueryOptions options = null) { // TODO: This method is way too long. Break it down IClassInfo classInfo = GetClassInfo(obj); if (!classInfo.DoEvent(obj, IQEventType.BeforeSave, this)) { return(false); } // Determine if the object is tracked for changes. If not, we will just save everything. IObjectData dbData; bool tracked = IQ.MapperCache.TryGetObjectData(obj, out dbData); // Determine if the object is a new record based on the primary key value bool isNew = ClassInfo.IsNew(obj); QueryType queryType = isNew ? QueryType.Insert : QueryType.Update; ISqlQueryMaker query = classInfo.GetQuery(queryType, options); bool isDirty = false; string pk = classInfo.Query.PrimaryKey; foreach (var item in classInfo.Fields) { string name = item.Name; if (!item.IsPrimaryKey && !item.IsSqlReadOnly && (isNew || !tracked || dbData.IsDirty(name))) { query.AddUpdateData(classInfo[name].SqlName, classInfo[name].GetValue(obj)); isDirty = true; } } bool success = false; if (isDirty) { if (queryType == QueryType.Insert) { if (!classInfo.DoEvent(obj, IQEventType.BeforeInsert, this)) { return(false); } int newPK = DataStorageController.RunQueryInsert(Connection, query, Transaction, CommandBehavior); if (newPK <= 0) { throw new InvalidOperationException("The record could not be inserted."); } classInfo[pk].SetValue(obj, newPK); if (!classInfo.DoEvent(obj, IQEventType.OnInsert, this)) { throw new InvalidOperationException("The operation was cancelled after the database query was executed."); } success = true; } else { if (!classInfo.DoEvent(obj, IQEventType.BeforeUpdate, this)) { return(false); } query.Where.Add(classInfo.PrimaryKeyField.Name, classInfo.PrimaryKeyField.GetValue(obj)); success = DataStorageController.RunQueryScalar(Connection, query, Transaction, CommandBehavior) > 0; if (!classInfo.DoEvent(obj, IQEventType.OnUpdate, this)) { throw new InvalidOperationException("The operation was cancelled after the database query was executed."); } } } else { success = false; } if (!classInfo.DoEvent(obj, IQEventType.OnSave, this)) { throw new InvalidOperationException("The operation was cancelled after the database query was executed."); } if (success && tracked) { dbData.Clean(); } return(success); }