Exemplo n.º 1
0
        /// <summary>
        /// Handles decoding an instance from a query result
        /// </summary>
        /// <param name="queryResult">The query result to decode</param>
        /// <returns>The item decoded from the query result</returns>
        private T __Decode(IQueryResult queryResult)
        {
            // Make the result
            T result = new T();

            // Iterate over all properties
            for (int index = 0; index < myModelProperties.Length; index++)
            {
                // get a nice shorthand reference
                PropertyInfo pi = myModelProperties[index];

                // Get the DataField attribute
                DataField field = pi.GetCustomAttribute <DataField>();

                // Get the value from the query result
                object value = queryResult.Row[field.FieldName];

                // If the value is DbNull, we need to explicitly cast the value to null
                if (value.GetType() == typeof(DBNull))
                {
                    value = null;
                }
                // Otherwise, we should have a value, we check to see if it is a nullable field
                else if (pi.PropertyType.IsGenericType && pi.PropertyType.Name.Remove(pi.PropertyType.Name.IndexOf('`')) == "Nullable")
                {
                    // Get the type for the property from the nullable instance's generic types
                    Type paramType = pi.PropertyType.GenericTypeArguments[0];

                    // If the value is a value type, and the given value is the same as the default value for that type,
                    // we assume that the field should be null
                    if (paramType.IsValueType && Activator.CreateInstance(paramType).Equals(value))
                    {
                        value = null;
                    }

                    // If the value is null, simply set it to null
                    if (value == null)
                    {
                        pi.SetValue(result, value);
                    }
                    // Otherwise
                    else
                    {
                        // If it is a foriegn key to another table, use the value as a primary key to get the data from the table
                        if (pi.GetCustomAttribute <ForeignKey>() != null)
                        {
                            pi.SetValue(result, DataAccess.FromPrimaryKeyWeak(pi.PropertyType, value));
                        }
                        // Otherwise just cast it to the properties type and set the value
                        else
                        {
                            pi.SetValue(result, Convert.ChangeType(value, pi.PropertyType.GenericTypeArguments[0]));
                        }
                    }
                }
                // Finally, for any other type
                else
                {
                    // If it is a foriegn key to another table, use the value as a primary key to get the data from the table
                    if (pi.GetCustomAttribute <ForeignKey>() != null)
                    {
                        pi.SetValue(result, DataAccess.FromPrimaryKeyWeak(pi.PropertyType, value));
                    }
                    // Otherwise just cast it to the properties type and set the value
                    else
                    {
                        pi.SetValue(result, Convert.ChangeType(value, pi.PropertyType));
                    }
                }
            }

            // return the decoded result
            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets a collection of models from the database that match the fields set in the given model
        /// </summary>
        /// <param name="match">The model instance to match</param>
        /// <returns>A collection of models from the database</returns>
        public T[] GetMatches(T match)
        {
            // Iterate over dependancies
            for (int index = 0; index < myDependencies.Length; index++)
            {
                // Get the value from the property
                object pValue = myDependencies[index].GetValue(match);

                // IF the database does not contain something that matches, we know that we cannot have this instance
                if (pValue != null && !DataAccess.ExistsWeak(myDependencies[index].PropertyType, pValue))
                {
                    return(new T[0]);
                }
            }

            // We need to build two sides of the query, allocate strings
            string searchTerms  = "";
            string resultValues = "";

            // We also need to store a list of values to insert as well as a list of query parameters
            List <object>     insertParams = new List <object>();
            List <QueryParam> queryParams  = new List <QueryParam>();

            // Iterate over each property
            for (int index = 0; index < myModelProperties.Length; index++)
            {
                // Get the value of the property
                object value = myModelProperties[index].GetValue(match);
                // Get the DataField attribute
                DataField dField = myModelProperties[index].GetCustomAttribute <DataField>();

                // Check for a null value
                if (value == null)
                {
                    // just ignore
                }
                // Next see if this is a foreign key
                else if (myModelProperties[index].GetCustomAttribute <ForeignKey>() != null)
                {
                    // Use the DataAccess to get the primary key value for the instance
                    object key = DataAccess.GetPrimaryKeyWeak(myModelProperties[index].PropertyType, value);

                    // Append the the field name to the search
                    searchTerms += string.Format("{0}=@{0} AND ", dField.FieldName);

                    // Make and insert the query parameter
                    queryParams.Add(new QueryParam(dField.FieldName, dField.FieldType));
                    // Add that key value we got
                    insertParams.Add(key);
                }
                // Otherwise it is a regular data field
                else if (myModelProperties[index].GetCustomAttribute <PrimaryKey>() == null)
                {
                    // Append the the field name to the search
                    searchTerms += string.Format("{0}=@{0} AND ", dField.FieldName);

                    // Make and insert the query parameter
                    queryParams.Add(new QueryParam(dField.FieldName, dField.FieldType));
                    // Add that key value we got
                    insertParams.Add(value);
                }

                resultValues += dField.FieldName + ",";
            }

            // Prep the final query
            string query = string.Format("select {1} from {0} where {2}", myTableName, resultValues.Trim(','), searchTerms.Remove(searchTerms.Length - 5, 4).Trim());

            // Execute the query
            IQueryResult result = DataAccess.Execute(query, queryParams.ToArray(), insertParams.ToArray());

            T[] results = new T[result.NumRows];

            for (int index = 0; index < results.Length; index++)
            {
                results[index] = __Decode(result);
                result.MoveNext();
            }

            // Return true if at least one row was effected
            return(results);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Handles inserting a model instance into the database
        /// </summary>
        /// <param name="model">The model isntance to insert</param>
        /// <returns>True if the insert was successful, false if otherwise</returns>
        public bool Insert(T model)
        {
            // Iterate over dependancies
            for (int index = 0; index < myDependencies.Length; index++)
            {
                // Get the value from the property
                object pValue = myDependencies[index].GetValue(model);

                if (pValue == null && myDependencies[index].GetCustomAttribute <Nullable>() == null)
                {
                    throw new InvalidOperationException("Cannot insert with a missing dependancy");
                }

                // IF the database does not contain something that matches, add one
                if (!DataAccess.ExistsWeak(myDependencies[index].PropertyType, pValue))
                {
                    DataAccess.InsertWeak(myDependencies[index].PropertyType, pValue);
                }

                myDependencies[index].SetValue(model, DataAccess.MatchWeak(myDependencies[index].PropertyType, pValue)[0]);
            }

            // We need to build two sides of the query, allocate strings
            string insertLeft, insertRight;

            insertLeft = insertRight = "";

            // We also need to store a list of values to insert as well as a list of query parameters
            List <object>     insertParams = new List <object>();
            List <QueryParam> queryParams  = new List <QueryParam>();

            // Iterate over each property
            for (int index = 0; index < myModelProperties.Length; index++)
            {
                // Get the value of the property
                object value = myModelProperties[index].GetValue(model);
                // Get the DataField attribute
                DataField dField = myModelProperties[index].GetCustomAttribute <DataField>();

                // We only include in insert if auto-generaed is false
                if (myModelProperties[index].GetCustomAttribute <AutoGenerated>() == null)
                {
                    // Check for a null value
                    if (value == null)
                    {
                        // If we do not allow null, throw an exception, otherwise ignore
                        if (myModelProperties[index].GetCustomAttribute <Nullable>() == null)
                        {
                            throw new InvalidOperationException("Cannot insert with non-nullable field not set: " + myModelProperties[index].Name);
                        }
                    }
                    // Next see if this is a foreign key
                    else if (myModelProperties[index].GetCustomAttribute <ForeignKey>() != null)
                    {
                        // Use the DataAccess to get the primary key value for the instance
                        object key = DataAccess.GetPrimaryKeyWeak(myModelProperties[index].PropertyType, value);

                        // Append the field name to the left string
                        insertLeft += dField.FieldName + ",";
                        // Append the field name as a parameter to the right string
                        insertRight += string.Format("@{0},", dField.FieldName);

                        // Make and insert the query parameter
                        queryParams.Add(new QueryParam(dField.FieldName, dField.FieldType));
                        // Add that key value we got
                        insertParams.Add(key);
                    }
                    // Otherwise it is a regular data field
                    else
                    {
                        // Append the field name to the left string
                        insertLeft += dField.FieldName + ",";
                        // Append the field name as a parameter to the right string
                        insertRight += string.Format("@{0},", dField.FieldName);

                        // Make and insert the query parameter
                        queryParams.Add(new QueryParam(dField.FieldName, dField.FieldType));
                        // Add that key value we got
                        insertParams.Add(value);
                    }
                }
            }

            // Prep the final query
            string query = string.Format("insert into {0} ({1}) VALUES ({2})", myTableName, insertLeft.Trim(','), insertRight.Trim(','));
            // Execute the query
            int results = DataAccess.ExecuteStatement(query, queryParams.ToArray(), insertParams.ToArray());

            // Return true if at least one row was effected
            return(results > 0);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Handles updating a model in the database
        /// </summary>
        /// <param name="value">The value of the model to update</param>
        /// <param name="updateNullValues">True if null values should be assigned to null in the database, false to keep existing</param>
        /// <param name="updateChildren">True if referenced items should be updated, false if otherwise</param>
        /// <returns>The number of rows to be modified. In most cases this should be 1</returns>
        public int Update(T value, bool updateNullValues = true, bool updateChildren = true)
        {
            // Iterate over dependancies
            if (updateChildren)
            {
                for (int index = 0; index < myDependencies.Length; index++)
                {
                    // Get the value from the property
                    object pValue = myDependencies[index].GetValue(value);

                    // If the value is null and the field is not nullable
                    if (pValue == null && myDependencies[index].GetCustomAttribute <Nullable>() == null)
                    {
                        // if we are trying to update the nullable fields, throw an exception
                        if (updateNullValues)
                        {
                            throw new InvalidOperationException("Cannot insert with a missing dependancy");
                        }
                    }
                    else
                    {
                        // IF the database does not contain something that matches, add one
                        if (!DataAccess.ExistsWeak(myDependencies[index].PropertyType, pValue))
                        {
                            DataAccess.InsertWeak(myDependencies[index].PropertyType, pValue);
                            myDependencies[index].SetValue(value, DataAccess.MatchWeak(myDependencies[index].PropertyType, pValue)[0]);
                        }
                        else if (updateChildren)
                        {
                            DataAccess.UpdateWeak(myDependencies[index].PropertyType, pValue);
                        }
                    }
                }
            }

            // We need to build two sides of the query, allocate strings
            string updateValues, updateSearch;

            updateValues = updateSearch = "";

            // We also need to store a list of values to insert as well as a list of query parameters
            List <object>     insertParams = new List <object>();
            List <QueryParam> queryParams  = new List <QueryParam>();

            // Iterate over each property
            for (int index = 0; index < myModelProperties.Length; index++)
            {
                // Get the value of the property
                object pValue = myModelProperties[index].GetValue(value);
                // Get the DataField attribute
                DataField dField = myModelProperties[index].GetCustomAttribute <DataField>();


                if (myModelProperties[index].GetCustomAttribute <PrimaryKey>() != null)
                {
                    if (myModelProperties[index].GetCustomAttribute <ForeignKey>() != null)
                    {
                        // Use the DataAccess to get the primary key value for the instance
                        pValue = DataAccess.GetPrimaryKeyWeak(myModelProperties[index].PropertyType, pValue);
                    }

                    if (pValue == null)
                    {
                        throw new ArgumentException("Cannot update without primary key set. Has this record been retreived from the DB?");
                    }

                    // Append the field name as a parameter to the right string
                    updateSearch += string.Format("{0}=@{0} AND ", dField.FieldName);

                    // Make and insert the query parameter
                    queryParams.Add(new QueryParam(dField.FieldName, dField.FieldType));
                    // Add that key value we got
                    insertParams.Add(pValue);
                }
                // We only include in insert if auto-generaed is false
                else if (myModelProperties[index].GetCustomAttribute <AutoGenerated>() == null)
                {
                    // Check for a null value
                    if (pValue == null)
                    {
                        if (updateNullValues)
                        {
                            // If we do not allow null, throw an exception, otherwise ignore
                            if (myModelProperties[index].GetCustomAttribute <Nullable>() == null)
                            {
                                throw new InvalidOperationException("Cannot insert with non-nullable field not set: " + myModelProperties[index].Name);
                            }
                            else
                            {
                                updateValues += string.Format("{0}=null,", dField.FieldName);
                            }
                        }
                    }
                    // Next see if this is a foreign key
                    else if (myModelProperties[index].GetCustomAttribute <ForeignKey>() != null)
                    {
                        // Use the DataAccess to get the primary key value for the instance
                        object key = DataAccess.GetPrimaryKeyWeak(myModelProperties[index].PropertyType, pValue);

                        // Append the field name to the left string
                        updateValues += string.Format("{0}=@{0},", dField.FieldName);

                        // Make and insert the query parameter
                        queryParams.Add(new QueryParam(dField.FieldName, dField.FieldType));
                        // Add that key value we got
                        insertParams.Add(key);
                    }
                    // Otherwise it is a regular data field
                    else
                    {
                        // Append the field name to the left string
                        updateValues += string.Format("{0}=@{0},", dField.FieldName);

                        // Make and insert the query parameter
                        queryParams.Add(new QueryParam(dField.FieldName, dField.FieldType));
                        // Add that key value we got
                        insertParams.Add(pValue);
                    }
                }
            }

            // Prep the final query
            string query = string.Format("update {0}  set {1} where {2}", myTableName, updateValues.Trim(','), updateSearch.Remove(updateSearch.Length - 5, 4).Trim());
            // Execute the query
            int results = DataAccess.ExecuteStatement(query, queryParams.ToArray(), insertParams.ToArray());

            // Return true if at least one row was effected
            return(results);
        }