public DataTable Select(Database database, ICollection <Selection> selections, ICollection <Join> joins, ICollection <Filter> filters) { var planner = new SimpleExecutionPlanner(database, repository, selections, joins, filters); var rootOperation = planner.GetRootOperation(); DataTable result = new DataTable(); var metadata = rootOperation.GetMetadata(); var queryResult = rootOperation.Execute(); // Add header. List <string> columns = new List <string>(); columns.AddRange(KeyValue.Split(metadata.Value)); columns.AddRange(KeyValue.Split(metadata.Key)); foreach (var item in columns) { result.Columns.Add(item, typeof(string)); } // Add query result. foreach (var pair in queryResult) { List <string> row = new List <string>(); row.AddRange(KeyValue.Split(pair.Value)); row.AddRange(KeyValue.Split(pair.Key)); result.Rows.Add(row.ToArray()); } return(result); }
public ReturnStatus Delete(Database database, Table table, ICollection <Filter> filters) { string databaseFileName = KeyValue.GetDatabaseFileName(database.Name); var planner = new SimpleExecutionPlanner(database, repository, new List <Selection>(), new List <Join>(), filters); var rootOperation = planner.GetRootOperation(); var nonKeyColumnNames = table.Columns.Where(c => !table.PrimaryKey.Contains(c.Name)).Select(c => c.Name).ToList(); var metadata = rootOperation.GetMetadata(); var rows = rootOperation.Execute(); ReturnStatus status = new ReturnStatus(); var indexFactory = new IndexFactory(databaseFileName, repository); var rowsToDelete = new List <string>(); var rowData = new List <KeyValuePair <string, string> >(); foreach (var row in rows) { rowsToDelete.Add(row.Key); rowData.Add(row); } foreach (var row in rowsToDelete) { // Check foreign key constraints. foreach (var association in database.GetAssociationsWhereTableIsParent(table.Name)) { var indexMeta = table.Indexes.Where(i => i.Name.Equals(association.Name)).Single(); var index = indexFactory.GetIndex(indexMeta); var foreignKey = string.Empty; if (index.Exists(row)) { status.ReturnCode = ReturnCode.ForeignKeyConstraintFailed; status.Message = string.Format("Foreign key constraint check failed, the key [{0}] is referenced in {1}.", row, association.Child); return(status); } } } foreach (var row in rowData) { // Delete unique indexes. foreach (var uniqueIndex in table.Indexes.Where(i => i.Unique)) { var index = indexFactory.GetIndex(uniqueIndex); var columnValues = new List <string>(); foreach (var column in uniqueIndex.IndexMembers) { columnValues.Add(KeyValue.Split(row.Value).ElementAt(KeyValue.Split(metadata.Value).ToList().IndexOf(column))); } var uniqueKey = KeyValue.Concatenate(columnValues); index.Delete(uniqueKey); } // Delete foreign key indexes. foreach (var association in database.GetAssociationsWhereTableIsChild(table.Name)) { var parentTable = database.GetTable(association.Parent); var indexMeta = parentTable.Indexes.Where(i => i.Name.Equals(association.Name)).Single(); var index = indexFactory.GetIndex(indexMeta); var foreignKey = string.Empty; if (table.PrimaryKey.Contains(association.ColumnMappings.Values.First())) { foreignKey = KeyValue.Split(row.Key).ElementAt(table.PrimaryKey.IndexOf(association.ColumnMappings.Values.First())); } else { foreignKey = KeyValue.Split(row.Value).ElementAt(nonKeyColumnNames.IndexOf(association.ColumnMappings.Values.First())); } index.Delete(foreignKey, row.Key); } } foreach (var rowToDelete in rowsToDelete) { // Delete primary key and data. repository.Delete(databaseFileName, table.Name, rowToDelete); } status.ReturnCode = ReturnCode.Success; status.Message = string.Format("({0} row(s) affected)", rowsToDelete.Count); return(status); }