@ tefigel #### # # Generate a complete DataTable Class, repeatedly scanning # lists METATABLE, _PKEY, and CUR_RELATIONS. # #### interface(METATABLE_INDEX,METATABLE_COUNT,METATABLE) set CUR_METACOLUMN_LIST=~list_contents(METATABLE) @ text _ Public Class METATABLE&DataTable Inherits DataTable Implements System.Collections.IEnumerable @ for METACOLUMN=CUR_METACOLUMN_LIST Private column&MetaColInfo(METACOLUMN,id) As DataColumn @ endfor Friend Sub New() MyBase.New("METATABLE") Me.InitClass End Sub Friend Sub New(ByVal table As DataTable) MyBase.New(table.TableName) If (table.CaseSensitive <> table.DataSet.CaseSensitive) Then Me.CaseSensitive = table.CaseSensitive End If If (table.Locale.ToString <> table.DataSet.Locale.ToString) Then Me.Locale = table.Locale End If If (table.Namespace <> table.DataSet.Namespace) Then Me.Namespace = table.Namespace End If Me.Prefix = table.Prefix Me.MinimumCapacity = table.MinimumCapacity End Sub _ Public ReadOnly Property Count As Integer Get Return Me.Rows.Count End Get End Property @ for METACOLUMN=CUR_METACOLUMN_LIST @ set COLUMN_ID=MetaColInfo(METACOLUMN,id) Friend ReadOnly Property COLUMN_ID&Column As DataColumn Get Return Me.column&COLUMN_ID End Get End Property @ endfor Public Default ReadOnly Property Item(ByVal index As Integer) As METATABLE&Row Get Return CType(Me.Rows(index),METATABLE&Row) End Get End Property Public Event METATABLE&RowChanged As METATABLE&RowChangeEventHandler Public Event METATABLE&RowChanging As METATABLE&RowChangeEventHandler Public Event METATABLE&RowDeleted As METATABLE&RowChangeEventHandler Public Event METATABLE&RowDeleting As METATABLE&RowChangeEventHandler Public Overloads Sub Add&METATABLE&Row(ByVal row As METATABLE&Row) Me.Rows.Add(row) End Sub Public Overloads Function Add&METATABLE&Row(~columns_byval(METATABLE)) As METATABLE&Row Dim row&METATABLE&Row As METATABLE&Row = CType(Me.NewRow,METATABLE&Row) row&METATABLE&Row.ItemArray = New Object() {~new_row(METATABLE)} Me.Rows.Add(row&METATABLE&Row) Return row&METATABLE&Row End Function Public Function ~mk_findby(METATABLE) As METATABLE&Row Return CType(Me.Rows.Find(New Object() {~list_contents(METATABLE&_PKEY)}),METATABLE&Row) End Function Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator Return Me.Rows.GetEnumerator End Function Public Overrides Function Clone() As DataTable Dim cln As METATABLE&DataTable = CType(MyBase.Clone,METATABLE&DataTable) cln.InitVars Return cln End Function Protected Overrides Function CreateInstance() As DataTable Return New METATABLE&DataTable End Function Friend Sub InitVars() @ for METACOLUMN=CUR_METACOLUMN_LIST Me.column&MetaColInfo(METACOLUMN,id) = Me.Columns("MetaColInfo(METACOLUMN,db_id)") @ endfor End Sub Private Sub InitClass() @ for METACOLUMN=CUR_METACOLUMN_LIST @ set COLUMN_ID=MetaColInfo(METACOLUMN,id) @ set COLUMN_DBID=MetaColInfo(METACOLUMN,db_id) @ set COLUMN_TYPE=MetaColInfo(METACOLUMN,type) @ Me.column&COLUMN_ID = New DataColumn("COLUMN_DBID", GetType(System.COLUMN_TYPE), Nothing, System.Data.MappingType.Element) Me.Columns.Add(Me.column&COLUMN_ID) @ endfor Me.Constraints.Add(New UniqueConstraint("~value(METATABLE&_PKEY_ID)", New DataColumn() {~list_contents(METATABLE&_PKEY,Me.column)}, true)) @ @ list_process(METATABLE,set_constraints) @ End Sub Public Function New&METATABLE&Row() As METATABLE&Row Return CType(Me.NewRow,METATABLE&Row) End Function Protected Overrides Function NewRowFromBuilder(ByVal builder As DataRowBuilder) As DataRow Return New METATABLE&Row(builder) End Function Protected Overrides Function GetRowType() As System.Type Return GetType(METATABLE&Row) End Function Protected Overrides Sub OnRowChanged(ByVal e As DataRowChangeEventArgs) MyBase.OnRowChanged(e) If (Not (Me.METATABLE&RowChangedEvent) Is Nothing) Then RaiseEvent METATABLE&RowChanged(Me, New METATABLE&RowChangeEvent(CType(e.Row,METATABLE&Row), e.Action)) End If End Sub Protected Overrides Sub OnRowChanging(ByVal e As DataRowChangeEventArgs) MyBase.OnRowChanging(e) If (Not (Me.METATABLE&RowChangingEvent) Is Nothing) Then RaiseEvent METATABLE&RowChanging(Me, New METATABLE&RowChangeEvent(CType(e.Row,METATABLE&Row), e.Action)) End If End Sub Protected Overrides Sub OnRowDeleted(ByVal e As DataRowChangeEventArgs) MyBase.OnRowDeleted(e) If (Not (Me.METATABLE&RowDeletedEvent) Is Nothing) Then RaiseEvent METATABLE&RowDeleted(Me, New METATABLE&RowChangeEvent(CType(e.Row,METATABLE&Row), e.Action)) End If End Sub Protected Overrides Sub OnRowDeleting(ByVal e As DataRowChangeEventArgs) MyBase.OnRowDeleting(e) If (Not (Me.METATABLE&RowDeletingEvent) Is Nothing) Then RaiseEvent METATABLE&RowDeleting(Me, New METATABLE&RowChangeEvent(CType(e.Row,METATABLE&Row), e.Action)) End If End Sub Public Sub Remove&METATABLE&Row(ByVal row As METATABLE&Row) Me.Rows.Remove(row) End Sub End Class _ Public Class METATABLE&Row Inherits DataRow Private table&METATABLE As METATABLE&DataTable Friend Sub New(ByVal rb As DataRowBuilder) MyBase.New(rb) Me.table&METATABLE = CType(Me.Table,METATABLE&DataTable) End Sub @ for METACOLUMN=CUR_METACOLUMN_LIST @ set COLUMN_ID=MetaColInfo(METACOLUMN,id) @ set COLUMN_DBID=MetaColInfo(METACOLUMN,db_id) @ set COLUMN_TYPE=MetaColInfo(METACOLUMN,VBtype) @ set COLUMN_NULL=MetaColInfo(METACOLUMN,nullable) @ Public Property COLUMN_ID As COLUMN_TYPE Get @ if COLUMN_NULL=false Return CType(Me(Me.table&METATABLE.COLUMN_ID&Column),COLUMN_TYPE) @ else Try Return CType(Me(Me.table&METATABLE.COLUMN_ID&Column),COLUMN_TYPE) Catch e As InvalidCastException Throw New StrongTypingException("Cannot get value because it is DBNull.", e) End Try @ endif End Get Set Me(Me.table&METATABLE.COLUMN_ID&Column) = value End Set End Property @ endfor @ @ for METARELATION=~list_contents(CUR_RELATIONS) @ set P_TABLE=MetaRelInfo(METARELATION,parent_table) @ set RELATION_ID=MetaRelInfo(METARELATION,id) @ set C_TABLE=MetaRelInfo(METARELATION,child_table) @ @ if C_TABLE=METATABLE Public Property P_TABLE&Row As P_TABLE&Row Get Return CType(Me.GetParentRow(Me.Table.ParentRelations("RELATION_ID")),P_TABLE&Row) End Get Set Me.SetParentRow(value, Me.Table.ParentRelations("RELATION_ID")) End Set End Property @ endif @ endfor @ @ for METACOLUMN=CUR_METACOLUMN_LIST @ set COLUMN_ID=MetaColInfo(METACOLUMN,id) @ set COLUMN_NULL=MetaColInfo(METACOLUMN,nullable) @ @ if COLUMN_NULL#false Public Function Is&COLUMN_ID&Null() As Boolean Return Me.IsNull(Me.table&METATABLE.COLUMN_ID&Column) End Function Public Sub Set&COLUMN_ID&Null() Me(Me.table&METATABLE.COLUMN_ID&Column) = System.Convert.DBNull End Sub @ endif @ endfor @ @ for METARELATION=~list_contents(CUR_RELATIONS) @ set P_TABLE=MetaRelInfo(METARELATION,parent_table) @ set RELATION_ID=MetaRelInfo(METARELATION,id) @ set C_TABLE=MetaRelInfo(METARELATION,child_table) @ @ if P_TABLE=METATABLE Public Function Get&C_TABLE&Rows() As C_TABLE&Row() Return CType(Me.GetChildRows(Me.Table.ChildRelations("RELATION_ID")),C_TABLE&Row()) End Function @ endif @ @ endfor End Class _ Public Class METATABLE&RowChangeEvent Inherits EventArgs Private eventRow As METATABLE&Row Private eventAction As DataRowAction Public Sub New(ByVal row As METATABLE&Row, ByVal action As DataRowAction) MyBase.New Me.eventRow = row Me.eventAction = action End Sub Public ReadOnly Property Row As METATABLE&Row Get Return Me.eventRow End Get End Property Public ReadOnly Property Action As DataRowAction Get Return Me.eventAction End Get End Property End Class