From 3e3e3d2ea82f5ecd22e710e55ffc53f22fbd66d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Otter?= Date: Sat, 11 May 2024 18:53:20 +0200 Subject: [PATCH] Tables and Indexes --- cubesql-webadmin.xojo_project | 7 +- styles/CheckboxCellRenderer.xojo_code | 145 ++ webapp/Session.xojo_code | 17 + .../data/cntTablesIndexes.xojo_code | 1059 ++++++++++++++ webapp/dialogs/dlgIndexCreate.xojo_code | 798 ++++++++++ webapp/dialogs/dlgTableEditor.xojo_code | 1293 +++++++++++++++++ webapp/dialogs/dlgTableEditorField.xojo_code | 840 +++++++++++ webapp/main/CubeSQLAdminPage.xojo_code | 4 + webapp/modCubeSQLAdmin.xojo_code | 33 +- 9 files changed, 4190 insertions(+), 6 deletions(-) create mode 100644 styles/CheckboxCellRenderer.xojo_code create mode 100644 webapp/containers/data/cntTablesIndexes.xojo_code create mode 100644 webapp/dialogs/dlgIndexCreate.xojo_code create mode 100644 webapp/dialogs/dlgTableEditor.xojo_code create mode 100644 webapp/dialogs/dlgTableEditorField.xojo_code diff --git a/cubesql-webadmin.xojo_project b/cubesql-webadmin.xojo_project index 0beb3b8..66c1d87 100644 --- a/cubesql-webadmin.xojo_project +++ b/cubesql-webadmin.xojo_project @@ -4,6 +4,7 @@ MinIDEVersion=20200200 OrigIDEVersion=20240100 Folder=resources;resources;&h0000000035B107FF;&h0000000000000000;false Folder=styles;styles;&h00000000139DBFFF;&h0000000000000000;false +Class=CheckboxCellRenderer;styles/CheckboxCellRenderer.xojo_code;&h000000007F7FF7FF;&h00000000139DBFFF;false Folder=webapp;webapp;&h0000000018D38FFF;&h0000000000000000;false Folder=main;webapp/main;&h000000001D9447FF;&h0000000018D38FFF;false WebView=LoginPage;webapp/main/LoginPage.xojo_code;&h000000005492FFFF;&h000000001D9447FF;false @@ -16,6 +17,9 @@ WebView=dlgGetServerKey;webapp/dialogs/dlgGetServerKey.xojo_code;&h0000000076F62 WebView=dlgDatabaseCreate;webapp/dialogs/dlgDatabaseCreate.xojo_code;&h0000000045C397FF;&h0000000054A427FF;false WebView=dlgDatabaseUpload;webapp/dialogs/dlgDatabaseUpload.xojo_code;&h00000000375D2FFF;&h0000000054A427FF;false WebView=dlgDatabaseSchedules;webapp/dialogs/dlgDatabaseSchedules.xojo_code;&h00000000514E3FFF;&h0000000054A427FF;false +WebView=dlgIndexCreate;webapp/dialogs/dlgIndexCreate.xojo_code;&h000000000919DFFF;&h0000000054A427FF;false +WebView=dlgTableEditor;webapp/dialogs/dlgTableEditor.xojo_code;&h0000000035FA4FFF;&h0000000054A427FF;false +WebView=dlgTableEditorField;webapp/dialogs/dlgTableEditorField.xojo_code;&h000000007BD80FFF;&h0000000054A427FF;false WebView=dlgSchedule;webapp/dialogs/dlgSchedule.xojo_code;&h00000000476F1FFF;&h0000000054A427FF;false WebView=dlgScheduleDatabases;webapp/dialogs/dlgScheduleDatabases.xojo_code;&h000000005565B7FF;&h0000000054A427FF;false WebView=dlgUserCreate;webapp/dialogs/dlgUserCreate.xojo_code;&h0000000064C14FFF;&h0000000054A427FF;false @@ -33,6 +37,7 @@ Folder=server;webapp/containers/server;&h0000000045A527FF;&h000000005859EFFF;fal Folder=data;webapp/containers/data;&h00000000107E37FF;&h000000005859EFFF;false WebContainer=cntDatabases;webapp/containers/data/cntDatabases.xojo_code;&h0000000040B4DFFF;&h00000000107E37FF;false WebContainer=cntDatabasesEncryption;webapp/containers/data/cntDatabasesEncryption.xojo_code;&h0000000044B7E7FF;&h00000000107E37FF;false +WebContainer=cntTablesIndexes;webapp/containers/data/cntTablesIndexes.xojo_code;&h000000004B6CDFFF;&h00000000107E37FF;false WebContainer=cntBackups;webapp/containers/data/cntBackups.xojo_code;&h000000004237B7FF;&h00000000107E37FF;false WebContainer=cntSchedules;webapp/containers/data/cntSchedules.xojo_code;&h000000002F98DFFF;&h00000000107E37FF;false WebContainer=cntRegistrationAction;webapp/containers/server/cntRegistrationAction.xojo_code;&h000000000788EFFF;&h0000000045A527FF;false @@ -97,7 +102,7 @@ WebDebugPort=8080 WebLivePort=80 WebSecurePort=443 WebProtocol=1 -WebHTMLHeader= +WebHTMLHeader= WebHostingIdentifier= WebHostingAppName=cubeSQLWebAdmin WebHostingDomain= diff --git a/styles/CheckboxCellRenderer.xojo_code b/styles/CheckboxCellRenderer.xojo_code new file mode 100644 index 0000000..eaed0ca --- /dev/null +++ b/styles/CheckboxCellRenderer.xojo_code @@ -0,0 +1,145 @@ +#tag Class +Protected Class CheckboxCellRenderer +Inherits WebListboxCellRenderer + #tag Event + Sub Deserialize(js As JSONItem) + // Restore the values of the column to the object + + Checked = js.Lookup("checked", False).BooleanValue + + End Sub + #tag EndEvent + + #tag Event + Function JavascriptClassCode(s As WebSession) As String + #Pragma unused s + + Var code() As String + + // All custom cells extend the XojoWeb.ListboxCellRenderer class + code.Add "class CheckboxCell extends XojoWeb.ListboxCellRenderer {" + + // You must override the "render" method + // controlID (string): The identifier of the listbox control that the renderer is currently running under + // row (HTMLElement): The HTML DOM element of the entire row. This is provided so that you can make modifications to the entire row if necessary, like applying a style. + // data (object): The data that the Xojo portion of your control provided for this column + // rowIndex (number): The row number that is currently being rendered + // columnIndex (number): The column number that is currently being rendered + // cell (HTMLElement): The HTML DOM element of the cell that your renderer is responsible for. + code.Add " render(controlID, row, data, rowIndex, columnIndex, cell) {" + + // Remove the text that's already in the cell + code.Add " cell.innerHTML= '';" + + // Make a bootstrap checkbox + code.Add " let checkbox = document.createElement('input');" + code.Add " checkbox.type = 'checkbox';" + code.Add " checkbox.className = 'form-check-input';" + code.Add " checkbox.checked = data.checked;" + code.Add " checkbox.style.marginLeft = '6px'" + code.Add " checkbox.style.marginRight = '6px'" + + // Handle clicking on the button + code.Add " checkbox.addEventListener('click', function(ev) {" + code.Add " ev.stopPropagation();" + code.Add " var obj = new XojoWeb.JSONItem;" + code.Add " obj.set('row', rowIndex);" // All extensions should include the row (default is -1) + code.Add " obj.set('column', columnIndex);" // All extensions should include the column (default is -1) + code.Add " obj.set('identifier', 'idCheckbox');" // All extensions should include an identifier (default is "") + code.Add " obj.set('value', checkbox.checked);" // Including a value is optional (default is null) + code.Add " XojoWeb.controls.lookup(controlID).triggerServerEvent('CustomCellAction', obj);" + code.Add " return false;" + code.Add " });" + + // Add our new content + code.Add " cell.appendChild(checkbox);" + code.Add " }" + code.Add "}" + + Return String.FromArray(code, EndOfLine.Windows) + + + End Function + #tag EndEvent + + #tag Event + Function Serialize() As JSONItem + // Use this code to convert the value(s) needed to render your codes to JSON. + // This is also used by non-datasource listboxes to store these settings for your column. + + Var js As New JSONItem + js.Value("checked") = Checked + + return js + End Function + #tag EndEvent + + + #tag Method, Flags = &h0 + Sub Constructor(isChecked As Boolean) + // Calling the overridden superclass constructor. + Super.Constructor + + Self.Checked = isChecked + + End Sub + #tag EndMethod + + + #tag Property, Flags = &h0 + Checked As Boolean + #tag EndProperty + + + #tag ViewBehavior + #tag ViewProperty + Name="Name" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Index" + Visible=true + Group="ID" + InitialValue="-2147483648" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Super" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Left" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Top" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Checked" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag EndViewBehavior +End Class +#tag EndClass diff --git a/webapp/Session.xojo_code b/webapp/Session.xojo_code index 4621f9d..9be067d 100644 --- a/webapp/Session.xojo_code +++ b/webapp/Session.xojo_code @@ -38,6 +38,18 @@ Inherits WebSession rs.Close End If + rs = db.SelectSQL("SHOW INFO FOR KEY engine_version") + If (rs <> Nil) Then + + If (rs.RowCount > 0) Then + rs.MoveToFirstRow + + DBEngineVersion = Version_AsDouble(rs.Column("value").StringValue) + End If + + rs.Close + End If + Catch err As DatabaseException Return False @@ -60,6 +72,7 @@ Inherits WebSession DB = Nil ClientId = -1 + DBEngineVersion = 0.0 End Sub #tag EndMethod @@ -73,6 +86,10 @@ Inherits WebSession DB As CubeSQLServer #tag EndProperty + #tag Property, Flags = &h0 + DBEngineVersion As Double + #tag EndProperty + #tag ViewBehavior #tag ViewProperty diff --git a/webapp/containers/data/cntTablesIndexes.xojo_code b/webapp/containers/data/cntTablesIndexes.xojo_code new file mode 100644 index 0000000..86c008d --- /dev/null +++ b/webapp/containers/data/cntTablesIndexes.xojo_code @@ -0,0 +1,1059 @@ +#tag WebContainerControl +Begin cntDatasourceBase cntTablesIndexes + Compatibility = "" + ControlCount = 0 + ControlID = "" + Enabled = True + Height = 500 + Indicator = 0 + LayoutDirection = 0 + LayoutType = 0 + Left = 0 + LockBottom = False + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + ScrollDirection = 0 + TabIndex = 0 + Top = 0 + Visible = True + Width = 750 + _mDesignHeight = 0 + _mDesignWidth = 0 + _mPanelIndex = -1 + Begin WebListBox lstInfos + ColumnCount = 1 + ColumnWidths = "" + ControlID = "" + Enabled = True + HasHeader = True + Height = 342 + HighlightSortedColumn= True + Index = -2147483648 + Indicator = 0 + InitialValue = "" + LastAddedRowIndex= 0 + LastColumnIndex = 0 + LastRowIndex = 0 + Left = 0 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + NoRowsMessage = "No Tables & Indexes" + ProcessingMessage= "" + RowCount = 0 + RowSelectionType= 1 + Scope = 2 + SearchCriteria = "" + SelectedRowColor= &c0d6efd + SelectedRowIndex= 0 + TabIndex = 0 + TabStop = True + Tooltip = "" + Top = 0 + Visible = True + Width = 750 + _mPanelIndex = -1 + End + Begin WebRectangle rctFilter + BackgroundColor = &cFFFFFF + ControlCount = 0 + ControlID = "" + Enabled = True + HasBackgroundColor= False + Height = 75 + Index = -2147483648 + Indicator = 0 + LayoutDirection = 0 + LayoutType = 0 + Left = 0 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = False + LockVertical = False + PanelIndex = "0" + Scope = 2 + TabIndex = 1 + TabStop = True + Tooltip = "" + Top = 350 + Visible = True + Width = 750 + _mDesignHeight = 0 + _mDesignWidth = 0 + _mPanelIndex = -1 + Begin WebLabel labFilter + Bold = True + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 20 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFilter" + Scope = 2 + TabIndex = 0 + TabPanelIndex = -1 + TabStop = True + Text = "View" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 370 + Underline = False + Visible = True + Width = 60 + _mPanelIndex = -1 + End + Begin WebLabel labFilterDatabase + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 151 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFilter" + Scope = 2 + TabIndex = 1 + TabPanelIndex = -1 + TabStop = True + Text = "Database:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 370 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + Begin WebPopupMenu lstFilterDatabase + ControlID = "" + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + InitialValue = "" + LastAddedRowIndex= 0 + LastRowIndex = 0 + Left = 299 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + PanelIndex = "0" + Parent = "rctFilter" + RowCount = 0 + Scope = 2 + SelectedRowIndex= 0 + SelectedRowText = "" + TabIndex = 2 + TabPanelIndex = -1 + TabStop = True + Tooltip = "" + Top = 370 + Visible = True + Width = 400 + _mPanelIndex = -1 + End + End + Begin WebButton btnDrop + AllowAutoDisable= False + Cancel = False + Caption = "Drop" + ControlID = "" + Default = False + Enabled = False + Height = 38 + Index = -2147483648 + Indicator = 4 + Left = 630 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + PanelIndex = "0" + Scope = 2 + TabIndex = 4 + TabStop = True + Tooltip = "" + Top = 442 + Visible = True + Width = 100 + _mPanelIndex = -1 + End + Begin WebMessageDialog dlgDrop + ControlID = "" + Enabled = True + Explanation = "" + Index = -2147483648 + Indicator = 0 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Message = "" + PanelIndex = "0" + Scope = 2 + Title = "" + Tooltip = "" + _mPanelIndex = -1 + End + Begin WebButton btnCreateTable + AllowAutoDisable= False + Cancel = False + Caption = "Create Table" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 20 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = False + LockVertical = False + PanelIndex = "0" + Scope = 2 + TabIndex = 2 + TabStop = True + Tooltip = "" + Top = 442 + Visible = True + Width = 120 + _mPanelIndex = -1 + End + Begin WebButton btnCreateIndex + AllowAutoDisable= False + Cancel = False + Caption = "Create Index" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 148 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = False + LockVertical = False + PanelIndex = "0" + Scope = 2 + TabIndex = 3 + TabStop = True + Tooltip = "" + Top = 442 + Visible = True + Width = 120 + _mPanelIndex = -1 + End + Begin WebButton btnAlterTable + AllowAutoDisable= False + Cancel = False + Caption = "Alter Table" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 502 + LockBottom = True + LockedInPosition= False + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + PanelIndex = "0" + Scope = 2 + TabIndex = 5 + TabStop = True + Tooltip = "" + Top = 442 + Visible = True + Width = 120 + _mPanelIndex = -1 + End +End +#tag EndWebContainerControl + +#tag WindowCode + #tag Event + Sub Closed() + Try + Session.DB.ExecuteSQL("CLEAR CURRENT DATABASE") + + Catch err As DatabaseException + + End Try + + End Sub + #tag EndEvent + + + #tag Method, Flags = &h21 + Private Sub ActionAlterTable() + Var selectedItem As Dictionary = Me.GetSelectedTableRowTag() + If (selectedItem = Nil) Then Return + If (selectedItem.Lookup("type", "").StringValue <> "table") Then Return + If (selectedItem.Lookup("name", "").StringValue = "") Then Return + + Var dlgTable As New dlgTableEditor + AddHandler dlgTable.TableEditorSaveAction, WeakAddressOf ActionAlterTableButtonPressed + dlgTable.ShowAsAlter(selectedItem.Lookup("name", "").StringValue) + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function ActionAlterTableButtonPressed(obj As dlgTableEditor, Name As String, SQLStatements() As String) As Boolean + #Pragma unused obj + + If (Name = "") Then Return False + If (SQLStatements.LastIndex < 0) Then Return False + + Try + + For i As Integer = 0 To SQLStatements.LastIndex + Session.DB.ExecuteSQL(SQLStatements(i)) + Next + + Session.DB.ExecuteSQL("COMMIT") + + Catch err As DatabaseException + ShowErrorDialog("Alter Table", "Could not alter table.", err) + Return False + + End Try + + 'Success - no dialog + Var selectRowTag As New Dictionary + selectRowTag.Value("type") = "table" + selectRowTag.Value("name") = Name + + Me.RefreshInfos(selectRowTag) + Return True + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub ActionCreateIndex() + Var databasename As String = Me.GetSelectedDatabasename() + If (databasename = "") Then Return + + Var dlgIndex As New dlgIndexCreate + AddHandler dlgIndex.IndexCreateAction, WeakAddressOf ActionCreateIndexButtonPressed + dlgIndex.Show(databasename) + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function ActionCreateIndexButtonPressed(obj As dlgIndexCreate, Name As String, Table As String, Fields() As String) As Boolean + #Pragma unused obj + + If (Name = "") Or (Table = "") Then Return False + If (Fields.LastIndex < 0) Then Return False + + Try + Var escapedFields() As String + For i As Integer = 0 To Fields.LastIndex + escapedFields.Add(Fields(i).EscapeSqlFieldIfRequired) + Next + + Session.DB.ExecuteSQL("CREATE INDEX " + Name.EscapeSqlFieldIfRequired + " ON " + Table.EscapeSqlFieldIfRequired + " (" + String.FromArray(escapedFields, ", ") + ")") + Session.DB.ExecuteSQL("COMMIT") + + Catch err As DatabaseException + ShowErrorDialog("Create Index", "Could not create index.", err) + Return False + + End Try + + 'Success - no dialog + Var selectRowTag As New Dictionary + selectRowTag.Value("type") = "index" + selectRowTag.Value("name") = Name + + Me.RefreshInfos(selectRowTag) + Return True + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub ActionCreateTable() + Var dlgTable As New dlgTableEditor + AddHandler dlgTable.TableEditorSaveAction, WeakAddressOf ActionCreateTableButtonPressed + dlgTable.ShowAsCreate() + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function ActionCreateTableButtonPressed(obj As dlgTableEditor, Name As String, SQLStatements() As String) As Boolean + #Pragma unused obj + + If (Name = "") Then Return False + If (SQLStatements.LastIndex < 0) Then Return False + + Try + + For i As Integer = 0 To SQLStatements.LastIndex + Session.DB.ExecuteSQL(SQLStatements(i)) + Next + + Session.DB.ExecuteSQL("COMMIT") + + Catch err As DatabaseException + ShowErrorDialog("Create Table", "Could not create table.", err) + Return False + + End Try + + 'Success - no dialog + Var selectRowTag As New Dictionary + selectRowTag.Value("type") = "table" + selectRowTag.Value("name") = Name + + Me.RefreshInfos(selectRowTag) + Return True + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub ActionDrop() + Var item As Dictionary = Me.GetSelectedTableRowTag() + If (item = Nil) Then Return + + dlgDrop.Title = "Drop " + item.Lookup("type", "").StringValue.Titlecase + dlgDrop.Indicator = Indicators.Danger + dlgDrop.ActionButton.Caption = "Drop" + dlgDrop.CancelButton.Visible = True + dlgDrop.Message = "Are you sure you want to drop " + item.Lookup("type", "").StringValue + " '" + item.Lookup("name", "").StringValue + "'?" + dlgDrop.Explanation = "This action cannot be undone." + + edictActionItem = item + + dlgDrop.ShowWithActionDanger() + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub ActionDropButtonPressed(obj As WebMessageDialog, button As WebMessageDialogButton) + Var dictDropItem As Dictionary = edictActionItem + edictActionItem = Nil + + If (button <> obj.ActionButton) Then Return + If (dictDropItem = Nil) Then Return + + Try + Session.DB.ExecuteSQL("DROP " + dictDropItem.Lookup("type", "").StringValue.Uppercase + " IF EXISTS " + dictDropItem.Lookup("name", "").StringValue.EscapeSqlFieldIfRequired) + Session.DB.ExecuteSQL("COMMIT") + + Catch err As DatabaseException + ShowErrorDialog("Drop " + dictDropItem.Lookup("type", "").StringValue.Titlecase, "Could not drop " + dictDropItem.Lookup("type", "").StringValue.Lowercase + ".", err) + + Finally + Me.RefreshInfos() + + End Try + + End Sub + #tag EndMethod + + #tag Method, Flags = &h0 + Sub Constructor() + Super.Constructor + + Me.Area = "Data" + Me.Title = "Tables & Indexes" + Me.Table = lstInfos + Me.SearchAvailable = True + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function GetSelectedDatabasename() As String + If (lstFilterDatabase.SelectedRowIndex < 0) Then Return "" + Return lstFilterDatabase.RowTagAt(lstFilterDatabase.SelectedRowIndex) + + End Function + #tag EndMethod + + #tag Method, Flags = &h1 + Protected Sub Load() + Me.LoadDatabases() + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub LoadDatabases() + lstFilterDatabase.RemoveAllRows + + Try + Var rs As RowSet = Session.DB.SelectSQL("SHOW DATABASES") + If (rs = Nil) Then Return + + If (rs.RowCount > 0) Then + rs.MoveToFirstRow + While (Not rs.AfterLastRow) + lstFilterDatabase.AddRow(rs.Column("databasename").StringValue, rs.Column("databasename").StringValue) + + rs.MoveToNextRow + Wend + End If + + rs.Close + + Catch DatabaseException + + Finally + If (lstFilterDatabase.RowCount > 0) Then lstFilterDatabase.SelectedRowIndex = 0 + + End Try + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub RefreshButtons() + Var bCreateTable, bAlterTable, bCreateIndex, bDrop As Boolean + + Var selectedDatabasename As String = Me.GetSelectedDatabasename() + Var selectedItem As Dictionary = Me.GetSelectedTableRowTag() + + If (selectedDatabasename <> "") Then + bCreateTable = True + bCreateIndex = True + End If + + If (selectedItem <> Nil) And (selectedItem.Lookup("type", "").StringValue = "table") And (selectedItem.Lookup("name", "").StringValue <> "") Then + bAlterTable = True + End If + + If (selectedItem <> Nil) And (selectedItem.Lookup("type", "").StringValue <> "") And (selectedItem.Lookup("name", "").StringValue <> "") Then + bDrop = True + End If + + If (btnCreateTable.Enabled <> bCreateTable) Then btnCreateTable.Enabled = bCreateTable + If (btnCreateIndex.Enabled <> bCreateIndex) Then btnCreateIndex.Enabled = bCreateIndex + If (btnAlterTable.Enabled <> bAlterTable) Then btnAlterTable.Enabled = bAlterTable + If (btnDrop.Enabled <> bDrop) Then btnDrop.Enabled = bDrop + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub RefreshInfos(selectRowTag As Dictionary = nil) + If (selectRowTag = Nil) Then + selectRowTag = Me.GetSelectedTableRowTag() + End If + + edictSelectAfterReload = selectRowTag + + Me.TableLoad() + + 'Select Row async via TableRowDataLoaded + + End Sub + #tag EndMethod + + #tag Method, Flags = &h1 + Protected Sub TableInitColumns() + Super.TableInitColumns() + + Var col As DatasourceColumn + + col = New DatasourceColumn() + col.Width = "15%" + col.DatabaseColumnName = "type" + col.Heading = "Type" + col.FieldType = DatasourceColumn.FieldTypes.Text + col.Sortable = True + col.SortDirection = WebListBox.SortDirections.Descending + Me.Columns.Add(col) + + col = New DatasourceColumn() + col.Width = "20%" + col.DatabaseColumnName = "name" + col.Heading = "Name" + col.FieldType = DatasourceColumn.FieldTypes.Text + col.Sortable = True + col.SortDirection = WebListBox.SortDirections.None + Me.Columns.Add(col) + + col = New DatasourceColumn() + col.Width = "65%" + col.DatabaseColumnName = "sql" + col.Heading = "SQL" + col.FieldType = DatasourceColumn.FieldTypes.Text + col.Sortable = False + col.SortDirection = WebListBox.SortDirections.None + Me.Columns.Add(col) + + + End Sub + #tag EndMethod + + #tag Method, Flags = &h1 + Protected Function TableLoadRowSet() As RowSet + Var filterDatabasename As String = Me.GetSelectedDatabasename() + + + Try + If (filterDatabasename <> "") Then + Session.DB.ExecuteSQL("USE DATABASE '" + filterDatabasename.EscapeSqlQuotes + "'") + Else + Session.DB.ExecuteSQL("CLEAR CURRENT DATABASE") + End If + + Catch err As DatabaseException + + End Try + + If (filterDatabasename <> "") Then + Return Session.DB.SelectSQL("SELECT type, name, sql FROM sqlite_master WHERE (type='table' OR type='index') AND (name NOT LIKE 'sqlite_%') AND (name NOT LIKE 'cubesql_temp_%') ORDER BY type DESC, name") + End If + + Return Nil + + End Function + #tag EndMethod + + #tag Method, Flags = &h1 + Protected Function TableNoRowsMessage() As String + Var sInfo As String = "No Tables & Indexes" + + Var filterDatabasename As String = Me.GetSelectedDatabasename() + If (filterDatabasename <> "") Then + sInfo = sInfo + " for Database " + filterDatabasename + End If + + If (Me.SearchValue <> "") Then + sInfo = sInfo + " matching '" + Me.SearchValue + "'" + End If + + Return sInfo + + End Function + #tag EndMethod + + #tag Method, Flags = &h1 + Protected Sub TableRowDataLoaded() + Super.TableRowDataLoaded() + + If (edictSelectAfterReload = Nil) Then + Me.RefreshButtons() + Return + End If + + Var sSelectAfterReload As Dictionary = edictSelectAfterReload + edictSelectAfterReload = Nil + + Var bFound As Boolean = False + For i As Integer = Me.Table.LastRowIndex DownTo 0 + Var rowTag As Dictionary = Me.Table.RowTagAt(i) + If (rowTag IsA Dictionary) Then + If (rowTag.Lookup("type", "").StringValue = sSelectAfterReload.Lookup("type", "-").StringValue) And _ + (rowTag.Lookup("name", "").StringValue = sSelectAfterReload.Lookup("name", "-").StringValue) Then + + Me.Table.SelectedRowIndex = i + bFound = True + Exit 'Loop + End If + End If + Next + + If (Not bFound) Then Me.Table.SelectedRowIndex = -1 + + Me.RefreshButtons() + + End Sub + #tag EndMethod + + + #tag Property, Flags = &h21 + Private edictActionItem As Dictionary + #tag EndProperty + + #tag Property, Flags = &h21 + Private edictSelectAfterReload As Dictionary + #tag EndProperty + + +#tag EndWindowCode + +#tag Events lstInfos + #tag Event + Sub SelectionChanged(rows() As Integer) + #Pragma unused rows + + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events lstFilterDatabase + #tag Event + Sub SelectionChanged(item As WebMenuItem) + #Pragma unused item + + If (Not ebOpened) Then Return + + Self.TableLoad() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnDrop + #tag Event + Sub Pressed() + Self.ActionDrop() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events dlgDrop + #tag Event + Sub ButtonPressed(button As WebMessageDialogButton) + Self.ActionDropButtonPressed(Me, button) + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnCreateTable + #tag Event + Sub Pressed() + Self.ActionCreateTable() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnCreateIndex + #tag Event + Sub Pressed() + Self.ActionCreateIndex() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnAlterTable + #tag Event + Sub Pressed() + Self.ActionAlterTable() + + End Sub + #tag EndEvent +#tag EndEvents +#tag ViewBehavior + #tag ViewProperty + Name="Area" + Visible=false + Group="Behavior" + InitialValue="Home" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="SearchAvailable" + Visible=false + Group="Behavior" + InitialValue="False" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mPanelIndex" + Visible=false + Group="Behavior" + InitialValue="-1" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="ControlCount" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Name" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Super" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Left" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Top" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="ControlID" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="Enabled" + Visible=true + Group="Behavior" + InitialValue="True" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockBottom" + Visible=true + Group="Behavior" + InitialValue="False" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockHorizontal" + Visible=true + Group="Behavior" + InitialValue="False" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockLeft" + Visible=true + Group="Behavior" + InitialValue="True" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockRight" + Visible=true + Group="Behavior" + InitialValue="False" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockTop" + Visible=true + Group="Behavior" + InitialValue="True" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockVertical" + Visible=true + Group="Behavior" + InitialValue="False" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Visible" + Visible=true + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mDesignHeight" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mDesignWidth" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mName" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="ScrollDirection" + Visible=true + Group="Behavior" + InitialValue="ScrollDirections.None" + Type="WebContainer.ScrollDirections" + EditorType="Enum" + #tag EnumValues + "0 - None" + "1 - Horizontal" + "2 - Vertical" + "3 - Both" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="TabIndex" + Visible=true + Group="Visual Controls" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Indicator" + Visible=false + Group="Visual Controls" + InitialValue="" + Type="WebUIControl.Indicators" + EditorType="Enum" + #tag EnumValues + "0 - Default" + "1 - Primary" + "2 - Secondary" + "3 - Success" + "4 - Danger" + "5 - Warning" + "6 - Info" + "7 - Light" + "8 - Dark" + "9 - Link" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="LayoutType" + Visible=true + Group="View" + InitialValue="LayoutTypes.Fixed" + Type="LayoutTypes" + EditorType="Enum" + #tag EnumValues + "0 - Fixed" + "1 - Flex" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="LayoutDirection" + Visible=true + Group="View" + InitialValue="LayoutDirections.LeftToRight" + Type="LayoutDirections" + EditorType="Enum" + #tag EnumValues + "0 - LeftToRight" + "1 - RightToLeft" + "2 - TopToBottom" + "3 - BottomToTop" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="Title" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="Width" + Visible=false + Group="" + InitialValue="250" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Height" + Visible=false + Group="" + InitialValue="250" + Type="Integer" + EditorType="" + #tag EndViewProperty +#tag EndViewBehavior diff --git a/webapp/dialogs/dlgIndexCreate.xojo_code b/webapp/dialogs/dlgIndexCreate.xojo_code new file mode 100644 index 0000000..7b57335 --- /dev/null +++ b/webapp/dialogs/dlgIndexCreate.xojo_code @@ -0,0 +1,798 @@ +#tag WebPage +Begin dlgBase dlgIndexCreate + Compatibility = "" + ControlCount = 0 + ControlID = "" + Enabled = True + Height = 600 + Index = -2147483648 + Indicator = 0 + LayoutDirection = 0 + LayoutType = 0 + Left = 0 + LockBottom = False + LockHorizontal = False + LockLeft = False + LockRight = False + LockTop = False + LockVertical = False + TabIndex = 0 + Top = 0 + Visible = True + Width = 600 + _mDesignHeight = 0 + _mDesignWidth = 0 + _mPanelIndex = -1 + Begin WebLabel labTitle + Bold = True + ControlID = "" + Enabled = True + FontName = "" + FontSize = 24.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 20 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + Multiline = False + Scope = 2 + TabIndex = 0 + TabStop = True + Text = "Create Index" + TextAlignment = 2 + TextColor = &c000000FF + Tooltip = "" + Top = 20 + Underline = False + Visible = True + Width = 560 + _mPanelIndex = -1 + End + Begin WebRectangle rctFormContent + BackgroundColor = &cFFFFFF + ControlCount = 0 + ControlID = "" + Enabled = True + HasBackgroundColor= False + Height = 457 + Index = -2147483648 + Indicator = 0 + LayoutDirection = 0 + LayoutType = 0 + Left = 20 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + Scope = 2 + TabIndex = 1 + TabStop = True + Tooltip = "" + Top = 66 + Visible = True + Width = 560 + _mDesignHeight = 0 + _mDesignWidth = 0 + _mPanelIndex = -1 + Begin WebLabel labName + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + InitialParent = "rctFormContent" + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 0 + TabPanelIndex = 0 + TabStop = True + Text = "Name:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 86 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + Begin WebTextField edtName + AllowAutoComplete= False + AllowSpellChecking= False + Caption = "" + ControlID = "" + Enabled = True + FieldType = 0 + Height = 38 + Hint = "" + Index = -2147483648 + Indicator = 0 + InitialParent = "rctFormContent" + Left = 188 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + MaximumCharactersAllowed= 0 + PanelIndex = "0" + Parent = "rctFormContent" + ReadOnly = False + Scope = 2 + TabIndex = 1 + TabPanelIndex = 0 + TabStop = True + Text = "" + TextAlignment = 0 + Tooltip = "" + Top = 86 + Visible = True + Width = 372 + _mPanelIndex = -1 + End + Begin WebLabel labTable + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + InitialParent = "rctFormContent" + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 2 + TabPanelIndex = 0 + TabStop = True + Text = "Table:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 132 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + Begin WebPopupMenu lstTable + ControlID = "" + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + InitialParent = "rctFormContent" + InitialValue = "" + LastAddedRowIndex= 0 + LastRowIndex = 0 + Left = 188 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Parent = "rctFormContent" + RowCount = 0 + Scope = 2 + SelectedRowIndex= 0 + SelectedRowText = "" + TabIndex = 3 + TabPanelIndex = 0 + TabStop = True + Tooltip = "" + Top = 132 + Visible = True + Width = 372 + _mPanelIndex = -1 + End + Begin WebListBox lstFields + ColumnCount = 2 + ColumnWidths = "30, *" + ControlID = "" + Enabled = True + HasHeader = False + Height = 325 + HighlightSortedColumn= True + Index = -2147483648 + Indicator = 0 + InitialValue = "" + LastAddedRowIndex= 0 + LastColumnIndex = 0 + LastRowIndex = 0 + Left = 188 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + NoRowsMessage = "No Fields" + Parent = "rctFormContent" + ProcessingMessage= "" + RowCount = 0 + RowSelectionType= 0 + Scope = 0 + SearchCriteria = "" + SelectedRowColor= &c0d6efd + SelectedRowIndex= 0 + TabIndex = 5 + TabPanelIndex = 0 + TabStop = True + Tooltip = "" + Top = 178 + Visible = True + Width = 372 + _mPanelIndex = -1 + End + Begin WebLabel labFields + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 4 + TabPanelIndex = 0 + TabStop = True + Text = "Fields:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 178 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + End + Begin WebButton btnCreate + AllowAutoDisable= False + Cancel = False + Caption = "Create" + ControlID = "" + Default = True + Enabled = False + Height = 38 + Index = -2147483648 + Indicator = 1 + Left = 480 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + Scope = 2 + TabIndex = 3 + TabStop = True + Tooltip = "" + Top = 542 + Visible = True + Width = 100 + _mPanelIndex = -1 + End + Begin WebButton btnCancel + AllowAutoDisable= False + Cancel = True + Caption = "Cancel" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 372 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + Scope = 2 + TabIndex = 2 + TabStop = True + Tooltip = "" + Top = 542 + Visible = True + Width = 100 + _mPanelIndex = -1 + End +End +#tag EndWebPage + +#tag WindowCode + #tag Event + Sub Shown() + edtName.SetFocus() + + End Sub + #tag EndEvent + + + #tag Method, Flags = &h21 + Private Function GetFields() As String() + Var fields() As String + + Var dictRowTag As Dictionary + Var addField As String + Var isChecked As Boolean + For i As Integer = 0 To lstFields.LastRowIndex + Var rowTag As Variant = lstFields.RowTagAt(i) + If (rowTag IsA Dictionary) Then + dictRowTag = Dictionary(rowTag) + addField = dictRowTag.Lookup("name", "") + isChecked = dictRowTag.Lookup("checked", False) + + If (isChecked And (addField <> "")) Then + fields.Add(addField) + End If + End If + Next + + Return fields + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function GetTablename() As String + If (lstTable.SelectedRowIndex >= 0) Then Return lstTable.RowTagAt(lstTable.SelectedRowIndex) + Return "" + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub Load() + Try + Session.DB.ExecuteSQL("USE DATABASE '" + esDatabasename.EscapeSqlQuotes + "'") + + Catch err As DatabaseException + + Finally + + Me.LoadTables() + Me.LoadFields() + + Me.RefreshButtons() + End Try + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub LoadFields() + lstFields.RemoveAllRows + + Var tablename As String = Me.GetTablename() + If (tablename = "") Then Return + + Try + Var rs As RowSet = Session.DB.SelectSQL("PRAGMA table_info('" + tablename.EscapeSqlQuotes + "')") + If (rs <> Nil) Then + If (rs.RowCount > 0) Then + rs.MoveToFirstRow + While (Not rs.AfterLastRow) + lstFields.AddRow("", rs.Column("name").StringValue, rs.Column("name").StringValue) + lstFields.CellTextAt(lstFields.LastAddedRowIndex, 0) = New CheckboxCellRenderer(False) + + Var rowTag As Dictionary = New Dictionary + rowTag.Value("name") = rs.Column("name").StringValue + rowTag.Value("checked") = False + lstFields.RowTagAt(lstFields.LastAddedRowIndex) = rowTag + + rs.MoveToNextRow + Wend + End If + + rs.Close + End If + + Catch err As DatabaseException + + Finally + lstFields.SelectedRowIndex = -1 + + End Try + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub LoadTables() + lstTable.RemoveAllRows + + Try + Var rs As RowSet = Session.DB.SelectSQL("SHOW TABLES") + If (rs <> Nil) Then + If (rs.RowCount > 0) Then + rs.MoveToFirstRow + While (Not rs.AfterLastRow) + lstTable.AddRow(rs.Column("tablename").StringValue, rs.Column("tablename").StringValue) + + rs.MoveToNextRow + Wend + End If + + rs.Close + End If + + Catch err As DatabaseException + + Finally + If (lstTable.LastRowIndex >= 0) Then lstTable.SelectedRowIndex = 0 + + End Try + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub RefreshButtons() + btnCreate.Enabled = (edtName.Text.Trim <> "") And (Me.GetTablename() <> "") And (Me.GetFields().LastIndex >= 0) + + End Sub + #tag EndMethod + + #tag Method, Flags = &h0 + Sub Show(Databasename As String) + esDatabasename = Databasename + + Me.Load() + + Super.Show() + End Sub + #tag EndMethod + + + #tag Hook, Flags = &h0 + Event IndexCreateAction(Name As String, Table As String, Fields() As String) As Boolean + #tag EndHook + + + #tag Property, Flags = &h21 + Private esDatabasename As String + #tag EndProperty + + +#tag EndWindowCode + +#tag Events edtName + #tag Event + Sub TextChanged() + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events lstTable + #tag Event + Sub SelectionChanged(item As WebMenuItem) + #Pragma unused item + + If (Not ebShown) Then Return + + Self.LoadFields() + Self.RefreshButtons() + + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events lstFields + #tag Event + Sub CustomCellAction(row As Integer, column As Integer, identifier As String, value As Variant) + #Pragma unused column + #Pragma unused identifier + + If (Not ebShown) Then Return + + Var rowTag As Dictionary + If (row <= Me.LastRowIndex) Then rowTag = Me.RowTagAt(row) + + If (rowTag = Nil) Then Return + + rowTag.Value("checked") = value.BooleanValue + + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnCreate + #tag Event + Sub Pressed() + If IndexCreateAction(edtName.Text.Trim, Self.GetTablename().Trim, Self.GetFields()) Then + Self.Close() + End If + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnCancel + #tag Event + Sub Pressed() + Self.Close() + + End Sub + #tag EndEvent +#tag EndEvents +#tag ViewBehavior + #tag ViewProperty + Name="ControlCount" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mPanelIndex" + Visible=false + Group="Behavior" + InitialValue="-1" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Index" + Visible=false + Group="ID" + InitialValue="-2147483648" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Name" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Super" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Left" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Top" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="ControlID" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="Enabled" + Visible=true + Group="Behavior" + InitialValue="True" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Height" + Visible=true + Group="Behavior" + InitialValue="400" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LayoutType" + Visible=true + Group="Behavior" + InitialValue="LayoutTypes.Fixed" + Type="LayoutTypes" + EditorType="Enum" + #tag EnumValues + "0 - Fixed" + "1 - Flex" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="LockBottom" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockHorizontal" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockLeft" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockRight" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockTop" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockVertical" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Visible" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Width" + Visible=true + Group="Behavior" + InitialValue="600" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mDesignHeight" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mDesignWidth" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mName" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="TabIndex" + Visible=true + Group="Visual Controls" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Indicator" + Visible=false + Group="Visual Controls" + InitialValue="" + Type="WebUIControl.Indicators" + EditorType="Enum" + #tag EnumValues + "0 - Default" + "1 - Primary" + "2 - Secondary" + "3 - Success" + "4 - Danger" + "5 - Warning" + "6 - Info" + "7 - Light" + "8 - Dark" + "9 - Link" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="LayoutDirection" + Visible=true + Group="WebView" + InitialValue="LayoutDirections.LeftToRight" + Type="LayoutDirections" + EditorType="Enum" + #tag EnumValues + "0 - LeftToRight" + "1 - RightToLeft" + "2 - TopToBottom" + "3 - BottomToTop" + #tag EndEnumValues + #tag EndViewProperty +#tag EndViewBehavior diff --git a/webapp/dialogs/dlgTableEditor.xojo_code b/webapp/dialogs/dlgTableEditor.xojo_code new file mode 100644 index 0000000..df717d5 --- /dev/null +++ b/webapp/dialogs/dlgTableEditor.xojo_code @@ -0,0 +1,1293 @@ +#tag WebPage +Begin dlgBase dlgTableEditor + Compatibility = "" + ControlCount = 0 + ControlID = "" + Enabled = True + Height = 700 + Index = -2147483648 + Indicator = 0 + LayoutDirection = 0 + LayoutType = 0 + Left = 0 + LockBottom = False + LockHorizontal = False + LockLeft = False + LockRight = False + LockTop = False + LockVertical = False + TabIndex = 0 + Top = 0 + Visible = True + Width = 800 + _mDesignHeight = 0 + _mDesignWidth = 0 + _mPanelIndex = -1 + Begin WebLabel labTitle + Bold = True + ControlID = "" + Enabled = True + FontName = "" + FontSize = 24.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 20 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + Multiline = False + Scope = 2 + TabIndex = 0 + TabStop = True + Text = "Table Editor" + TextAlignment = 2 + TextColor = &c000000FF + Tooltip = "" + Top = 20 + Underline = False + Visible = True + Width = 760 + _mPanelIndex = -1 + End + Begin WebRectangle rctFormContent + BackgroundColor = &cFFFFFF + ControlCount = 0 + ControlID = "" + Enabled = True + HasBackgroundColor= False + Height = 557 + Index = -2147483648 + Indicator = 0 + LayoutDirection = 0 + LayoutType = 0 + Left = 20 + LockBottom = True + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + Scope = 2 + TabIndex = 1 + TabStop = True + Tooltip = "" + Top = 66 + Visible = True + Width = 760 + _mDesignHeight = 0 + _mDesignWidth = 0 + _mPanelIndex = -1 + Begin WebLabel labTablename + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + InitialParent = "rctFormContent" + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 0 + TabPanelIndex = 0 + TabStop = True + Text = "Table Name:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 86 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + Begin WebTextField edtTablename + AllowAutoComplete= False + AllowSpellChecking= False + Caption = "" + ControlID = "" + Enabled = True + FieldType = 0 + Height = 38 + Hint = "" + Index = -2147483648 + Indicator = 0 + InitialParent = "rctFormContent" + Left = 188 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + MaximumCharactersAllowed= 0 + PanelIndex = "0" + Parent = "rctFormContent" + ReadOnly = False + Scope = 2 + TabIndex = 1 + TabPanelIndex = 0 + TabStop = True + Text = "" + TextAlignment = 0 + Tooltip = "" + Top = 86 + Visible = True + Width = 572 + _mPanelIndex = -1 + End + Begin WebListBox lstFields + ColumnCount = 5 + ColumnWidths = "40, *, 20%, 20%, 25%" + ControlID = "" + Enabled = True + HasHeader = True + Height = 418 + HighlightSortedColumn= False + Index = -2147483648 + Indicator = 0 + InitialValue = "" + LastAddedRowIndex= 0 + LastColumnIndex = 0 + LastRowIndex = 0 + Left = 40 + LockBottom = False + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + NoRowsMessage = "No Fields" + Parent = "rctFormContent" + ProcessingMessage= "" + RowCount = 0 + RowSelectionType= 1 + Scope = 0 + SearchCriteria = "" + SelectedRowColor= &c0d6efd + SelectedRowIndex= 0 + TabIndex = 5 + TabPanelIndex = 0 + TabStop = True + Tooltip = "" + Top = 132 + Visible = True + Width = 720 + _mPanelIndex = -1 + End + Begin WebButton btnFieldAdd + AllowAutoDisable= False + Cancel = False + Caption = "Add" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 660 + LockBottom = True + LockedInPosition= False + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 11 + TabPanelIndex = 0 + TabStop = True + Tooltip = "" + Top = 565 + Visible = True + Width = 100 + _mPanelIndex = -1 + End + Begin WebLabel labField + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 12 + TabPanelIndex = 0 + TabStop = True + Text = "Field:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 565 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + Begin WebButton btnFieldEdit + AllowAutoDisable= False + Cancel = False + Caption = "Edit" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 552 + LockBottom = True + LockedInPosition= False + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 13 + TabPanelIndex = 0 + TabStop = True + Tooltip = "" + Top = 565 + Visible = True + Width = 100 + _mPanelIndex = -1 + End + Begin WebButton btnFieldDelete + AllowAutoDisable= False + Cancel = False + Caption = "Delete" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 444 + LockBottom = True + LockedInPosition= False + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 14 + TabPanelIndex = 0 + TabStop = True + Tooltip = "" + Top = 565 + Visible = True + Width = 100 + _mPanelIndex = -1 + End + End + Begin WebButton btnSave + AllowAutoDisable= False + Cancel = False + Caption = "Create" + ControlID = "" + Default = True + Enabled = False + Height = 38 + Index = -2147483648 + Indicator = 1 + Left = 680 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + Scope = 2 + TabIndex = 3 + TabStop = True + Tooltip = "" + Top = 642 + Visible = True + Width = 100 + _mPanelIndex = -1 + End + Begin WebButton btnCancel + AllowAutoDisable= False + Cancel = True + Caption = "Cancel" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 572 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + Scope = 2 + TabIndex = 2 + TabStop = True + Tooltip = "" + Top = 642 + Visible = True + Width = 100 + _mPanelIndex = -1 + End +End +#tag EndWebPage + +#tag WindowCode + #tag Event + Sub Shown() + If ebIsCreate Then + edtTablename.SetFocus() + End If + + End Sub + #tag EndEvent + + + #tag Method, Flags = &h21 + Private Sub ActionFieldAdd() + Var dlgField As New dlgTableEditorField + AddHandler dlgField.FieldSaveAction, WeakAddressOf ActionFieldAddButtonPressed + dlgField.ShowAsAdd() + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function ActionFieldAddButtonPressed(obj As dlgTableEditorField, Name As String, Type As String, Default As String, Constraint As String) As Boolean + #Pragma unused obj + + If (Name = "") Then Return False + + Var dictField As New Dictionary + dictField.Value("isNew") = True + dictField.Value("fieldname") = Name + dictField.Value("fieldtype") = Type + dictField.Value("defaultvalue") = Default + dictField.Value("constraint") = Constraint + + Var sanityMessage As String = Me.SanityCheckField(dictField) + If (sanityMessage <> "") Then + ShowWarningDialog("Add Field", "Can't add field.", sanityMessage) + Return False + End If + + Me.AddField(dictField) + + Self.RefreshButtons() + Return True + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub ActionFieldDelete() + Var selectedField As Dictionary = Me.GetSelectedField() + If (selectedField = Nil) Then Return + + If (selectedField.Lookup("isNew", True).BooleanValue = False) Then + If (Not ebDropColumnSupported) Then Return + If selectedField.Lookup("constraint", "").StringValue.Contains("PRIMARY", ComparisonOptions.CaseInsensitive) Or _ + selectedField.Lookup("constraint", "").StringValue.Contains("UNIQUE", ComparisonOptions.CaseInsensitive) Or _ + selectedField.Lookup("isIndexed", False).BooleanValue Then + Return + End If + + 'Drop existing Column + If (lstFields.SelectedRowIndex >= 0) And (selectedField = lstFields.RowTagAt(lstFields.SelectedRowIndex)) Then + selectedField.Value("isDropped") = (Not selectedField.Lookup("isDropped", False).BooleanValue) + lstFields.CellTextAt(lstFields.SelectedRowIndex, 0) = Me.GetFieldIcon(selectedField) + lstFields.RowTagAt(lstFields.SelectedRowIndex) = selectedField + End If + + Self.RefreshButtons() + Return + End If + + 'Remove new added Field + If (lstFields.SelectedRowIndex >= 0) Then + Var rowTag As Variant = lstFields.RowTagAt(lstFields.SelectedRowIndex) + If (rowTag IsA Dictionary) Then + If (Dictionary(rowTag).Lookup("isNew", False).BooleanValue = True) Then + lstFields.RemoveRowAt(lstFields.SelectedRowIndex) + End If + End If + End If + + Self.RefreshButtons() + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub ActionFieldEdit() + Var selectedField As Dictionary = Me.GetSelectedField() + If (selectedField = Nil) Then Return + + If (selectedField.Lookup("isNew", True).BooleanValue = False) Then + If (Not ebRenameColumnSupported) Then Return + End If + + Var dlgField As New dlgTableEditorField + AddHandler dlgField.FieldSaveAction, WeakAddressOf ActionFieldEditButtonPressed + + If (selectedField.Lookup("isNew", True).BooleanValue = True) Then + dlgField.ShowAsEdit(selectedField.Lookup("fieldname", ""), selectedField.Lookup("fieldtype", ""), selectedField.Lookup("defaultvalue", ""), selectedField.Lookup("constraint", "")) + Else + dlgField.ShowAsRename(selectedField.Lookup("fieldname", ""), selectedField.Lookup("fieldtype", ""), selectedField.Lookup("defaultvalue", ""), selectedField.Lookup("constraint", "")) + End If + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function ActionFieldEditButtonPressed(obj As dlgTableEditorField, Name As String, Type As String, Default As String, Constraint As String) As Boolean + #Pragma unused obj + + If (Name = "") Then Return False + + Var selectedField As Dictionary = Me.GetSelectedField() + If (selectedField = Nil) Then Return False + + Var modifiedField As New Dictionary + For Each vKey As Variant In selectedField.Keys + modifiedField.Value(vKey) = selectedField.Value(vKey) + Next + + modifiedField.Value("fieldname") = Name + modifiedField.Value("fieldtype") = Type + modifiedField.Value("defaultvalue") = Default + modifiedField.Value("constraint") = Constraint + + If (modifiedField.Lookup("isNew", False).BooleanValue = False) Then + Var bIsRenamed As Boolean = (modifiedField.Lookup("fieldname_loaded", "").StringValue.Compare(Name, ComparisonOptions.CaseInsensitive) <> 0) + modifiedField.Value("isRenamed") = bIsRenamed + End If + + Var sanityMessage As String = Me.SanityCheckField(modifiedField) + If (sanityMessage <> "") Then + ShowWarningDialog("Edit Field", "Can't edit field.", sanityMessage) + Return False + End If + + lstFields.CellTextAt(lstFields.SelectedRowIndex, 0) = Me.GetFieldIcon(modifiedField) + lstFields.CellTextAt(lstFields.SelectedRowIndex, 1) = modifiedField.Lookup("fieldname", "").StringValue + lstFields.CellTextAt(lstFields.SelectedRowIndex, 2) = modifiedField.Lookup("fieldtype", "").StringValue + lstFields.CellTextAt(lstFields.SelectedRowIndex, 3) = modifiedField.Lookup("defaultvalue", "").StringValue + lstFields.CellTextAt(lstFields.SelectedRowIndex, 4) = modifiedField.Lookup("constraint", "").StringValue + lstFields.RowTagAt(lstFields.SelectedRowIndex) = modifiedField + + Self.RefreshButtons() + Return True + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub AddField(dictField As Dictionary) + If (dictField = Nil) Then Return + + lstFields.AddRow("") + lstFields.CellTextAt(lstFields.LastAddedRowIndex, 0) = Me.GetFieldIcon(dictField) + lstFields.CellTextAt(lstFields.LastAddedRowIndex, 1) = dictField.Lookup("fieldname", "").StringValue + lstFields.CellTextAt(lstFields.LastAddedRowIndex, 2) = dictField.Lookup("fieldtype", "").StringValue + lstFields.CellTextAt(lstFields.LastAddedRowIndex, 3) = dictField.Lookup("defaultvalue", "").StringValue + lstFields.CellTextAt(lstFields.LastAddedRowIndex, 4) = dictField.Lookup("constraint", "").StringValue + lstFields.RowTagAt(lstFields.LastAddedRowIndex) = dictField + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function GetFieldIcon(field As Dictionary) As WebListboxImageRenderer + Var icon As WebPicture + + If (field.Lookup("isNew", False).BooleanValue = True) Then + icon = WebPicture.BootstrapIcon("plus-circle-fill", Color.Green) + Else + icon = WebPicture.BootstrapIcon("circle-fill", Color.Green) + If (field.Lookup("isRenamed", False).BooleanValue = True) Then + icon = WebPicture.BootstrapIcon("c-circle-fill", Color.Orange) + End If + If (field.Lookup("isDropped", False).BooleanValue = True) Then + icon = WebPicture.BootstrapIcon("x-circle-fill", Color.Red) + End If + End If + + Return New WebListboxImageRenderer(icon.URL, True) + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function GetFields() As Dictionary() + Var fields() As Dictionary + + For i As Integer = 0 To lstFields.LastRowIndex + + Var rowTag As Variant = lstFields.RowTagAt(i) + If (rowTag IsA Dictionary) Then + fields.Add(Dictionary(rowTag)) + End If + Next + + Return fields + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function GetSelectedField() As Dictionary + If (lstFields.SelectedRowIndex >= 0) Then + Var rowTag As Variant = lstFields.RowTagAt(lstFields.SelectedRowIndex) + If (rowTag IsA Dictionary) Then + Return Dictionary(rowTag) + End If + End If + + Return Nil + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub LoadTableForAlter(Tablename As String) + lstFields.RemoveAllRows() + + Try + Var rs As RowSet + + Var uniqueColumns() As String + Try + If (Session.DBEngineVersion >= Version_AsDouble("3.16.0")) Then + rs = Session.DB.SelectSQL("SELECT DISTINCT ii.name AS unique_column_name FROM sqlite_master AS m, pragma_index_list(m.name) AS il, pragma_index_info(il.name) AS ii WHERE m.type = 'table' AND m.name = '" + Tablename.EscapeSqlQuotes + "' AND il.[unique] = 1") + If (rs <> Nil) And (rs.RowCount > 0) Then + + rs.MoveToFirstRow + While (Not rs.AfterLastRow) + uniqueColumns.Add(rs.Column("unique_column_name").StringValue) + rs.MoveToNextRow + Wend + End If + End If + Catch err As DatabaseException + 'ignore + End Try + + Var indexedColumns() As String + Try + If (Session.DBEngineVersion >= Version_AsDouble("3.16.0")) Then + rs = Session.DB.SelectSQL("SELECT DISTINCT ii.name AS indexed_column_name FROM sqlite_master AS m, pragma_index_list(m.name) AS il, pragma_index_info(il.name) AS ii WHERE m.type = 'table' AND m.name = '" + Tablename.EscapeSqlQuotes + "'") + If (rs <> Nil) And (rs.RowCount > 0) Then + + rs.MoveToFirstRow + While (Not rs.AfterLastRow) + indexedColumns.Add(rs.Column("indexed_column_name").StringValue) + rs.MoveToNextRow + Wend + End If + End If + Catch err As DatabaseException + 'ignore + End Try + + + rs = Session.DB.SelectSQL("PRAGMA TABLE_INFO(" + Tablename.EscapeSqlFieldIfRequired + ")") + If (rs = Nil) Then Return + + If (rs.RowCount > 0) Then + rs.MoveToFirstRow + While (Not rs.AfterLastRow) + Var defaultValue As String = rs.Column("dflt_value").StringValue + If (defaultValue.Length >= 2) And (defaultValue.Left(1) = "'") And (defaultValue.Right(1) = "'") Then + defaultValue = defaultValue.Middle(1, defaultValue.Length-2) + End If + + Var dictField As New Dictionary + dictField.Value("isNew") = False + dictField.Value("fieldname") = rs.Column("name").StringValue + dictField.Value("fieldname_loaded") = rs.Column("name").StringValue + dictField.Value("fieldtype") = rs.Column("type").StringValue + dictField.Value("defaultvalue") = defaultValue + + If (rs.Column("pk").StringValue = "1") Then + dictField.Value("constraint") = "PRIMARY KEY" + ElseIf (rs.Column("notnull").StringValue = "1") Then + dictField.Value("constraint") = "NOT NULL" + ElseIf (uniqueColumns.IndexOf(rs.Column("name").StringValue) >= 0) Then + dictField.Value("constraint") = "UNIQUE" + End If + + If (indexedColumns.IndexOf(rs.Column("name").StringValue) >= 0) Then + dictField.Value("isIndexed") = True + Else + dictField.Value("isIndexed") = False + End If + + Me.AddField(dictField) + + rs.MoveToNextRow + Wend + End If + + rs.Close + + Catch DatabaseException + + End Try + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub RefreshButtons() + Var bHasRenamedTablename As Boolean + Var bHasNewFields As Boolean + Var bHasRenamedFields As Boolean + Var bHasDroppedFields As Boolean + + If ebIsAlter And ebRenameTablenameSupported And (esLoadedTablename <> edtTablename.Text.Trim) Then + bHasRenamedTablename = True + End If + + Var fields() As Dictionary = Me.GetFields() + For Each field As Dictionary In fields + If (field.Lookup("isNew", False).BooleanValue = True) Then bHasNewFields = True + If ebIsAlter And (field.Lookup("isNew", True).BooleanValue = False) Then + If (field.Lookup("isDropped", False) = True) Then + bHasDroppedFields = True + ElseIf (field.Lookup("isRenamed", False) = True) Then + bHasRenamedFields = True + End If + End If + Next + + Var selectedField As Dictionary = Me.GetSelectedField() + + Var bAdd As Boolean = True + If (btnFieldAdd.Enabled <> bAdd) Then btnFieldAdd.Enabled = bAdd + + Var bEdit As Boolean = (selectedField <> Nil) + If (bEdit = True) Then + If (selectedField.Lookup("isNew", True).BooleanValue = True) Then + If (btnFieldEdit.Indicator <> Indicators.Default) Then btnFieldEdit.Indicator = Indicators.Default + If (btnFieldEdit.Caption <> "Edit") Then btnFieldEdit.Caption = "Edit" + bEdit = True + Else + If (btnFieldEdit.Indicator <> Indicators.Warning) Then btnFieldEdit.Indicator = Indicators.Warning + If (btnFieldEdit.Caption <> "Rename") Then btnFieldEdit.Caption = "Rename" + bEdit = ebRenameColumnSupported + End If + End If + If (btnFieldEdit.Enabled <> bEdit) Then btnFieldEdit.Enabled = bEdit + If (btnFieldEdit.Visible <> bEdit) Then btnFieldEdit.Visible = bEdit + + Var bDelete As Boolean = (selectedField <> Nil) + If (bDelete = True) Then + If (selectedField.Lookup("isNew", False).BooleanValue = True) Then + If (btnFieldDelete.Indicator <> Indicators.Default) Then btnFieldDelete.Indicator = Indicators.Default + If (btnFieldDelete.Caption <> "Delete") Then btnFieldDelete.Caption = "Delete" + bDelete = True + Else + Var dropCaption As String = If(selectedField.Lookup("isDropped", False).BooleanValue = True, "UnDrop", "Drop") + If (btnFieldDelete.Caption <> dropCaption) Then btnFieldDelete.Caption = dropCaption + If (btnFieldDelete.Indicator <> Indicators.Danger) Then btnFieldDelete.Indicator = Indicators.Danger + bDelete = ebDropColumnSupported And _ + (Not selectedField.Lookup("constraint", "").StringValue.Contains("PRIMARY", ComparisonOptions.CaseInsensitive)) And _ + (Not selectedField.Lookup("constraint", "").StringValue.Contains("UNIQUE", ComparisonOptions.CaseInsensitive)) And _ + (Not selectedField.Lookup("isIndexed", False).BooleanValue) + End If + End If + If (btnFieldDelete.Enabled <> bDelete) Then btnFieldDelete.Enabled = bDelete + If (btnFieldDelete.Visible <> bDelete) Then btnFieldDelete.Visible = bDelete + + Var bSave As Boolean = (edtTablename.Text.Trim <> "") And (bHasNewFields Or bHasDroppedFields Or bHasRenamedFields Or bHasRenamedTablename) + If (btnSave.Enabled <> bSave) Then btnSave.Enabled = bSave + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function SanityCheckField(field As Dictionary) As String + If (field = Nil) Then Return "" + + If ebIsAlter And (field.Lookup("isNew", False).BooleanValue = True) Then + 'new Fields in ALTER TABLE + Var defaultValue As String = field.Lookup("defaultvalue", "").StringValue + Select Case defaultValue + Case "CURRENT_TIME", "CURRENT_DATE", "CURRENT_TIMESTAMP" + Return "The column may not have a default value of CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP in an ALTER TABLE command." + End Select + + Var constraint As String = field.Lookup("constraint", "").StringValue + If (constraint.Contains("PRIMARY KEY") Or constraint.Contains("UNIQUE")) Then + Return "The column may not have a PRIMARY KEY or UNIQUE constraint in an ALTER TABLE command." + End If + End If + + Return "" + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function SaveAsSQL() As String() + If ebIsCreate Then + Return Me.SaveAsSQLCreate() + End If + + If ebIsAlter Then + Return Me.SaveAsSQLAlter() + End If + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function SaveAsSQLAlter() As String() + Var sqlStatements() As String + + If (esLoadedTablename <> edtTablename.Text.Trim) Then + If ebRenameTablenameSupported Then + 'Rename Table + Var sqlRename As String = "ALTER TABLE " + esLoadedTablename.EscapeSqlFieldIfRequired + _ + " RENAME TO " + edtTablename.Text.Trim.EscapeSqlFieldIfRequired + sqlStatements.Add(sqlRename) + + Else + 'Oops, should not have happened...make sure altering the loaded tablename + edtTablename.Text = esLoadedTablename + End If + End If + + Var fields() As Dictionary = Me.GetFields() + + Var field As Dictionary + For i As Integer = 0 To fields.LastIndex + field = fields(i) + If (field.Lookup("isNew", False).BooleanValue <> True) Then + If (field.Lookup("isDropped", False) = True) And ebDropColumnSupported Then + 'Drop Column + Var sqlDrop As String = "ALTER TABLE " + edtTablename.Text.Trim.EscapeSqlFieldIfRequired + _ + " DROP COLUMN " + field.Lookup("fieldname_loaded", "").StringValue.EscapeSqlFieldIfRequired + sqlStatements.Add(sqlDrop) + + Continue + End If + + If (field.Lookup("isRenamed", False) = True) And ebRenameColumnSupported Then + 'Rename Column + Var sqlRename As String = "ALTER TABLE " + edtTablename.Text.Trim.EscapeSqlFieldIfRequired + _ + " RENAME COLUMN " + field.Lookup("fieldname_loaded", "").StringValue.EscapeSqlFieldIfRequired + _ + " TO " + field.Lookup("fieldname", "").StringValue.EscapeSqlFieldIfRequired + sqlStatements.Add(sqlRename) + + Continue + End If + + Continue + End If + + 'Add Column + Var sqlField As String = field.Lookup("fieldname", "").StringValue.EscapeSqlFieldIfRequired + _ + If(field.Lookup("fieldtype", "").StringValue <> "", " " + field.Lookup("fieldtype", "").StringValue, "") + + Select Case field.Lookup("constraint", "").StringValue + Case "UNIQUE (multi)" + 'not allowed in ALTER TABLE + Case "UNIQUE (single)" + 'not allowed in ALTER TABLE + Else + sqlField = sqlField + " " + field.Lookup("constraint", "").StringValue + End Select + + If (field.Lookup("defaultvalue", "").StringValue <> "") Then + sqlField = sqlField + " DEFAULT " + field.Lookup("defaultvalue", "").StringValue.EscapeSqlDefaultValueIfRequired + End If + + Var sql As String = "ALTER TABLE " + edtTablename.Text.Trim.EscapeSqlFieldIfRequired + _ + " ADD COLUMN " + sqlField + + sqlStatements.Add(sql) + Next + + Return sqlStatements + + End Function + #tag EndMethod + + #tag Method, Flags = &h21 + Private Function SaveAsSQLCreate() As String() + Var fields() As Dictionary = Me.GetFields() + + Var field As Dictionary + Var sqlFields() As String + Var multiUniqueFields() As String + For i As Integer = 0 To fields.LastIndex + field = fields(i) + If (field.Lookup("isNew", False).BooleanValue <> True) Then Continue + + Var sqlField As String = field.Lookup("fieldname", "").StringValue.EscapeSqlFieldIfRequired + _ + If(field.Lookup("fieldtype", "").StringValue <> "", " " + field.Lookup("fieldtype", "").StringValue, "") + + Select Case field.Lookup("constraint", "").StringValue + Case "UNIQUE (multi)" + 'add later at table level + multiUniqueFields.Add(field.Lookup("fieldname", "").StringValue.EscapeSqlFieldIfRequired) + Case "UNIQUE (single)" + sqlField = sqlField + " UNIQUE" + Else + sqlField = sqlField + " " + field.Lookup("constraint", "").StringValue + End Select + + If (field.Lookup("defaultvalue", "").StringValue <> "") Then + sqlField = sqlField + " DEFAULT " + field.Lookup("defaultvalue", "").StringValue.EscapeSqlDefaultValueIfRequired + End If + + sqlFields.Add(sqlField) + Next + + Var sqlUniqueMulti As String + If (multiUniqueFields.LastIndex >= 0) Then + sqlUniqueMulti = ", UNIQUE (" + String.FromArray(multiUniqueFields, ", ") + ")" + End If + + Var sql As String = "CREATE TABLE " + edtTablename.Text.Trim.EscapeSqlFieldIfRequired + " (" + _ + String.FromArray(sqlFields, ", ") + _ + sqlUniqueMulti + _ + ")" + + Return Array(sql) + + End Function + #tag EndMethod + + #tag Method, Flags = &h0 + Sub ShowAsAlter(Tablename As String) + btnSave.Caption = "Alter" + edtTablename.Text = Tablename + ebIsCreate = False + ebIsAlter = True + esLoadedTablename = Tablename + + Me.Show_InitSupportedCommands() + Me.LoadTableForAlter(Tablename) + edtTablename.Enabled = ebRenameTablenameSupported + + Me.RefreshButtons() + + Super.Show() + End Sub + #tag EndMethod + + #tag Method, Flags = &h0 + Sub ShowAsCreate() + btnSave.Caption = "Create" + ebIsCreate = True + ebIsAlter = False + esLoadedTablename = "" + + Me.Show_InitSupportedCommands() + Me.RefreshButtons() + + Super.Show() + + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub Show_InitSupportedCommands() + ebRenameColumnSupported = (Session.DBEngineVersion >= Version_AsDouble("3.25.0")) + ebDropColumnSupported = (Session.DBEngineVersion >= Version_AsDouble("3.35.0")) + + 'The behavior of ALTER TABLE when renaming a table was enhanced in versions 3.25.0 (2018-09-15) and 3.26.0 (2018-12-01) in order to carry the rename operation forward into triggers and views that reference the renamed table. + ebRenameTablenameSupported = (Session.DBEngineVersion >= Version_AsDouble("3.26.0")) + End Sub + #tag EndMethod + + + #tag Hook, Flags = &h0 + Event TableEditorSaveAction(Name As String, SQLStatements() As String) As Boolean + #tag EndHook + + + #tag Property, Flags = &h21 + Private ebDropColumnSupported As Boolean + #tag EndProperty + + #tag Property, Flags = &h21 + Private ebIsAlter As Boolean + #tag EndProperty + + #tag Property, Flags = &h21 + Private ebIsCreate As Boolean + #tag EndProperty + + #tag Property, Flags = &h21 + Private ebRenameColumnSupported As Boolean + #tag EndProperty + + #tag Property, Flags = &h21 + Private ebRenameTablenameSupported As Boolean + #tag EndProperty + + #tag Property, Flags = &h21 + Private esLoadedTablename As String + #tag EndProperty + + +#tag EndWindowCode + +#tag Events edtTablename + #tag Event + Sub TextChanged() + If ebIsAlter Then + If (Me.Text.Trim <> esLoadedTablename) Then + labTablename.TextColor = Color.Orange + Else + labTablename.TextColor = nil + End If + End If + + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events lstFields + #tag Event + Sub Opening() + Me.HeaderAt(0) = " " + Me.HeaderAt(1) = "Fieldname" + Me.HeaderAt(2) = "Type" + Me.HeaderAt(3) = "Default" + Me.HeaderAt(4) = "Constraint" + + Me.ColumnSortTypeAt(0) = WebListBox.SortTypes.Unsortable + Me.ColumnSortTypeAt(1) = WebListBox.SortTypes.Unsortable + Me.ColumnSortTypeAt(2) = WebListBox.SortTypes.Unsortable + Me.ColumnSortTypeAt(3) = WebListBox.SortTypes.Unsortable + Me.ColumnSortTypeAt(4) = WebListBox.SortTypes.Unsortable + + End Sub + #tag EndEvent + #tag Event + Sub SelectionChanged(rows() As Integer) + #Pragma unused rows + + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnFieldAdd + #tag Event + Sub Pressed() + Self.ActionFieldAdd() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnFieldEdit + #tag Event + Sub Pressed() + Self.ActionFieldEdit() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnFieldDelete + #tag Event + Sub Pressed() + Self.ActionFieldDelete() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnSave + #tag Event + Sub Pressed() + If TableEditorSaveAction(edtTablename.Text.Trim, Self.SaveAsSQL()) Then + Self.Close() + End If + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnCancel + #tag Event + Sub Pressed() + Self.Close() + + End Sub + #tag EndEvent +#tag EndEvents +#tag ViewBehavior + #tag ViewProperty + Name="ControlCount" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mPanelIndex" + Visible=false + Group="Behavior" + InitialValue="-1" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Index" + Visible=false + Group="ID" + InitialValue="-2147483648" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Name" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Super" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Left" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Top" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="ControlID" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="Enabled" + Visible=true + Group="Behavior" + InitialValue="True" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Height" + Visible=true + Group="Behavior" + InitialValue="400" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LayoutType" + Visible=true + Group="Behavior" + InitialValue="LayoutTypes.Fixed" + Type="LayoutTypes" + EditorType="Enum" + #tag EnumValues + "0 - Fixed" + "1 - Flex" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="LockBottom" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockHorizontal" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockLeft" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockRight" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockTop" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockVertical" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Visible" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Width" + Visible=true + Group="Behavior" + InitialValue="600" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mDesignHeight" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mDesignWidth" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mName" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="TabIndex" + Visible=true + Group="Visual Controls" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Indicator" + Visible=false + Group="Visual Controls" + InitialValue="" + Type="WebUIControl.Indicators" + EditorType="Enum" + #tag EnumValues + "0 - Default" + "1 - Primary" + "2 - Secondary" + "3 - Success" + "4 - Danger" + "5 - Warning" + "6 - Info" + "7 - Light" + "8 - Dark" + "9 - Link" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="LayoutDirection" + Visible=true + Group="WebView" + InitialValue="LayoutDirections.LeftToRight" + Type="LayoutDirections" + EditorType="Enum" + #tag EnumValues + "0 - LeftToRight" + "1 - RightToLeft" + "2 - TopToBottom" + "3 - BottomToTop" + #tag EndEnumValues + #tag EndViewProperty +#tag EndViewBehavior diff --git a/webapp/dialogs/dlgTableEditorField.xojo_code b/webapp/dialogs/dlgTableEditorField.xojo_code new file mode 100644 index 0000000..8b48bc2 --- /dev/null +++ b/webapp/dialogs/dlgTableEditorField.xojo_code @@ -0,0 +1,840 @@ +#tag WebPage +Begin dlgBase dlgTableEditorField + Compatibility = "" + ControlCount = 0 + ControlID = "" + Enabled = True + Height = 362 + Index = -2147483648 + Indicator = 0 + LayoutDirection = 0 + LayoutType = 0 + Left = 0 + LockBottom = False + LockHorizontal = False + LockLeft = False + LockRight = False + LockTop = False + LockVertical = False + TabIndex = 0 + Top = 0 + Visible = True + Width = 600 + _mDesignHeight = 0 + _mDesignWidth = 0 + _mPanelIndex = -1 + Begin WebLabel labTitle + Bold = True + ControlID = "" + Enabled = True + FontName = "" + FontSize = 24.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 20 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + Multiline = False + Scope = 2 + TabIndex = 0 + TabStop = True + Text = "Field" + TextAlignment = 2 + TextColor = &c000000FF + Tooltip = "" + Top = 20 + Underline = False + Visible = True + Width = 560 + _mPanelIndex = -1 + End + Begin WebRectangle rctFormContent + BackgroundColor = &cFFFFFF + ControlCount = 0 + ControlID = "" + Enabled = True + HasBackgroundColor= False + Height = 219 + Index = -2147483648 + Indicator = 0 + LayoutDirection = 0 + LayoutType = 0 + Left = 20 + LockBottom = True + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + Scope = 2 + TabIndex = 1 + TabStop = True + Tooltip = "" + Top = 66 + Visible = True + Width = 560 + _mDesignHeight = 0 + _mDesignWidth = 0 + _mPanelIndex = -1 + Begin WebLabel labName + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + InitialParent = "rctFormContent" + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 0 + TabPanelIndex = 0 + TabStop = True + Text = "Name:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 86 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + Begin WebTextField edtName + AllowAutoComplete= False + AllowSpellChecking= False + Caption = "" + ControlID = "" + Enabled = True + FieldType = 0 + Height = 38 + Hint = "" + Index = -2147483648 + Indicator = 0 + InitialParent = "rctFormContent" + Left = 188 + LockBottom = False + LockedInPosition= True + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + MaximumCharactersAllowed= 0 + PanelIndex = "0" + Parent = "rctFormContent" + ReadOnly = False + Scope = 2 + TabIndex = 1 + TabPanelIndex = 0 + TabStop = True + Text = "" + TextAlignment = 0 + Tooltip = "" + Top = 86 + Visible = True + Width = 372 + _mPanelIndex = -1 + End + Begin WebPopupMenu lstType + ControlID = "" + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + InitialValue = "" + LastAddedRowIndex= 0 + LastRowIndex = 0 + Left = 188 + LockBottom = False + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + PanelIndex = "0" + Parent = "rctFormContent" + RowCount = 0 + Scope = 2 + SelectedRowIndex= -1 + SelectedRowText = "" + TabIndex = 2 + TabPanelIndex = 0 + TabStop = True + Tooltip = "" + Top = 132 + Visible = True + Width = 372 + _mPanelIndex = -1 + End + Begin WebLabel labType + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 4 + TabPanelIndex = 0 + TabStop = True + Text = "Type:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 132 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + Begin WebLabel labDefault + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 5 + TabPanelIndex = 0 + TabStop = True + Text = "Default Value:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 178 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + Begin WebTextField edtDefault + AllowAutoComplete= False + AllowSpellChecking= False + Caption = "" + ControlID = "" + Enabled = True + FieldType = 0 + Height = 38 + Hint = "" + Index = -2147483648 + Indicator = 0 + Left = 188 + LockBottom = False + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = True + LockTop = True + LockVertical = False + MaximumCharactersAllowed= 0 + PanelIndex = "0" + Parent = "rctFormContent" + ReadOnly = False + Scope = 2 + TabIndex = 6 + TabPanelIndex = 0 + TabStop = True + Text = "" + TextAlignment = 0 + Tooltip = "" + Top = 178 + Visible = True + Width = 372 + _mPanelIndex = -1 + End + Begin WebPopupMenu lstConstraint + ControlID = "" + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + InitialValue = "" + LastAddedRowIndex= 0 + LastRowIndex = 0 + Left = 188 + LockBottom = False + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + PanelIndex = "0" + Parent = "rctFormContent" + RowCount = 0 + Scope = 2 + SelectedRowIndex= -1 + SelectedRowText = "" + TabIndex = 7 + TabPanelIndex = 0 + TabStop = True + Tooltip = "" + Top = 224 + Visible = True + Width = 372 + _mPanelIndex = -1 + End + Begin WebLabel labConstraint + Bold = False + ControlID = "" + Enabled = True + FontName = "" + FontSize = 0.0 + Height = 38 + Index = -2147483648 + Indicator = 0 + Italic = False + Left = 40 + LockBottom = False + LockedInPosition= False + LockHorizontal = False + LockLeft = True + LockRight = False + LockTop = True + LockVertical = False + Multiline = False + PanelIndex = "0" + Parent = "rctFormContent" + Scope = 2 + TabIndex = 8 + TabPanelIndex = 0 + TabStop = True + Text = "Constraint:" + TextAlignment = 0 + TextColor = &c000000FF + Tooltip = "" + Top = 224 + Underline = False + Visible = True + Width = 140 + _mPanelIndex = -1 + End + End + Begin WebButton btnSave + AllowAutoDisable= False + Cancel = False + Caption = "Create" + ControlID = "" + Default = True + Enabled = False + Height = 38 + Index = -2147483648 + Indicator = 1 + Left = 480 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + Scope = 2 + TabIndex = 3 + TabStop = True + Tooltip = "" + Top = 304 + Visible = True + Width = 100 + _mPanelIndex = -1 + End + Begin WebButton btnCancel + AllowAutoDisable= False + Cancel = True + Caption = "Cancel" + ControlID = "" + Default = False + Enabled = True + Height = 38 + Index = -2147483648 + Indicator = 0 + Left = 372 + LockBottom = True + LockedInPosition= True + LockHorizontal = False + LockLeft = False + LockRight = True + LockTop = False + LockVertical = False + Scope = 2 + TabIndex = 2 + TabStop = True + Tooltip = "" + Top = 304 + Visible = True + Width = 100 + _mPanelIndex = -1 + End +End +#tag EndWebPage + +#tag WindowCode + #tag Event + Sub Shown() + edtName.SetFocus() + + End Sub + #tag EndEvent + + + #tag Method, Flags = &h21 + Private Sub RefreshButtons() + btnSave.Enabled = (edtName.Text.Trim <> "") + + End Sub + #tag EndMethod + + #tag Method, Flags = &h0 + Sub ShowAsAdd() + labTitle.Text = "Add Field" + btnSave.Caption = "Add" + Super.Show() + + End Sub + #tag EndMethod + + #tag Method, Flags = &h0 + Sub ShowAsEdit(Name As String, Type As String, Default As String, Constraint As String) + labTitle.Text = "Edit Field" + btnSave.Caption = "Edit" + btnSave.Indicator = Indicators.Primary + + Me.ShowAsEdit_FillValues(Name, Type, Default, Constraint) + + Me.RefreshButtons() + + Super.Show() + End Sub + #tag EndMethod + + #tag Method, Flags = &h21 + Private Sub ShowAsEdit_FillValues(Name As String, Type As String, Default As String, Constraint As String) + #Pragma BreakOnExceptions False + edtName.Text = Name + + lstType.SelectedRowIndex = -1 + Try + lstType.SelectRowWithTag(Type) + Catch InvalidArgumentException + lstType.AddRow("-") + lstType.AddRow(Type, Type) + lstType.SelectRowWithTag(Type) + End Try + + edtDefault.Text = Default + + lstConstraint.SelectedRowIndex = -1 + Try + lstConstraint.SelectRowWithTag(Constraint) + Catch InvalidArgumentException + lstConstraint.AddRow("-") + lstConstraint.AddRow(Constraint, Constraint) + lstConstraint.SelectRowWithTag(Constraint) + End Try + + End Sub + #tag EndMethod + + #tag Method, Flags = &h0 + Sub ShowAsRename(Name As String, Type As String, Default As String, Constraint As String) + labTitle.Text = "Rename Field" + btnSave.Caption = "Rename" + btnSave.Indicator = Indicators.Warning + + Me.ShowAsEdit_FillValues(Name, Type, Default, Constraint) + + labType.Enabled = False + lstType.Enabled = False + labDefault.Enabled = False + edtDefault.Enabled = False + labConstraint.Enabled = False + lstConstraint.Enabled = False + + Me.RefreshButtons() + + Super.Show() + End Sub + #tag EndMethod + + + #tag Hook, Flags = &h0 + Event FieldSaveAction(Name As String, Type As String, Default As String, Constraint As String) As Boolean + #tag EndHook + + +#tag EndWindowCode + +#tag Events edtName + #tag Event + Sub TextChanged() + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events lstType + #tag Event + Sub Opening() + Me.RemoveAllRows() + + Me.AddRow("(no type)", "") + Me.AddRow("-") + + Me.AddRow("TEXT", "TEXT") + Me.AddRow("INTEGER", "INTEGER") + Me.AddRow("REAL", "REAL") + Me.AddRow("BLOB", "BLOB") + Me.AddRow("CURRENCY", "CURRENCY") + Me.AddRow("BOOLEAN", "BOOLEAN") + Me.AddRow("DATE", "DATE") + Me.AddRow("TIME", "TIME") + Me.AddRow("TIMESTAMP", "TIMESTAMP") + Me.AddRow("DOUBLE", "DOUBLE") + Me.AddRow("FLOAT", "FLOAT") + Me.AddRow("SMALLINT", "SMALLINT") + Me.AddRow("VARCHAR", "VARCHAR") + Me.AddRow("BINARY", "BINARY") + + Me.SelectedRowIndex = 0 + + End Sub + #tag EndEvent + #tag Event + Sub SelectionChanged(item As WebMenuItem) + #Pragma unused item + + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events edtDefault + #tag Event + Sub TextChanged() + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events lstConstraint + #tag Event + Sub Opening() + Me.RemoveAllRows() + + Me.AddRow("(no constraint)", "") + Me.AddRow("-") + + Me.AddRow("NOT NULL", "NOT NULL") + Me.AddRow("PRIMARY KEY", "PRIMARY KEY") + Me.AddRow("PRIMARY KEY AUTOINCREMENT", "PRIMARY KEY AUTOINCREMENT") + Me.AddRow("UNIQUE (single)", "UNIQUE (single)") + Me.AddRow("UNIQUE (multi)", "UNIQUE (multi)") + + Me.SelectedRowIndex = 0 + + End Sub + #tag EndEvent + #tag Event + Sub SelectionChanged(item As WebMenuItem) + #Pragma unused item + + Self.RefreshButtons() + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnSave + #tag Event + Sub Pressed() + If FieldSaveAction(edtName.Text.Trim, _ + lstType.RowTagAt(lstType.SelectedRowIndex).StringValue, _ + edtDefault.Text.Trim, _ + lstConstraint.RowTagAt(lstConstraint.SelectedRowIndex)) Then + Self.Close() + End If + + End Sub + #tag EndEvent +#tag EndEvents +#tag Events btnCancel + #tag Event + Sub Pressed() + Self.Close() + + End Sub + #tag EndEvent +#tag EndEvents +#tag ViewBehavior + #tag ViewProperty + Name="ControlCount" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mPanelIndex" + Visible=false + Group="Behavior" + InitialValue="-1" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Index" + Visible=false + Group="ID" + InitialValue="-2147483648" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Name" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Super" + Visible=true + Group="ID" + InitialValue="" + Type="String" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Left" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Top" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="ControlID" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="Enabled" + Visible=true + Group="Behavior" + InitialValue="True" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Height" + Visible=true + Group="Behavior" + InitialValue="400" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LayoutType" + Visible=true + Group="Behavior" + InitialValue="LayoutTypes.Fixed" + Type="LayoutTypes" + EditorType="Enum" + #tag EnumValues + "0 - Fixed" + "1 - Flex" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="LockBottom" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockHorizontal" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockLeft" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockRight" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockTop" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="LockVertical" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Visible" + Visible=false + Group="Behavior" + InitialValue="" + Type="Boolean" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Width" + Visible=true + Group="Behavior" + InitialValue="600" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mDesignHeight" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mDesignWidth" + Visible=false + Group="Behavior" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="_mName" + Visible=false + Group="Behavior" + InitialValue="" + Type="String" + EditorType="MultiLineEditor" + #tag EndViewProperty + #tag ViewProperty + Name="TabIndex" + Visible=true + Group="Visual Controls" + InitialValue="" + Type="Integer" + EditorType="" + #tag EndViewProperty + #tag ViewProperty + Name="Indicator" + Visible=false + Group="Visual Controls" + InitialValue="" + Type="WebUIControl.Indicators" + EditorType="Enum" + #tag EnumValues + "0 - Default" + "1 - Primary" + "2 - Secondary" + "3 - Success" + "4 - Danger" + "5 - Warning" + "6 - Info" + "7 - Light" + "8 - Dark" + "9 - Link" + #tag EndEnumValues + #tag EndViewProperty + #tag ViewProperty + Name="LayoutDirection" + Visible=true + Group="WebView" + InitialValue="LayoutDirections.LeftToRight" + Type="LayoutDirections" + EditorType="Enum" + #tag EnumValues + "0 - LeftToRight" + "1 - RightToLeft" + "2 - TopToBottom" + "3 - BottomToTop" + #tag EndEnumValues + #tag EndViewProperty +#tag EndViewBehavior diff --git a/webapp/main/CubeSQLAdminPage.xojo_code b/webapp/main/CubeSQLAdminPage.xojo_code index 5d0ea6c..7bd8df0 100644 --- a/webapp/main/CubeSQLAdminPage.xojo_code +++ b/webapp/main/CubeSQLAdminPage.xojo_code @@ -197,6 +197,9 @@ End Case ContainerKey.Databases showContainer = New cntDatabases + Case ContainerKey.TablesAndIndexes + showContainer = New cntTablesIndexes + Case ContainerKey.Backups showContainer = New cntBackups @@ -277,6 +280,7 @@ End btn.Style = WebToolbarButton.ButtonStyles.Menu btn.Caption = "Data" btn.Menu.AddMenuItem(New WebMenuItem("Databases", ContainerKey.Databases)) + btn.Menu.AddMenuItem(New WebMenuItem("Tables & Indexes", ContainerKey.TablesAndIndexes)) btn.Menu.AddMenuItem(New WebMenuItem("Backups", ContainerKey.Backups)) btn.Menu.AddMenuItem(New WebMenuItem("Schedules", ContainerKey.Schedules)) Me.AddItem(btn) diff --git a/webapp/modCubeSQLAdmin.xojo_code b/webapp/modCubeSQLAdmin.xojo_code index 9a89c15..7750fec 100644 --- a/webapp/modCubeSQLAdmin.xojo_code +++ b/webapp/modCubeSQLAdmin.xojo_code @@ -1,8 +1,30 @@ #tag Module Protected Module modCubeSQLAdmin #tag Method, Flags = &h0 - Function EscapeSqlQuotes(Extends sql As String) As String - Return sql.ReplaceAll("'", "''") + Function EscapeSqlDefaultValueIfRequired(Extends defaultValue As String) As String + If (defaultValue.Contains(" ") Or defaultValue.Contains("'")) Then + Return "'" + defaultValue.EscapeSqlQuotes + "'" + End If + + Return defaultValue + + End Function + #tag EndMethod + + #tag Method, Flags = &h0 + Function EscapeSqlFieldIfRequired(Extends fieldname As String) As String + If (fieldname.Contains(" ") Or fieldname.Contains("""")) Then + Return """" + fieldname.ReplaceAll("""", """""") + """" + End If + + Return fieldname + + End Function + #tag EndMethod + + #tag Method, Flags = &h0 + Function EscapeSqlQuotes(Extends value As String) As String + Return value.ReplaceAll("'", "''") End Function #tag EndMethod @@ -77,15 +99,16 @@ Protected Module modCubeSQLAdmin Registration=1 Console = 2 Databases = 11 - Backups = 12 + TablesAndIndexes=12 + Schedules=14 + Backups = 13 Groups = 21 Users = 22 Privileges = 23 EnginePreferences = 24 Commands = 31 Clients = 32 - Log = 33 - Schedules=13 + Log = 33 #tag EndEnum