compiler "data" { source: data-desc target: csharp } string function PrivateField(string value) { return "_" ToPascalCase($(value)); } node function GetEntity(string entityName) { context($(root)) return ["entity[entity-name == '" $(entityName) "']"]; } node function GetEntityDataset(string entityName) { context($(root)) return ["dataset[/>/entity-name == '" $(entityName) "']"]; } node function GetEntityDataSource(string entityName) { context($(root)) { string sourceName = ["dataset/data-list/data-type[entity-name == '" $(entityName) "']/data-source-name"]; return ["datasource[data-source-name == '" $(sourceName) "']"]; } } string function GetEntityDatasetName(string entityName) { string name; context ($(root)) $(name) = ["dataset/data-list/data-type[entity-name == '" $(entityName) "']/data-name"]; if ($(name) == "") return $(entityName); return $(name); } node function GetEnum(string enumName) { context($(root)) return ["enum[enum-name == '" $(enumName) "']"]; } bool function IsEnum(string typeName) { context ($(root)) return ["enum[enum-name == '" $(typeName) "']"]; } bool function IsSimpleType(node entityType) { context ($(entityType)) return (["field-type-name"] isanyof ("Int", "Real", "Text", "Date", "Bool")) or IsEnum(["field-type-name"]); } string function GetClassType(node fieldType) { context ($(fieldType)) { if (IsEnum(["field-type-name"])) { string typeName = ["field-type-name"]; $(typeName) << "?"; return $(typeName); } else if (["field-type-name"] == "Int") { string typeName = map ["field-size"] default "int?" { "1" -> "byte?", "2" -> "short?", "4" -> "int?", "8" -> "long?" }; return $(typeName); } else { string typeName = map ["field-type-name"] default ["field-type-name"] { "Text" -> "string", "Date" -> "DateTime?", "Bool" -> "bool?" }; if ([".[/>/field-type-attribute == 'listof']"]) { if ([".[/>/field-type-attribute == 'ref']"]) $(typeName) = ["../../../entity-name"] ["../field-name"]; $(typeName) << "Table"; } return $(typeName); } } } string function GetSqlType(node fieldType) { context ($(fieldType)) { if (["field-type-name"] == "Int") { string typeName = map ["field-size"] default "int" { "1" -> "tinyint", "2" -> "shortint", "4" -> "int", "8" -> "bigint" }; return $(typeName); } else if (["field-type-name"] == "Text") { string typeName; if (["field-size"]) $(typeName) = "varchar(" ["field-size"] ")"; else $(typeName) = "text"; return $(typeName); } else { string typeName = map ["field-type-name"] default ["int"] { "Date" -> "datetime", "Bool" -> "bit" }; if ($(typeName) == "") $(typeName) << "int"; return $(typeName); } } } string function GetFieldValue(node field) { context ($(field)) { bool mustFormat = ["field-class-type"] isanyof ("string", "DateTime?", "bool?"); bool isEnum = IsEnum(["field-entity-type"]); string valueRef = "value."; if (["field-class-base-name"] != "") $(valueRef) << PrivateField(["field-class-base-name"]); else $(valueRef) << PrivateField(["field-class-name"]); $(valueRef) << " == null ? \"null\" : "; if ($(mustFormat)) $(valueRef) << "FormatValue("; if ($(isEnum)) $(valueRef) << "((int)"; $(valueRef) << "value."; if (["field-class-base-name"] != "") $(valueRef) << PrivateField(["field-class-base-name"]) "."; $(valueRef) << PrivateField(["field-class-name"]); if ($(isEnum)) $(valueRef) << ")"; if ($(mustFormat)) $(valueRef) << ")"; else $(valueRef) << ".ToString()"; return $(valueRef); } } node function AddSqlTableField(node table, string sqlName, string className, string classBaseName, string classBaseType, string entityType, string sqlType, string classType, bool isKey, bool isAutoincremental, isList, bool isRef) { node field = AddNode($(table), "", "field", ""); AddNode($(field), "", "field-sql-name", $(sqlName)); AddNode($(field), "", "field-entity-type", $(entityType)); AddNode($(field), "", "field-class-type", $(classType)); AddNode($(field), "", "field-sql-type", $(sqlType)); if ($(className) == "") AddNode($(field), "", "field-class-name", $(sqlName)); else AddNode($(field), "", "field-class-name", $(className)); AddNode($(field), "", "field-class-base-name", $(classBaseName)); AddNode($(field), "", "field-class-base-type", $(classBaseType)); if ($(isKey)) AddNode($(field), "", "field-attribute", "primarykey"); if ($(isAutoincremental)) AddNode($(field), "", "field-attribute", "autoincremental"); if ($(isList)) AddNode($(field), "", "field-attribute", "list"); if ($(isRef)) AddNode($(field), "", "field-attribute", "ref"); if ($(entityType) != "") AddNode($(field), "", "field-attribute", "simpleType"); return $(field); } function AddSqlTableFields(node table, node entity, string baseName, string baseType) { context ($(entity)) { string entityName = ["entity-name"]; if ($(baseName) == "") AddSqlTableField($(table), $(entityName) "Id", "", "", "", "", "int", "int?", true, true, false, false); foreach ["field-list/field"] { string sqlType = GetSqlType(["field-type"]); string classType = GetClassType(["field-type"]); if (IsSimpleType(["field-type"])) { string fieldSqlName; string fieldEntityName; bool isClassField; if ($(baseName) == "") $(fieldSqlName) = ["field-name"]; else $(fieldSqlName) = $(baseName) ["field-name"]; if (IsEnum(["field-type/field-type-name"])) $(fieldEntityName) = ["field-type/field-type-name"]; AddSqlTableField($(table), $(fieldSqlName), ["field-name"], $(baseName), $(baseType), $(fieldEntityName), $(sqlType), GetClassType(["field-type"]), false, false, false, false); } else { node innerEntity = GetEntity(["field-type/field-type-name"]); if (Count($(innerEntity)) == 0) AddSqlTableField($(table), ["field-name"], "", "", "", "", "shortint", "int?", false, false, false, false); else { bool isRef = ["field-type[/>/field-type-attribute == 'ref']"]; bool isList = ["field-type[/>/field-type-attribute == 'listof']"]; bool expandType = false; if (not($(isList))) { if ($(isRef)) { string fieldEntityName = ["field-type/field-type-name"]; string className = $(fieldEntityName) "Id"; AddSqlTableField($(table), ["field-name"], $(className), ["field-name"], ["field-type/field-type-name"], ["field-type/field-type-name"], "int", "int", false, false, false, true); } else AddSqlTableFields($(table), $(innerEntity), ["field-name"], ""); } } } } } } function AddSqlTableReference(node table, string entityName, string entityField) { node ref = AddNode($(table), "", "reference", ""); AddNode($(ref), "", "entity", $(entityName)); AddNode($(ref), "", "field", $(entityField) "Id"); AddNode($(ref), "", "entity-field", $(entityField)); } node function AddSqlTable(node tableTree, string tableName, string entityName, string dataset, string datasource, bool isTree, bool isRel) { node table = AddNode($(tableTree), "", "table", ""); AddNode($(table), "", "table-name", $(tableName)); AddNode($(table), "", "dataset-name", $(dataset)); AddNode($(table), "", "datasource-name", $(datasource)); if ($(entityName) != "") { AddNode($(table), "", "entity-name", $(entityName)); if ($(isRel)) AddNode($(table), "", "class-name", $(tableName) "Table"); else { AddNode($(table), "", "class-name", $(entityName) "Table"); AddSqlTableFields($(table), GetEntity($(entityName)), "", ""); } } else AddNode($(table), "", "class-name", $(tableName) "Table"); if ($(isRel)) AddNode($(table), "", "table-attribute", "relation"); if ($(isTree)) { AddNode($(table), "", "table-attribute", "tree"); AddSqlTableField($(table), "ParentId", $(entityName) "Id", "Parent", $(entityName), $(entityName), "int", "int", false, false, false, true); AddSqlTableReference($(table), "Container", "Parent"); } return $(table); } node function AddClassField(node class, string name, string classType, string entityType, bool simpleType, bool readOnly, bool isRef, bool isList, string refFieldName) { node field = AddNode($(class), "", "field", ""); AddNode($(field), "", "field-name", $(name)); AddNode($(field), "", "field-class-type", $(classType)); AddNode($(field), "", "field-entity-type", $(entityType)); if ($(refFieldName) == "") AddNode($(field), "", "field-ref-name", GetNode($(class), "entity-name")); else AddNode($(field), "", "field-ref-name", $(refFieldName)); if ($(isList)) AddNode($(field), "", "field-attribute", "list"); if ($(isRef)) AddNode($(field), "", "field-attribute", "ref"); if ($(readOnly) or $(isList)) AddNode($(field), "", "field-attribute", "readOnly"); if ($(simpleType)) AddNode($(field), "", "field-attribute", "simpleType"); } node function AddClass(node classTree, node tableTree, node entity) { context ($(entity)) { node decTable; node class = AddNode($(classTree), "", "class", ""); string entityName = ["entity-name"]; AddNode($(class), "", "class-name", $(entityName)); AddNode($(class), "", "entity-name", $(entityName)); context ($(tableTree)) $(decTable) = ["table[entity-name == '" $(entityName) "']"]; if ($(decTable)) { AddClassField($(class), $(entityName) "Id", "int?", "", true, false, false, false, ""); context ($(decTable)) { if ([".[table-attribute == 'tree']"]) { AddClassField($(class), "Parent", $(entityName), $(entityName), false, false, true, false, ""); AddClassField($(class), "Childs", $(entityName) "Table", $(entityName), false, false, true, true, "Parent"); } } } foreach ["field-list/field"] { bool isRef = ["field-type[/>/field-type-attribute == 'ref']"]; bool isList = ["field-type[/>/field-type-attribute == 'listof']"]; AddClassField($(class), ["field-name"], GetClassType(["field-type"]), ["field-type/field-type-name"], IsSimpleType(["field-type"]), false, $(isRef), $(isList), ""); } context ($(root)) { foreach ["entity/field-list/field[/>/field-type-name == '" $(entityName) "']"] { string entityName = ["../../entity-name"]; bool isRef = ["field-type[/>/field-type-attribute == 'ref']"]; bool isList = ["field-type[/>/field-type-attribute == 'listof']"]; if ($(isList) and not($(isRef))) AddClassField($(class), $(entityName), $(entityName), $(entityName), false, true, true, false, ""); } } return $(class); } } node function BuildClassTree(node tableTree) { node classTree; foreach ["entity"] AddClass($(classTree), $(tableTree), ["."]); return $(classTree); } node function BuildTableTree() { node tableTree; foreach ["dataset/data-list/data-type"] { string dataSourceName = GetNode(GetEntityDataSource(["entity-name"]), "data-source-name"); AddSqlTable($(tableTree), ["data-name"], ["entity-name"], ["../../dataset-name"], $(dataSourceName), ["data-type-name"] == "tree", false); } foreach ["/>/field"] { string datasetName; string dataSourceName; string declareEntityName = ["../../entity-name"]; string entityName = ["field-type/field-type-name"]; bool isRef = ["field-type[/>/field-type-attribute == 'ref']"]; bool isList = ["field-type[/>/field-type-attribute == 'listof']"]; bool isDatasetTable = ["//entity-name == '" $(entityName) "']"]; node table; context ($(tableTree)) { $(datasetName) = ["table[entity-name == '" $(declareEntityName) "']/dataset-name"]; $(dataSourceName) = ["table[entity-name == '" $(declareEntityName) "']/datasource-name"]; $(table) = ["table[table-name == '" $(entityName) "']"]; } if (not($(isDatasetTable)) and GetEntity($(entityName)) and not($(table)) and ($(isRef) or $(isList))) $(table) = AddSqlTable($(tableTree), $(entityName), $(entityName), $(datasetName), $(dataSourceName), false, false); if ($(isList)) { if ($(isRef)) { node relTable = AddSqlTable($(tableTree), $(declareEntityName) ["field-name"], "", $(datasetName), $(dataSourceName), false, true); AddSqlTableField($(relTable), $(declareEntityName) "Id", "", "", "", $(declareEntityName), "int", "int?", true, false, false, false); AddSqlTableField($(relTable), ["field-name"] "Id", "", "", "", $(entityName), "int", "int?", true, false, false, false); } else { AddNode($(table), "", "table-attribute", "hidden"); AddSqlTableField($(table), $(declareEntityName) "Id", "", $(declareEntityName), $(declareEntityName), $(declareEntityName), "int", "int?", false, false, true, false); AddSqlTableReference($(table), $(declareEntityName), $(declareEntityName)); } } } return $(tableTree); } function ProcessClass(node class, node tableTree) { context ($(class)) { string entityName = ["entity-name"]; string className = ["class-name"]; string params; string values; string objects; foreach ["field"] { bool isReadonly = [".[field-attribute == 'readOnly']"]; bool isRef = [".[field-attribute == 'ref']"]; bool isList = [".[field-attribute == 'list']"]; bool isSimpleType = [".[field-attribute == 'simpleType']"]; if (not($(isReadonly)) and (NodeIndex() > 0)) { if ($(params) != "") $(params) << ", "; $(params) << ["field-class-type"] " " ToPascalCase(["field-name"]); $(values) << "\n" PrivateField(["field-name"]) " = " ToPascalCase(["field-name"]) ";"; } if (not($(isRef)) and not($(isList)) and not($(isSimpleType))) $(objects) << "\n" PrivateField(["field-name"]) " = new " ["field-class-type"] "();"; } begin-stream $(className) out "public partial class " $(className) " : DataEntity\n{"; indent inc; foreach ["field"] out "\nprotected internal " ["field-class-type"] " " PrivateField(["field-name"]) ";"; context($(tableTree)) { if (["table[entity-name == '" $(entityName) "']"]) { out "\nprotected internal " $(entityName) "Table _table;"; out "\n\npublic " $(entityName) "(int? " ToPascalCase($(entityName) "Id") ")\n{"; indent inc; out "\n" PrivateField($(entityName) "Id") " = " ToPascalCase($(entityName) "Id") ";"; out $(objects); out "\n_partial = true;"; indent dec; out "\n}\n"; out "\npublic void Update()\n{"; indent inc; out "\n_table.Update(this);"; indent dec; out "\n}\n"; out "\npublic void Delete()\n{"; indent inc; out "\n_table.Delete(this);"; indent dec; out "\n}\n"; } } out "\n\npublic " $(entityName) "()\n{"; indent inc; out $(objects); indent dec; out "\n}\n\n"; out "public " $(entityName) "(" $(params) ")\n{"; indent inc; out $(values); out "\n_partial = false;"; indent dec; out "\n}\n\n"; foreach ["field"] { bool isSimpleType = [".[field-attribute == 'simpleType']"]; bool isRef = [".[field-attribute == 'ref']"]; bool isList = [".[field-attribute == 'list']"]; bool isReadonly = [".[field-attribute == 'readOnly']"]; string fieldName = "" PrivateField(["field-name"]); string fieldClassType = ["field-class-type"]; string fieldEntityType = ["field-entity-type"]; string tableName; out "\npublic " $(fieldClassType) " " ["field-name"] "\n{"; indent inc; out "\n"; out "get\n{"; indent inc; if ($(isSimpleType) or (not($(isRef)) and not($(isList)))) out "\nreturn " $(fieldName) ";"; else if ($(isList)) { out "\nif (" $(fieldName) " == null)\n{"; indent inc; out "\n" $(fieldName) " = new " $(fieldClassType) "(_table._dataset);"; out "\n" $(fieldName) ".Set" ["field-ref-name"] "(this);"; indent dec; out "\n}"; out "\nreturn " $(fieldName) ";"; } else { string datasetName = GetEntityDatasetName($(fieldEntityType)); out "\nif (" $(fieldName) " == null)"; indent inc; out "\nreturn null;"; indent dec; out "\nif (IsPartial(" $(fieldName) ") && _table != null)"; indent inc; out "\n" $(fieldName) " = _table._dataset." PrivateField($(datasetName)) ".GetById((int)" $(fieldName) "." PrivateField($(fieldEntityType)) "Id);"; indent dec; out "\nreturn " $(fieldName) ";"; } indent dec; out "\n}"; if (not($(isList))) { out "\nset\n{"; indent inc; out "\n"; out $(fieldName) " = value;"; indent dec; out "\n}"; } indent dec; out "\n}\n"; } out "\npublic override void ToXml(XmlWriter writer, bool deep)\n{"; indent inc; out "\nwriter.WriteStartElement(\"" $(className) "\");"; context($(tableTree)) { if (["table[entity-name == '" $(entityName) "']"]) out "\nwriter.WriteAttributeString(\"id\", " PrivateField($(entityName)) "Id.ToString());"; } foreach ["field"] { if (NodeIndex() > 0) { bool simpleType = [".[field-attribute == 'simpleType']"]; if ($(simpleType)) out "\nwriter.WriteElementString(\"" ["field-name"] "\", " ["field-name"] " == null ? \"\" : " ["field-name"] ".ToString());"; else { out "\nif (deep)"; indent inc; out "\n" ["field-name"] ".ToXml(writer, false);"; indent dec; } } } out "\nwriter.WriteEndElement();"; indent dec; out "\n}"; end-stream } indent dec; out "\n}\n\n"; } function ProcessRelationTable(node table, node tableTree) { context ($(table)) { string dataSourceName = ["datasource-name"]; string tableName = ["table-name"]; string mainType = ["field[0]/field-entity-type"]; string refType = ["field[1]/field-entity-type"]; string refTableName; string mainTableName; context ($(tableTree)) { $(refTableName) = ["table[entity-name == '" $(refType) "']/table-name"]; $(mainTableName) = ["table[entity-name == '" $(mainType) "']/table-name"]; } string create = ["field[0]/field-sql-name"] " " ["field[0]/field-sql-type"] ", " ["field[1]/field-sql-name"] " " ["field[1]/field-sql-type"] ", PRIMARY KEY (" ["field[0]/field-sql-name"] ", " ["field[1]/field-sql-name"] ")" ", FOREIGN KEY (" ["field[0]/field-sql-name"] ") REFERENCES " $(mainTableName) "(" $(mainType) "Id) ON DELETE CASCADE ON UPDATE NO ACTION" ", FOREIGN KEY (" ["field[1]/field-sql-name"] ") REFERENCES " $(refTableName) "(" $(refType) "Id)"; string params = PrivateField($(mainType)) "." $(mainType) "Id, value." $(refType) "Id"; begin-stream ["class-name"] out "public partial class " ["class-name"] " : DatabaseTable<" $(refType) ">\n{"; indent inc; out "\nprotected internal " ["dataset-name"] " _dataset;"; out "\nprotected " $(mainType) " " PrivateField($(mainType)) " = null;"; out "\n\npublic " ["class-name"] "(" ["dataset-name"] " dataset)\n"; out "{"; indent inc; out "\n_dataset = dataset;"; indent dec; out "\n}\n"; out "\npublic override void Destroy()\n{"; indent inc; out "\nstring sql = \"IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '" $(tableName) "') DROP TABLE " $(tableName) "\";"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;\ncommand.ExecuteNonQuery();"; indent dec; out "\n}\n"; out "\npublic override void Create()\n{"; indent inc; out "\nDestroy();"; out "\nstring sql = \"CREATE TABLE " $(tableName) "(" $(create) ")\";"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;\ncommand.ExecuteNonQuery();"; indent dec; out "\n}\n"; out "\npublic override " $(refType) " Add(" $(refType) " value)\n{"; indent inc; out "\nstring sql = String.Format(\"INSERT INTO " $(tableName) "(" ["field[0]/field-sql-name"] ", " ["field[1]/field-sql-name"] ") VALUES ({0}, {1})\", " $(params) ");"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;"; out "\ncommand.ExecuteNonQuery();"; out "\nreturn value;"; indent dec; out "\n}\n"; out "\npublic override void Delete(" $(refType) " value)\n{"; indent inc; out "\nDelete((int)value." $(refType) "Id);"; indent dec; out "\n}\n"; out "\npublic override void Delete(int " ToPascalCase($(refType)) "Id)\n{"; indent inc; out "\nstring sql = String.Format(\"DELETE FROM " $(tableName) " WHERE " ["field[0]/field-sql-name"] " = {0} AND " ["field[1]/field-sql-name"] " = {1}\", " PrivateField($(mainType)) "." $(mainType) "Id, " ToPascalCase($(refType)) "Id);"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;\ncommand.ExecuteNonQuery();"; indent dec; out "\n}\n"; out "\npublic override " $(refType) "[] GetList(string filter)\n{"; indent inc; out "\nstring where = \"" $(tableName) "." ["field[0]/field-sql-name"] " = \" + " PrivateField($(mainType)) "." $(mainType) "Id;"; out "\nstring sql = \"SELECT " $(refTableName) ".* FROM " $(tableName) " INNER JOIN " $(refTableName) " ON " $(tableName) "." ["field[1]/field-sql-name"] " = " $(refTableName) "." $(refType) "Id\";"; out "\nif (!string.IsNullOrEmpty(filter))\n{"; out "\nif (where.Length > 0)"; indent inc; out "\nwhere += \" AND \";"; indent dec; out "\nwhere += filter;"; out "\n}"; indent dec; out "\nsql += \" WHERE \" + where;"; out "\nreturn _dataset." $(refTableName) ".FillData(sql);"; indent dec; out "\n}\n"; out "\nprotected internal void Set" ["field[0]/field-entity-type"] "(" ["field[0]/field-entity-type"] " value)\n{"; indent inc; out "\n" PrivateField(["field[0]/field-entity-type"]) " = value;"; indent dec; out "\n}\n"; indent dec; out "\n}\n\n"; end-stream } } function ProcessTable(node table, node tableTree) { context ($(table)) { string className = ["class-name"]; string datasetName = ["dataset-name"]; string dataSourceName = ["datasource-name"]; string entityName = ["entity-name"]; string tableName = ["table-name"]; string ids; string fields; string inFields; string inValues; string upFields; string values; string reader; string create; $(inValues) = ", \"\""; begin-stream $(className) foreach ["field"] { if (NodeIndex() > 0) { $(fields) << ", "; $(create) << ", "; if (NodeIndex() > 1) { $(ids) << ", "; $(upFields) << ", "; $(inFields) << ", "; } $(upFields) << "[" ["field-sql-name"] "] = {" NodeIndex() "}"; $(inFields) << "[" ["field-sql-name"] "]"; $(inValues) << ", " GetFieldValue(["."]); $(ids) << "{" NodeIndex() "}"; } $(create) << "[" ["field-sql-name"] "] " ["field-sql-type"]; if ([".[field-attribute == 'autoincremental']"]) $(create) << " IDENTITY(1,1)"; if ([".[field-attribute == 'primarykey']"]) $(create) << " PRIMARY KEY"; $(fields) << "[" ["field-sql-name"] "]"; $(values) << ", " GetFieldValue(["."]); $(reader) << "\nvalue."; if (["field-class-base-type"] != "") $(reader) << PrivateField(["field-class-base-name"]) " = reader.IsDBNull(" NodeIndex() ") ? null : new " ["field-class-base-type"] "((" ["field-class-type"] ")reader.GetValue(" NodeIndex() "));"; else { if (["field-class-base-name"] != "") $(reader) << ["field-class-base-name"] "."; $(reader) << PrivateField(["field-class-name"]) " = reader.IsDBNull(" NodeIndex() ") ? null : (" ["field-class-type"] ")"; if (IsEnum(["field-entity-type"])) $(reader) << "(int)"; $(reader) << "reader.GetValue(" NodeIndex() ");"; } } foreach ["field"] { string fieldEntityName = ["field-entity-type"]; bool isList = [".[field-attribute == 'list']"]; bool isRef =[".[field-attribute == 'ref']"]; if (($(isList) and not($(isRef))) or (not($(isList)) and $(isRef))) { string fieldEntityTable; context ($(tableTree)) $(fieldEntityTable) = ["table[entity-name == '" $(fieldEntityName) "']/table-name"]; if ($(fieldEntityName) != $(entityName)) $(create) << ", FOREIGN KEY ([" ["field-sql-name"] "]) REFERENCES " $(fieldEntityTable) "(" $(fieldEntityName) "Id) ON DELETE CASCADE ON UPDATE NO ACTION"; } } out "public partial class " $(className) " : DatabaseTable<" $(entityName) ">\n{"; indent inc; out "\nprotected internal " $(datasetName) " _dataset;"; foreach ["reference"] out "\nprotected " ["entity"] " " PrivateField(["entity-field"]) " = null;"; out "\n\npublic " $(className) "(" $(datasetName) " dataset)\n"; out "{"; indent inc; out "\n_dataset = dataset;"; indent dec; out "\n}\n"; out "\npublic override void Destroy()\n{"; indent inc; out "\nstring sql = \"IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '" $(tableName) "') DROP TABLE " $(tableName) "\";"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;\ncommand.ExecuteNonQuery();"; indent dec; out "\n}\n"; out "\npublic override void Create()\n{"; indent inc; out "\nDestroy();"; out "\nstring sql = \"CREATE TABLE " $(tableName) "(" $(create) ")\";"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;\ncommand.ExecuteNonQuery();"; indent dec; out "\n}\n"; out "\npublic override " $(entityName) " Add(" $(entityName) " value)\n{"; indent inc; foreach ["reference"] { out "\nif (" PrivateField(["entity-field"]) " != null)"; indent inc; out "\nvalue." PrivateField(["entity-field"]) " = " PrivateField(["entity-field"]) ";"; indent dec; } out "\nstring sql = String.Format(\"INSERT INTO " $(tableName) "(" $(inFields) ") VALUES (" $(ids) ")\"" $(inValues) ");"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;"; out "\ncommand.ExecuteNonQuery();"; out "\ncommand.CommandText = \"SELECT IDENT_CURRENT('" $(tableName) "')\";"; out "\nvalue." PrivateField($(entityName)) "Id = (int)(decimal)command.ExecuteScalar();"; out "\nvalue._table = this;"; out "\nreturn value;"; indent dec; out "\n}\n"; out "\npublic override void Delete(int " ToPascalCase($(entityName)) "Id)\n{"; indent inc; out "\nstring sql = String.Format(\"DELETE FROM " $(tableName) " WHERE " $(entityName) "Id = \" + " ToPascalCase($(entityName)) "Id);"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;\ncommand.ExecuteNonQuery();"; indent dec; out "\n}\n"; out "\npublic override void Delete(" $(entityName) " value)\n{"; indent inc; out "\nDelete((int)value." $(entityName) "Id);"; indent dec; out "\n}\n"; out "\npublic override void Update(" $(entityName) " value)\n{"; indent inc; foreach ["reference"] { out "\nif (" PrivateField(["entity-field"]) " != null)"; indent inc; out "\nvalue." PrivateField(["entity-field"]) " = " PrivateField(["entity-field"]) ";"; indent dec; } out "\nstring sql = String.Format(\"UPDATE " $(tableName) " SET " $(upFields) " WHERE " ["field[0]/field-sql-name"] " = {0}\"" $(values) ");"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;\ncommand.ExecuteNonQuery();"; out "\nvalue._table = this;"; indent dec; out "\n}\n"; out "\npublic override " $(entityName) " GetById(Int32 id)\n{"; indent inc; out "\nreturn GetList(\"" $(entityName) "Id = \" + id)[0];"; indent dec; out "\n}\n"; out "\npublic void Execute(string sql)\n{"; indent inc; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;\ncommand.ExecuteNonQuery();"; indent dec; out "\n}\n"; out "\npublic override " $(entityName) "[] GetList(string filter)\n{"; indent inc; out "\nstring where = \"\";"; out "\nstring sql = \"SELECT " $(fields) " FROM " $(tableName) "\";"; foreach ["reference"] { out "\nif (" PrivateField(["entity-field"]) " != null)"; indent inc; out "\nwhere += \"" ["field"] " = \" + " PrivateField(["entity-field"]) "." PrivateField(["entity"]) "Id + \" \";"; indent dec; } out "\nif (!string.IsNullOrEmpty(filter))\n{"; out "\nif (where.Length > 0)"; indent inc; out "\nwhere += \" AND \";"; indent dec; out "\nwhere += filter;"; out "\n}"; indent dec; out "\nif (where != \"\") sql += \" WHERE \" + where;"; out "\nreturn FillData(sql);"; indent dec; out "\n}\n"; out "\npublic override " $(entityName) "[] FillData(string sql)\n{"; indent inc; out "\nList<" $(entityName) "> list = new List<" $(entityName) ">();"; out "\nDbCommand command = _dataset." PrivateField($(dataSourceName)) ".CreateCommand();"; out "\ncommand.CommandText = sql;"; out "\nlock (_dataset." PrivateField($(dataSourceName)) ")\n{"; indent inc; out "\nDbDataReader reader = command.ExecuteReader();"; out "\ntry\n{"; indent inc; out "\nwhile (reader.Read())\n{"; indent inc; out "\n" $(entityName) " value = new " $(entityName) "();"; out $(reader); out "\nvalue._partial = false;"; out "\nvalue._table = this;"; out "\nlist.Add(value);"; indent dec; out "\n}"; out "\n}"; indent dec; out "\nfinally\n{"; indent inc; out "\nreader.Close();"; indent dec; out "\n}"; indent dec; out "\n}"; out "\nreturn list.ToArray();"; indent dec; out "\n}\n"; foreach ["reference"] { out "\nprotected internal void Set" ["entity-field"] "(" ["entity"] " value)\n{"; indent inc; out "\n" PrivateField(["entity-field"]) " = value;"; indent dec; out "\n}\n"; } indent dec; out "\n}\n\n"; end-stream } } function ProcessDataset(string datasetName, node tableTree) { context ($(tableTree)) { begin-stream $(datasetName) out "public partial class " $(datasetName) " : MarshalByRefObject\n{"; indent inc; foreach ["table[dataset-name == '" $(datasetName) "']"] { out "\nprotected internal "; if (["entity-name"] == "") out ["table-name"]; else out ["entity-name"]; out "Table " PrivateField(["table-name"]) ";"; } out "\nprotected string _dataPath;"; node dataSource; context ($(root)) { foreach ["dataset[dataset-name == '" $(datasetName) "']/>/data-source-name"] { string source = ["."]; context ($(dataSource)) { if (not([".[data-source == '" $(source) "']"])) AddNode($(dataSource), "", "data-source", $(source)); } } } string openBody; string closeBody; context ($(dataSource)) { foreach ["data-source"] { node curSource; string sourceName = ["."]; context ($(root)) $(curSource) = ["datasource[data-source-name == '" $(sourceName) "']"]; context ($(curSource)) { string connString = "@" ["connection-string"] ".Replace(\"$(datapath)\", _dataPath)"; out "\nprotected internal "; switch ["."] { case ([".[data-provider == 'sql']"]) out "System.Data.SqlClient.SqlConnection"; $(openBody) << "\n" PrivateField($(sourceName)) " = new System.Data.SqlClient.SqlConnection(" $(connString) ");"; $(openBody) << "\n" PrivateField($(sourceName)) ".Open();"; $(closeBody) << "\n" PrivateField($(sourceName)) ".Close();"; case ([".[data-provider == 'xml']"]) out "XmlDocument"; $(openBody) << "\n" PrivateField($(sourceName)) " = new XmlDocument();"; $(openBody) << "\n" PrivateField($(sourceName)) ".Load(" $(connString) ");"; $(closeBody) << "\n" PrivateField($(sourceName)) ".Save(" $(connString) ");"; } out " " PrivateField($(sourceName)) ";"; } } } out "\n\npublic " $(datasetName) "()\n{"; indent inc; foreach ["table[dataset-name == '" $(datasetName) "']"] { out "\n" PrivateField(["table-name"]) " = new "; if (["entity-name"] == "") out ["table-name"]; else out ["entity-name"]; out "Table(this);"; } indent dec; out "\n}\n"; out "\npublic void Open(string dataPath)\n{"; indent inc; out "\n_dataPath = dataPath;"; out $(openBody); indent dec; out "\n}\n"; out "\npublic void Close()\n{"; indent inc; out $(closeBody); indent dec; out "\n}\n"; out "\npublic void Create()\n{"; indent inc; foreach ["table[dataset-name == '" $(datasetName) "']"] { out "\n" PrivateField(["table-name"]) ".Create();"; } indent dec; out "\n}\n"; foreach ["table[dataset-name == '" $(datasetName) "']"] { if (not([".[table-attribute == 'relation' or table-attribute == 'hidden']"])) { out "\npublic " ["entity-name"] "Table " ["table-name"] "\n{"; indent inc; out "\nget\n{"; indent inc; out "\nreturn " PrivateField(["table-name"]) ";"; indent dec; out "\n}"; indent dec; out "\n}\n"; } } indent dec; out "\n}\n\n"; end-stream } } function ProcessEnum(node enum) { context ($(enum)) { out "public enum " ["enum-name"] "\n{"; indent inc; out "\n"; foreach ["enum-entry-list/enum-entry"] { if (NodeIndex() > 0) out ",\n"; out ["enum-value-name"] " = " ["enum-value"]; } indent dec; out "\n}\n\n"; } } function Main() { node tableTree = BuildTableTree(); node classTree = BuildClassTree($(tableTree)); out "using System;"; out "\nusing System.Xml;"; out "\nusing System.Data;"; out "\nusing System.Data.Common;"; out "\nusing System.Collections.Generic;"; out "\nusing DataAccess;\n"; out "namespace ProjectManager.Server.Data \n{\n"; foreach ["enum"] ProcessEnum(["."]); foreach ["dataset/dataset-name"] ProcessDataset(["."], $(tableTree)); context ($(classTree)) { foreach ["class"] ProcessClass(["."], $(tableTree)); } context ($(tableTree)) { foreach ["table"] { if ([".[table-attribute == 'relation']"]) ProcessRelationTable(["."], $(tableTree)); else ProcessTable(["."], $(tableTree)); } } out "}\n"; }