From fae2ee6a50ea2076af88e0b5ee60fed0187d49ec Mon Sep 17 00:00:00 2001 From: joyfullservice Date: Mon, 13 Mar 2023 14:03:04 -0500 Subject: [PATCH] Prevent table data import into linked tables Fixed an issue with table detection and adjusted to prevent importing table data into a linked table during a build or merge operation. #385 --- .../forms/frmVCSOptions.bas | 18 +---- .../modules/clsDbTableData.cls | 68 +++++++++++-------- .../modules/modDatabase.bas | 18 ++++- 3 files changed, 58 insertions(+), 46 deletions(-) diff --git a/Version Control.accda.src/forms/frmVCSOptions.bas b/Version Control.accda.src/forms/frmVCSOptions.bas index 6f2447b1..089513e6 100644 --- a/Version Control.accda.src/forms/frmVCSOptions.bas +++ b/Version Control.accda.src/forms/frmVCSOptions.bas @@ -18,7 +18,7 @@ Begin Form ItemSuffix =240 Left =3225 Top =2430 - Right =28545 + Right =22695 Bottom =16815 RecSrcDt = Begin 0x79e78b777268e540 @@ -3434,7 +3434,7 @@ Private Sub LoadTableList() ' Read table attributes blnHidden = Application.GetHiddenAttribute(acTable, tbl.Name) blnSystem = (tbl.Attributes And dbSystemObject) - blnLocal = isLocalTable(tbl.Name) + blnLocal = IsLocalTable(tbl.Name) blnOther = False ' Other represents tables not in this database. ' Add array record to represent table. AddUpdateTableInList tbl.Name, vbNullString, blnHidden, blnSystem, blnOther, blnLocal @@ -3455,20 +3455,6 @@ Private Sub LoadTableList() End Sub -'--------------------------------------------------------------------------------------- -' Procedure : isLocalTable -' Author : Adam Waller & Indigo744 -' Date : 11/11/2020 -' Purpose : Check wether a table is a local table (= not a linked table) -'--------------------------------------------------------------------------------------- -' -Private Function isLocalTable(ByVal tblName As String) -On Error Resume Next - isLocalTable = False - isLocalTable = Len(CurrentDb.TableDefs(tblName).Connect) = 0 -End Function - - '--------------------------------------------------------------------------------------- ' Procedure : AddUpdateTableInList ' Author : Adam Waller diff --git a/Version Control.accda.src/modules/clsDbTableData.cls b/Version Control.accda.src/modules/clsDbTableData.cls index c1ae1487..0bb63832 100644 --- a/Version Control.accda.src/modules/clsDbTableData.cls +++ b/Version Control.accda.src/modules/clsDbTableData.cls @@ -356,34 +356,45 @@ Private Sub IDbComponent_Import(strFile As String) Dim strTempFile As String Dim strTable As String - ' Import from different formats (XML is preferred for data integrity) - Select Case GetFormatByExt(strFile) - Case etdXML - strTable = GetObjectNameFromFileName(strFile) - ' Make sure table exists before importing data to it. - If TableExists(strTable) Then - ' The ImportXML function does not properly handle UrlEncoded paths - blnUseTemp = (InStr(1, strFile, "%") > 0) - If blnUseTemp Then - ' Import from (safe) temporary file name. - strTempFile = GetTempFile - FSO.CopyFile strFile, strTempFile - Application.ImportXML strTempFile, acAppendData - DeleteFile strTempFile - Else - Application.ImportXML strFile, acAppendData - End If - Else - ' Warn user that table does not exist. - MsgBox2 "Table structure not found for '" & strTable & "'", _ - "The structure of a table should be created before importing data into it.", _ - "Please ensure that the table definition file exists in \tbldefs.", vbExclamation - Log.Add "WARNING: Table definition does not exist for '" & strTable & "'. This must be created before importing table data." - End If - Case etdTabDelimited - ImportTableDataTDF strFile - End Select + ' Make sure table exists before importing data to it. + strTable = GetObjectNameFromFileName(strFile) + ' Only allow import into local tables (not linked tables) + If IsLocalTable(strTable) Then + + ' Import from different formats (XML is preferred for data integrity) + Select Case GetFormatByExt(strFile) + Case etdXML + + ' The ImportXML function does not properly handle UrlEncoded paths + blnUseTemp = (InStr(1, strFile, "%") > 0) + If blnUseTemp Then + ' Import from (safe) temporary file name. + strTempFile = GetTempFile + FSO.CopyFile strFile, strTempFile + Application.ImportXML strTempFile, acAppendData + DeleteFile strTempFile + Else + Application.ImportXML strFile, acAppendData + End If + + Case etdTabDelimited + ImportTableDataTDF strFile + End Select + + Else + ' Either not a local table, or it doesn't exist + If TableExists(strTable) Then + Log.Error eelWarning, "Table data may only be imported into local tables", "clsDbTableData.Import" + Else + ' Warn user that table does not exist. + Log.Error eelError, "Table structure not found for '" & strTable & "'.", "clsDbTableData.Import" + Log.Add "Table definition does not exist for '" & strTable & _ + "'. This must be created before importing table data.", False + End If + Log.Add "Table data from '" & strTable & "' was not imported.", False + End If + End Sub @@ -396,7 +407,8 @@ End Sub '--------------------------------------------------------------------------------------- ' Private Sub IDbComponent_Merge(strFile As String) - + Log.Error eelWarning, "Merge not supported for table data. (" & _ + GetObjectNameFromFileName(strFile) & ")", "clsDbTableData.Merge" End Sub diff --git a/Version Control.accda.src/modules/modDatabase.bas b/Version Control.accda.src/modules/modDatabase.bas index 4aae5f8a..208372d2 100644 --- a/Version Control.accda.src/modules/modDatabase.bas +++ b/Version Control.accda.src/modules/modDatabase.bas @@ -587,12 +587,26 @@ End Function '--------------------------------------------------------------------------------------- ' Procedure : TableExists ' Author : Adam Waller -' Date : 5/7/2020 +' Date : 3/13/2023 ' Purpose : Returns true if the table object is found in the dabase. (SQL version) +' : (Includes both local and linked tables, including system tables.) '--------------------------------------------------------------------------------------- ' Public Function TableExists(strName As String) As Boolean - TableExists = Not (DCount("*", "MSysObjects", "Name=""" & strName & """ AND Type=1") = 0) + TableExists = Not (DCount("*", "MSysObjects", "Name=""" & strName & """ AND Type in (1,4,6)") = 0) +End Function + + +'--------------------------------------------------------------------------------------- +' Procedure : IsLocalTable +' Author : Adam Waller +' Date : 3/13/2023 +' Purpose : Returns true if the table exists as a local (not linked) table in the +' : current database. +'--------------------------------------------------------------------------------------- +' +Public Function IsLocalTable(strName As String) As Boolean + IsLocalTable = Not (DCount("*", "MSysObjects", "Name=""" & strName & """ AND Type = 1") = 0) End Function