/// <summary> /// returns a <see cref="ValuedColumn"/> parsed from <paramref name="valuedColumnXmlNode"/>. /// </summary> /// <param name="valuedColumnXmlNode"></param> /// <returns> /// <see cref="ValuedColumn"/> parsed from <paramref name="valuedColumnXmlNode"/> /// </returns> /// <exception cref="MissingAttributeException"> /// <seealso cref="XmlNodeExtensionMethods.GetAttributeValue(XmlNode, string)"/> /// </exception> /// <exception cref="MissingNodeException"> /// <seealso cref="XmlNodeExtensionMethods.GetNodes(XmlNode, string)"/> /// </exception> public static ValuedColumn Parse(XmlNode valuedColumnXmlNode) { try { string columnName = valuedColumnXmlNode.GetAttributeValue("name"); object columnValue = valuedColumnXmlNode.GetNodes("value")[0].FirstChild.Value; ValuedColumn valuedColumn = new ValuedColumn(columnName, columnValue); return(valuedColumn); } catch (Exception exception) { if ( exception is XmlNodeMissingAttributeException || exception is XmlNodeMissingNodeException) // ValuedColumn parse failed { throw new ValuedColumnParseException(null, exception); } else // unhandled exception { throw exception; } } }
protected override string BuildQueryString() { StringBuilder queryStringBuilder = new StringBuilder(); // append command header queryStringBuilder.AppendFormat("UPDATE {0} SET ", this.TableName); // append ValuedColumns names and new values for (int i = 0; i < valuedColumns.Length; i++) { ValuedColumn valuedColumn = valuedColumns[i]; queryStringBuilder.AppendFormat("{0} = '{1}'", valuedColumn.Name, valuedColumn.Value); // append seperator if (i < valuedColumns.Length - 1) { queryStringBuilder.Append(", "); } } // append condition if (queryCondition != null) { queryStringBuilder.AppendFormat(" WHERE {0}", this.QueryCondition.ExpressionString); } return(queryStringBuilder.ToString()); }
/// <summary> /// parses <see cref="InsertQuery"/> having <paramref name="tableName"/> from /// <paramref name="rowDataXmlNode"/>. /// </summary> /// <param name="rowDataXmlNode"></param> /// <param name="tableName"></param> /// <returns> /// <see cref="InsertQuery"/> having <paramref name="tableName"/> parsed from /// <paramref name="rowDataXmlNode"/> /// </returns> /// <exception cref="InsertQueryParseException"> /// thrown if <see cref="InsertQuery"/> parse failed /// </exception> public static InsertQuery Parse(XmlNode rowDataXmlNode, string tableName) { try { // get ValuedColumns XmlNodeList valuedColumnsXmlNodeList = rowDataXmlNode.GetNodes("column"); // number of specified columns might be zero (?) ValuedColumn[] valuedColumns = new ValuedColumn[valuedColumnsXmlNodeList.Count]; for (int i = 0; i < valuedColumnsXmlNodeList.Count; i++) { XmlNode valuedColumnXmlNode = valuedColumnsXmlNodeList[0]; valuedColumns[i] = ValuedColumn.Parse(valuedColumnXmlNode); } InsertQuery insertQuery = new InsertQuery(tableName, valuedColumns); return(insertQuery); } catch (XmlNodeMissingAttributeException xmlNodeMissingAttributeException) { throw new InsertQueryParseException(xmlNodeMissingAttributeException); } }
/// <summary> /// returns <see cref="ValuedColumn"/>, based on <paramref name="queryType"/>, /// corresponding to the id of the triggered row in <paramref name="auditedTableSchema"/>. /// </summary> /// <remarks> /// <see cref="ValuedColumn"/> value might reference the old / new row id, /// before / after the triggering query took place (i.e (old/new).columnName), /// or the last inserted row id in audited table. /// </remarks> /// <param name="auditedTableSchema"></param> /// <param name="auditTableSchema"></param> /// <param name="queryType"></param> /// <returns> /// <see cref="ValuedColumn"/>, based on <paramref name="queryType"/>, /// corresponding to the id of the triggered row in <paramref name="auditedTableSchema"/>. /// </returns> private static ValuedColumn getAuditedTableTriggeredRowIdValuedColumn( TableSchema auditedTableSchema, TableSchema auditTableSchema, Query.eQueryType queryType) { ValuedColumn auditedTableTriggeredRowIdValuedColumn = null; // name of column (in audit table) containing audited table triggered row id string columnName = auditTableSchema.ColumnSchemas [AuditTableStructure.AUDITED_TABLE_ROW_ID_COLUMN_INDEX].Name; if (queryType == Query.eQueryType.Insert) // get the ID the row got after being inserted { object columnValue = new FunctionTableColumn( FunctionTableColumn.eFunctionType.LastInsertRowid); auditedTableTriggeredRowIdValuedColumn = new ValuedColumn(columnName, columnValue); } else if (queryType == Query.eQueryType.Update || queryType == Query.eQueryType.Delete) { // get the id the row had before being updated / deleted auditedTableTriggeredRowIdValuedColumn = new TriggerValuedColumn( columnName, auditedTableSchema.PrimaryKeyColumnSchema.Name, TriggerValuedColumn.ValueExpression.eTime.Old); } return(auditedTableTriggeredRowIdValuedColumn); }
/// <summary> /// parses an array of <see cref="ValuedColumn"/>s, each having a corresponding /// name and value from /// <paramref name="columnNames"/> and <paramref name="columnValues"/> /// </summary> /// <param name="columnNames"></param> /// <param name="columnValues"></param> /// <returns> /// array of <see cref="ValuedColumn"/>s, each having a corresponding /// name and value from /// <paramref name="columnNames"/> and <paramref name="columnValues"/> /// </returns> /// <exception cref="NamesAndValuesCountMismatchException"> /// <seealso cref="assertColumnNamesAndValuesCountMatches(IList{string}, IList{object})"/> /// </exception> public static ValuedColumn[] Parse(IList <string> columnNames, IList <object> columnValues) { assertColumnNamesAndValuesCountMatches(columnNames, columnValues); ValuedColumn[] parsedValuedColumns = new ValuedColumn[columnNames.Count]; for (int i = 0; i < parsedValuedColumns.Length; i++) { parsedValuedColumns[i] = new ValuedColumn(columnNames[i], columnValues[i]); } return(parsedValuedColumns); }
/// <summary> /// appends a single insert value tuple to <paramref name="queryStringBuilder"/>. /// </summary> /// <param name="insertQuery"></param> /// <param name="queryStringBuilder"></param> private static void appendInsertQuery( InsertQuery insertQuery, StringBuilder queryStringBuilder) { queryStringBuilder.Append("("); ValuedColumn[] valuedColumns = insertQuery.ValuedColumns; for (int i = 0; i < valuedColumns.Length; i++) { ValuedColumn valuedColumn = valuedColumns[i]; queryStringBuilder.AppendFormat("'{0}'", valuedColumn.Value); if (i < valuedColumns.Length - 1) { queryStringBuilder.Append(", "); } } queryStringBuilder.Append(")"); }
/// <summary> /// returns undo <see cref="Query"/> corresponding to query performed on /// <paramref name="auditedTableName"/>, where <paramref name="auditTableRow"/> contains /// the data required to undo a single row in <paramref name="auditedTableName"/>, /// which was affected by the query. /// </summary> /// <param name="auditTableRow"></param> /// <param name="auditedTableName"></param> /// <param name="queryTypeIdToQueryType"></param> /// <returns> /// undo <see cref="Query"/> corresponding to query performed on /// <paramref name="auditedTableName"/>, where <paramref name="auditTableRow"/> contains /// the data required to undo a single row in <paramref name="auditedTableName"/>, /// which was affected by the query /// </returns> /// <exception cref="UnsupportedAuditQueryTypeException"> /// thrown if <see cref="Query.eQueryType"/> specified in <paramref name="auditTableRow"/> /// is not supported for audit /// </exception> private static WriteQuery getUndoQuery( ResultSet.Row auditTableRow, string auditedTableName, Dictionary <long, Query.eQueryType> queryTypeIdToQueryType) { WriteQuery undoQuery; // type of query that was originally performed on audited table long queryTypeId = auditTableRow.GetColumnValue <long>( AuditTableStructure.QUERY_ID_COLUMN_INDEX); Query.eQueryType queryType = queryTypeIdToQueryType[queryTypeId]; // value of _id column of modified row in audit table long auditedTableRowId = auditTableRow.GetColumnValue <long>( AuditTableStructure.AUDITED_TABLE_ROW_ID_COLUMN_INDEX); // get undo query based on query type if (queryType == Query.eQueryType.Insert) { undoQuery = new DeleteQuery( auditedTableName, new BasicCondition( new ValuedTableColumn( DatabaseStructure.ID_COLUMN_NAME, auditedTableName, auditedTableRowId), BasicCondition.eOperatorType.Equal ) ); } else if (queryType == Query.eQueryType.Update || queryType == Query.eQueryType.Delete) { // ValuedColumn of _id column of modified row in audited table ArrayRange <ValuedColumn> auditedTableRowIdArrayRange = new ArrayRange <ValuedColumn>( new ValuedColumn(DatabaseStructure.ID_COLUMN_NAME, auditedTableRowId) ); // ValueColumn of columns other than _id of modified row in audited table ArrayRange <ValuedColumn> auditedTableRowValuesArrayRange = new ArrayRange <ValuedColumn>( ValuedColumn.Parse(auditTableRow.ColumnNames, auditTableRow.ColumnValues), AuditTableStructure.AUDITED_TABLE_DATA_COLUMNS_START_INDEX); // unified ValuedColumn list for undo query List <ValuedColumn> queryValuedColumns = ListUtils.ListFromArrayRanges( auditedTableRowIdArrayRange, auditedTableRowValuesArrayRange); if (queryType == Query.eQueryType.Update) { undoQuery = new UpdateQuery( auditedTableName, queryValuedColumns, new BasicCondition( new ValuedTableColumn( DatabaseStructure.ID_COLUMN_NAME, auditedTableName, auditedTableRowId), BasicCondition.eOperatorType.Equal ) ); } else // queryType == Query.eQueryType.Delete { undoQuery = new InsertQuery(auditedTableName, queryValuedColumns); } } else { throw new UnsupportedAuditQueryTypeException(queryType); } return(undoQuery); }