Kaydet (Commit) 3cac1694 authored tarafından Jean-Pierre Ledure's avatar Jean-Pierre Ledure

Access2Base - CopyObject applied on tables belonging to different databases

So far, only tables belonging to the SAME database could be copied.
Copying tables between databases from different sources (HSQLDB 1.8/2.3, MySQL, PostGres, Sqlite)
is admitted.
Field type conversions are in this case based on empiric rules.
A case study based on getMetadatInfo() is available on request.

Change-Id: Iae4ea7c4df4799cde3c8f973746513bad56246d8
üst 5f55b7d0
...@@ -72,12 +72,25 @@ Global Const ERRTABLECREATION = 1551 ...@@ -72,12 +72,25 @@ Global Const ERRTABLECREATION = 1551
Global Const ERRFIELDCREATION = 1552 Global Const ERRFIELDCREATION = 1552
Global Const ERRSUBFORMNOTFOUND = 1553 Global Const ERRSUBFORMNOTFOUND = 1553
Global Const ERRWINDOW = 1554 Global Const ERRWINDOW = 1554
Global Const ERRCOMPATIBILITY = 1555
Global Const ERRPRECISION = 1556
REM ----------------------------------------------------------------------------------------------------------------------- REM -----------------------------------------------------------------------------------------------------------------------
Global Const DBCONNECTBASE = 1 ' Connection from Base document (OpenConnection) Global Const DBCONNECTBASE = 1 ' Connection from Base document (OpenConnection)
Global Const DBCONNECTFORM = 2 ' Connection from a database-aware form (OpenConnection) Global Const DBCONNECTFORM = 2 ' Connection from a database-aware form (OpenConnection)
Global Const DBCONNECTANY = 3 ' Connection from any document for data access only (OpenDatabase) Global Const DBCONNECTANY = 3 ' Connection from any document for data access only (OpenDatabase)
REM -----------------------------------------------------------------------------------------------------------------------
Global Const DBMS_UNKNOWN = 0
Global Const DBMS_HSQLDB1 = 1
Global Const DBMS_HSQLDB2 = 2
Global Const DBMS_FIREBIRD = 3
Global Const DBMS_MSACCESS2003 = 4
Global Const DBMS_MSACCESS2007 = 5
Global Const DBMS_MYSQL = 6
Global Const DBMS_POSTGRES = 7
Global Const DBMS_SQLITE = 8
REM ----------------------------------------------------------------------------------------------------------------------- REM -----------------------------------------------------------------------------------------------------------------------
Global Const COLLALLDIALOGS = "ALLDIALOGS" Global Const COLLALLDIALOGS = "ALLDIALOGS"
Global Const COLLALLFORMS = "ALLFORMS" Global Const COLLALLFORMS = "ALLFORMS"
...@@ -1039,7 +1052,12 @@ Const cstThisSub = "OpenConnection" ...@@ -1039,7 +1052,12 @@ Const cstThisSub = "OpenConnection"
vDocContainer.DbConnect = DBCONNECTBASE vDocContainer.DbConnect = DBCONNECTBASE
._DbConnect = DBCONNECTBASE ._DbConnect = DBCONNECTBASE
Set .MetaData = .Connection.MetaData Set .MetaData = .Connection.MetaData
._ReadOnly = .Connection.isReadOnly() ._LoadMetadata()
If .MetaData.DatabaseProductName = "MySQL" Then
._ReadOnly = .MetaData.isReadOnly()
Else
._ReadOnly = .Connection.isReadOnly() ' Always True in Mysql ??
End If
Set .Document = oComponent Set .Document = oComponent
.Title = oComponent.Title .Title = oComponent.Title
.URL = vDocContainer.URL .URL = vDocContainer.URL
...@@ -1064,6 +1082,7 @@ Const cstThisSub = "OpenConnection" ...@@ -1064,6 +1082,7 @@ Const cstThisSub = "OpenConnection"
Set .Connection = .Form.ActiveConnection ' Might be Nothing in Windows at AOO/LO startup (not met in Linux) Set .Connection = .Form.ActiveConnection ' Might be Nothing in Windows at AOO/LO startup (not met in Linux)
If Not IsNull(.Connection) Then If Not IsNull(.Connection) Then
Set .MetaData = .Connection.MetaData Set .MetaData = .Connection.MetaData
._LoadMetadata()
._ReadOnly = .Connection.isReadOnly() ._ReadOnly = .Connection.isReadOnly()
TraceLog(TRACEANY, .MetaData.getDatabaseProductName() & " " & .MetaData.getDatabaseProductVersion, False) TraceLog(TRACEANY, .MetaData.getDatabaseProductName() & " " & .MetaData.getDatabaseProductVersion, False)
End If End If
...@@ -1163,6 +1182,7 @@ Const cstThisSub = "OpenDatabase" ...@@ -1163,6 +1182,7 @@ Const cstThisSub = "OpenDatabase"
Set odbDatabase.Connection = oBaseSource.getConnection(pvUser, pvPassword) Set odbDatabase.Connection = oBaseSource.getConnection(pvUser, pvPassword)
If Not IsNull(odbDatabase.Connection) Then ' Null when standalone and target db does not exist If Not IsNull(odbDatabase.Connection) Then ' Null when standalone and target db does not exist
Set odbDatabase.MetaData = odbDatabase.Connection.MetaData Set odbDatabase.MetaData = odbDatabase.Connection.MetaData
odbDatabase._LoadMetadata()
Else Else
Goto Trace_Error Goto Trace_Error
End If End If
......
...@@ -23,6 +23,13 @@ Private Connection As Object ' com.sun.star.sdbc.drivers.OConnectionW ...@@ -23,6 +23,13 @@ Private Connection As Object ' com.sun.star.sdbc.drivers.OConnectionW
Private URL As String Private URL As String
Private _ReadOnly As Boolean Private _ReadOnly As Boolean
Private MetaData As Object ' interface XDatabaseMetaData Private MetaData As Object ' interface XDatabaseMetaData
Private _RDBMS As Integer ' DBMS constants
Private _ColumnTypes() As Variant ' Part of Metadata.GetTypeInfo()
Private _ColumnTypeNames() As Variant
Private _ColumnPrecisions() As Variant
Private _ColumnTypesReference() As Variant
Private _ColumnTypesAlias() As Variant ' To what should a field whose origin is another DBMS be converted ? See DataTypes By RDBMS.ods
Private _BinaryStream As Boolean ' False = binary fields must NOT be streamed f.i. via ReadAllBytes or WriteAllBytes
Private Form As Object ' com.sun.star.form.XForm Private Form As Object ' com.sun.star.form.XForm
Private FormName As String Private FormName As String
Private RecordsetMax As Integer Private RecordsetMax As Integer
...@@ -41,6 +48,13 @@ Private Sub Class_Initialize() ...@@ -41,6 +48,13 @@ Private Sub Class_Initialize()
URL = "" URL = ""
_ReadOnly = False _ReadOnly = False
Set MetaData = Nothing Set MetaData = Nothing
_RDBMS = DBMS_UNKNOWN
_ColumnTypes = Array()
_ColumnTypeNames = Array()
_ColumnPrecisions = Array()
_ColumnTypesReference = Array()
_ColumnTypesAlias() = Array()
_BinaryStream = False
Set Form = Nothing Set Form = Nothing
FormName = "" FormName = ""
RecordsetMax = 0 RecordsetMax = 0
...@@ -1060,6 +1074,119 @@ Error_Function: ' Item by key aborted ...@@ -1060,6 +1074,119 @@ Error_Function: ' Item by key aborted
GoTo Exit_Function GoTo Exit_Function
End Function ' _hasRecordset V0.9.5 End Function ' _hasRecordset V0.9.5
REM -----------------------------------------------------------------------------------------------------------------------
Private Sub _LoadMetadata()
' Load essentially getTypeInfo() results from Metadata
Dim sProduct As String
Dim iInfo As Integer, oTypeInfo As Object, sName As String, lType As Integer
Const cstMaxInfo = 40
ReDim _ColumnTypes(0 To cstMaxInfo)
ReDim _ColumnTypeNames(0 To cstMaxInfo)
ReDim _ColumnPrecisions(0 To cstMaxInfo)
Const cstHSQLDB1 = "HSQL Database Engine 1."
Const cstHSQLDB2 = "HSQL Database Engine 2."
Const cstMSAccess2003 = "MS Jet 0"
Const cstMSAccess2007 = "MS Jet 04."
Const cstMYSQL = "MySQL"
Const cstPOSTGRES = "PostgreSQL"
Const cstSQLITE = "SQLite"
With com.sun.star.sdbc.DataType
_ColumnTypesReference = Array( _
.ARRAY _
, .BIGINT _
, .BINARY _
, .BIT _
, .BLOB _
, .BOOLEAN _
, .CHAR _
, .CLOB _
, .DATE _
, .DECIMAL _
, .DISTINCT _
, .DOUBLE _
, .FLOAT _
, .INTEGER _
, .LONGVARBINARY _
, .LONGVARCHAR _
, .NUMERIC _
, .OBJECT _
, .OTHER _
, .REAL _
, .REF _
, .SMALLINT _
, .SQLNULL _
, .STRUCT _
, .TIME _
, .TIMESTAMP _
, .TINYINT _
, .VARBINARY _
, .VARCHAR _
)
End With
With Metadata
sProduct = .getDatabaseProductName() & " " & .getDatabaseProductVersion
Select Case True
Case Len(sProduct) > Len(cstHSQLDB1) And Left(sProduct, Len(cstHSQLDB1)) = cstHSQLDB1
_RDBMS = DBMS_HSQLDB1
_ColumnTypesAlias = Array(0, -5, -2, 16, -4, 16, 1, -1, 91, 3, 0, 8, 6, 4, -4, -1, 2, 0, 0, 7, 0, 5, 0, 0, 92, 93, -6, -3, 12)
_BinaryStream = True
Case Len(sProduct) > Len(cstHSQLDB2) And Left(sProduct, Len(cstHSQLDB2)) = cstHSQLDB2
_RDBMS = DBMS_HSQLDB2
_ColumnTypesAlias = Array(0, -5, -3, -7, 2004, 16, 1, 2005, 91, 3, 0, 8, 8, 4, -3, 12, 2, 0, 0, 8, 0, 5, 0, 0, 92, 93, -6, -3, 12)
_BinaryStream = True
Case Len(sProduct) > Len(cstMSAccess2007) And Left(sProduct, Len(cstMSAccess2007)) = cstMSAccess2007
_RDBMS = DBMS_MSACCESS2007
_ColumnTypesAlias = Array(0, 4, -2, 16, -2, 16, 12, 12, 93, 8, 0, 8, 6, 4, -3, 12, 2, 0, 0, 8, 0, 5, 0, 0, 93, 93, -6, -2, 12)
_BinaryStream = True
Case Len(sProduct) > Len(cstMSAccess2003) And Left(sProduct, Len(cstMSAccess2003)) = cstMSAccess2003
_RDBMS = DBMS_MSACCESS2003
_ColumnTypesAlias = Array(0, 4, -2, 16, -2, 16, 12, 12, 93, 8, 0, 8, 6, 4, -3, 12, 2, 0, 0, 8, 0, 5, 0, 0, 93, 93, -6, -2, 12)
_BinaryStream = True
Case Len(sProduct) > Len(cstMYSQL) And Left(sProduct, Len(cstMYSQL)) = cstMYSQL
_RDBMS = DBMS_MYSQL
_ColumnTypesAlias = Array(0, -5, -2, -7, -4, -7, 1, -1, 91, 3, 0, 8, 8, 4, -4, -1, 2, 0, 0, 7, 0, 5, 0, 0, 92, 93, -6, -3, -1)
_BinaryStream = False
Case Len(sProduct) > Len(cstPOSTGRES) And Left(sProduct, Len(cstPOSTGRES)) = cstPOSTGRES
_RDBMS = DBMS_POSTGRES
_ColumnTypesAlias = Array(0, -5, -3, 16, -3, 16, 1, 12, 91, 8, 0, 8, 8, 4, -3, 12, 2, 0, 0, 7, 0, 5, 0, 0, 92, 93, 4, -3, 12)
_BinaryStream = True
Case Len(sProduct) > Len(cstSQLITE) And Left(sProduct, Len(cstSQLITE)) = cstSQLITE
_RDBMS = DBMS_SQLITE
_ColumnTypesAlias = Array(0, -5, -4, -7, -4, -7, 1, -1, 91, 8, 0, 8, 6, 4, -4, -1, 8, 0, 0, 8, 0, 5, 0, 0, 92, 93, -6, -4, 12)
_BinaryStream = True
Case Else ' Firebird TODO
_RDBMS = DBMS_UNKNOWN
_BinaryStream = True
End Select
iInfo = -1
Set oTypeInfo = MetaData.getTypeInfo()
With oTypeInfo
.next()
Do While Not .isAfterLast() And iInfo < cstMaxInfo
sName = .getString(1)
lType = .getLong(2)
If _RDBMS = DBMS_POSTGRES And (Left(sName, 1) <> "_" Or lType <> -1) Then ' Skip
Else
iInfo = iInfo + 1
_ColumnTypeNames(iInfo) = sName
_ColumnTypes(iInfo) = lType
_ColumnPrecisions(iInfo) = .getLong(3)
End If
.next()
Loop
End With
ReDim Preserve _ColumnTypes(0 To iInfo)
ReDim Preserve _ColumnTypeNames(0 To iInfo)
ReDim Preserve _ColumnPrecisions(0 To iInfo)
End With
End Sub ' _LoadMetadata V1.6.0
REM ----------------------------------------------------------------------------------------------------------------------- REM -----------------------------------------------------------------------------------------------------------------------
Private Function _OutputBooleanToHTML(ByVal pbBool As Boolean) As String Private Function _OutputBooleanToHTML(ByVal pbBool As Boolean) As String
' Converts input boolean value to HTML compatible string ' Converts input boolean value to HTML compatible string
......
...@@ -151,7 +151,7 @@ Dim iChunkType As Integer ...@@ -151,7 +151,7 @@ Dim iChunkType As Integer
Select Case Column.Type ' DOES NOT WORK FOR CHARACTER TYPES Select Case Column.Type ' DOES NOT WORK FOR CHARACTER TYPES
' Case .CHAR, .VARCHAR, .LONGVARCHAR, .CLOB ' Case .CHAR, .VARCHAR, .LONGVARCHAR, .CLOB
' iChunkType = vbString ' iChunkType = vbString
Case .BINARY, .VARBINARY, .LONGVARBINARY, .BLOB Case .BINARY, .VARBINARY, .LONGVARBINARY, .BLOB, .CHAR ' .CHAR added for Sqlite3
iChunkType = vbByte iChunkType = vbByte
Case Else Case Else
Goto Trace_Error Goto Trace_Error
......
...@@ -78,6 +78,8 @@ Dim sLocal As String ...@@ -78,6 +78,8 @@ Dim sLocal As String
Case "ERR" & ERRFIELDCREATION : sLocal = "Field '%0' could not be created" Case "ERR" & ERRFIELDCREATION : sLocal = "Field '%0' could not be created"
Case "ERR" & ERRSUBFORMNOTFOUND : sLocal = "Subform '%0' not found in parent form '%1'" Case "ERR" & ERRSUBFORMNOTFOUND : sLocal = "Subform '%0' not found in parent form '%1'"
Case "ERR" & ERRWINDOW : sLocal = "Current window is not a document" Case "ERR" & ERRWINDOW : sLocal = "Current window is not a document"
Case "ERR" & ERRCOMPATIBILITY : sLocal = "Field '%0' could not be converted due to incompatibility of field types between database systems"
Case "ERR" & ERRPRECISION : sLocal = "Field '%0' could not be loaded in record #%1 due to capacity shortage"
'---------------------------------------------------------------------------------------------------------------------- '----------------------------------------------------------------------------------------------------------------------
Case "OBJECT" : sLocal = "Object" Case "OBJECT" : sLocal = "Object"
Case "TABLE" : sLocal = "Table" Case "TABLE" : sLocal = "Table"
...@@ -187,6 +189,8 @@ Dim sLocal As String ...@@ -187,6 +189,8 @@ Dim sLocal As String
Case "ERR" & ERRFIELDCREATION : sLocal = "Le champ '%0' n'a pas pu être créé" Case "ERR" & ERRFIELDCREATION : sLocal = "Le champ '%0' n'a pas pu être créé"
Case "ERR" & ERRSUBFORMNOTFOUND : sLocal = "Sous-formulaire '%0' non trouvé dans le formulaire parent '%1'" Case "ERR" & ERRSUBFORMNOTFOUND : sLocal = "Sous-formulaire '%0' non trouvé dans le formulaire parent '%1'"
Case "ERR" & ERRWINDOW : sLocal = "La fenêtre courante n'est pas un document" Case "ERR" & ERRWINDOW : sLocal = "La fenêtre courante n'est pas un document"
Case "ERR" & ERRCOMPATIBILITY : sLocal = "Le champ '%0' n'a pas pu être converti à cause d'une incompatibilité entre les types de champs supportés par les systèmes de bases de données respectifs"
Case "ERR" & ERRPRECISION : sLocal = "Le champ '%0' n'a pas pu être chargé dans l'enregistrement #%1 par manque de capacité"
'---------------------------------------------------------------------------------------------------------------------- '----------------------------------------------------------------------------------------------------------------------
Case "OBJECT" : sLocal = "Objet" Case "OBJECT" : sLocal = "Objet"
Case "TABLE" : sLocal = "Table" Case "TABLE" : sLocal = "Table"
......
...@@ -816,7 +816,7 @@ Public Function _AppendChunk(ByVal psFieldName As String, ByRef pvChunk As Varia ...@@ -816,7 +816,7 @@ Public Function _AppendChunk(ByVal psFieldName As String, ByRef pvChunk As Varia
If _ErrorHandler() Then On Local Error GoTo Error_Function If _ErrorHandler() Then On Local Error GoTo Error_Function
Dim oFileAccess As Object Dim oFileAccess As Object
Dim i As Integer, oChunk As Object, iChunk As Integer, sRandom As String Dim i As Integer, oChunk As Object, iChunk As Integer
' Do nothing if chunk meaningless ' Do nothing if chunk meaningless
_AppendChunk = False _AppendChunk = False
...@@ -844,8 +844,7 @@ Dim i As Integer, oChunk As Object, iChunk As Integer, sRandom As String ...@@ -844,8 +844,7 @@ Dim i As Integer, oChunk As Object, iChunk As Integer, sRandom As String
If Not .ChunksRequested Then ' First chunk If Not .ChunksRequested Then ' First chunk
.ChunksRequested = True .ChunksRequested = True
.ChunkType = piChunkType .ChunkType = piChunkType
sRandom = Right("000000" & Int(999999 * Rnd), 6) .FileName = Utils._GetRandomFileName(_Name)
.FileName = DoCmd._getTempDirectoryURL() & "/" & "A2B_TEMP_" & _Name & "_" & sRandom
Set oFileAccess = CreateUnoService("com.sun.star.ucb.SimpleFileAccess") Set oFileAccess = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
.FileHandler = oFileAccess.openFileWrite(.FileName) .FileHandler = oFileAccess.openFileWrite(.FileName)
End If End If
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd"> <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="_License" script:language="StarBasic">&apos; Copyright 2012-2013 Jean-Pierre LEDURE <script:module xmlns:script="http://openoffice.org/2000/script" script:name="_License" script:language="StarBasic">&apos; Copyright 2012-2017 Jean-Pierre LEDURE
REM ======================================================================================================================= REM =======================================================================================================================
REM === The Access2Base library is a part of the LibreOffice project. === REM === The Access2Base library is a part of the LibreOffice project. ===
......
...@@ -8,7 +8,7 @@ REM ============================================================================ ...@@ -8,7 +8,7 @@ REM ============================================================================
Option Explicit Option Explicit
REM Access2Base ----------------------------------------------------- REM Access2Base -----------------------------------------------------
Global Const Access2Base_Version = &quot;1.5.0&quot; Global Const Access2Base_Version = &quot;1.6.0&quot;
REM AcCloseSave REM AcCloseSave
REM ----------------------------------------------------------------- REM -----------------------------------------------------------------
...@@ -87,6 +87,7 @@ Global Const vbUShort = 18 ...@@ -87,6 +87,7 @@ Global Const vbUShort = 18
Global Const vbULong = 19 Global Const vbULong = 19
Global Const vbBigint = 35 Global Const vbBigint = 35
Global Const vbDecimal = 37 Global Const vbDecimal = 37
Global Const vbArray = 8192
REM MsgBox constants REM MsgBox constants
REM ----------------------------------------------------------------- REM -----------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment