Advertisement
Guest User

mysqlbackup

a guest
Dec 5th, 2019
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 44.07 KB | None | 0 0
  1. Imports System
  2. Imports System.Timers
  3. Imports System.Collections.Generic
  4. Imports System.Text
  5. Imports MySql.Data.MySqlClient
  6. Imports System.ComponentModel
  7. Imports System.IO
  8. Imports System.IO.Compression
  9. Imports System.Globalization
  10. Imports System.Security.Cryptography
  11. Imports System.Reflection
  12.  
  13. Namespace MySql.Data.MySqlClient
  14.     Public Class MySqlBackup
  15.         Implements IDisposable
  16.  
  17.  
  18.  
  19.         Enum ProcessType
  20.             Export
  21.             Import
  22.         End Enum
  23.  
  24.         Public Enum ProcessEndType
  25.             UnknownStatus
  26.             Complete
  27.             Cancelled
  28.             [Error]
  29.         End Enum
  30.  
  31.         Public Const Version As String = "2.3.1"
  32.         Private _database As MySqlDatabase = New MySqlDatabase()
  33.         Private _server As MySqlServer = New MySqlServer()
  34.  
  35.         Private ReadOnly Property textEncoding As Encoding
  36.             Get
  37.  
  38.                 Try
  39.                     Return ExportInfo.TextEncoding
  40.                 Catch
  41.                 End Try
  42.  
  43.                 Return New UTF8Encoding(False)
  44.             End Get
  45.         End Property
  46.  
  47.         Private textWriter As TextWriter
  48.         Private textReader As TextReader
  49.         Private timeStart As DateTime
  50.         Private timeEnd As DateTime
  51.         Private currentProcess As ProcessType
  52.         Private processCompletionType As ProcessEndType
  53.         Private stopProcess As Boolean = False
  54.         Private _lastError As Exception = Nothing
  55.         Private _lastErrorSql As String = ""
  56.         Private _currentTableName As String = ""
  57.         Private _totalRowsInCurrentTable As Long = 0
  58.         Private _totalRowsInAllTables As Long = 0
  59.         Private _currentRowIndexInCurrentTable As Long = 0
  60.         Private _currentRowIndexInAllTable As Long = 0
  61.         Private _totalTables As Integer = 0
  62.         Private _currentTableIndex As Integer = 0
  63.         Private timerReport As Timer = Nothing
  64.         Private _currentBytes As Long = 0L
  65.         Private _totalBytes As Long = 0L
  66.         Private _sbImport As StringBuilder = Nothing
  67.         Private _mySqlScript As MySqlScript = Nothing
  68.         Private _delimiter As String = ""
  69.         Private utf8WithoutBOM As Encoding
  70.  
  71.  
  72.         Enum NextImportAction
  73.             Ignore
  74.             SetNames
  75.             CreateNewDatabase
  76.             AppendLine
  77.             ChangeDelimiter
  78.             AppendLineAndExecute
  79.         End Enum
  80.  
  81.         Public ReadOnly Property LastError As Exception
  82.             Get
  83.                 Return _lastError
  84.             End Get
  85.         End Property
  86.  
  87.         Public ReadOnly Property LastErrorSQL As String
  88.             Get
  89.                 Return _lastErrorSql
  90.             End Get
  91.         End Property
  92.  
  93.         Public ReadOnly Property Database As MySqlDatabase
  94.             Get
  95.                 Return _database
  96.             End Get
  97.         End Property
  98.  
  99.         Public ReadOnly Property Server As MySqlServer
  100.             Get
  101.                 Return _server
  102.             End Get
  103.         End Property
  104.  
  105.         Public Property Command As MySqlCommand
  106.         Public ExportInfo As ExportInformations = New ExportInformations()
  107.         Public ImportInfo As ImportInformations = New ImportInformations()
  108.         Public Delegate Sub exportProgressChange(ByVal sender As Object, ByVal e As ExportProgressArgs)
  109.         Public Event ExportProgressChanged As exportProgressChange
  110.         Public Delegate Sub exportComplete(ByVal sender As Object, ByVal e As ExportCompleteArgs)
  111.         Public Event ExportCompleted As exportComplete
  112.         Public Delegate Sub importProgressChange(ByVal sender As Object, ByVal e As ImportProgressArgs)
  113.         Public Event ImportProgressChanged As importProgressChange
  114.         Public Delegate Sub importComplete(ByVal sender As Object, ByVal e As ImportCompleteArgs)
  115.         Public Event ImportCompleted As importComplete
  116.         Public Delegate Sub getTotalRowsProgressChange(ByVal sender As Object, ByVal e As GetTotalRowsArgs)
  117.         Public Event GetTotalRowsProgressChanged As getTotalRowsProgressChange
  118.  
  119.         Public Sub New()
  120.             InitializeComponents()
  121.         End Sub
  122.  
  123.         Public Sub New(ByVal cmd As MySqlCommand)
  124.             InitializeComponents()
  125.             Command = cmd
  126.         End Sub
  127.  
  128.         Private Sub InitializeComponents()
  129.             AddHandler Me._database.GetTotalRowsProgressChanged, AddressOf Me._database_GetTotalRowsProgressChanged
  130.  
  131.             Me.timerReport = New Timer
  132.             AddHandler Me.timerReport.Elapsed, New ElapsedEventHandler(AddressOf Me.timerReport_Elapsed)
  133.             Me.utf8WithoutBOM = New UTF8Encoding(False)
  134.             timerReport = New Timer()
  135.             AddHandler timerReport.Elapsed, AddressOf timerReport_Elapsed
  136.         End Sub
  137.  
  138.         Private Sub _database_GetTotalRowsProgressChanged(ByVal sender As Object, ByVal e As GetTotalRowsArgs)
  139.             RaiseEvent GetTotalRowsProgressChanged(Me, e)
  140.         End Sub
  141.  
  142.         Public Function ExportToString() As String
  143.             Using ms As MemoryStream = New MemoryStream()
  144.                 ExportToMemoryStream(ms)
  145.                 ms.Position = 0L
  146.  
  147.                 Using thisReader = New StreamReader(ms)
  148.                     Return thisReader.ReadToEnd()
  149.                 End Using
  150.             End Using
  151.         End Function
  152.  
  153.         Public Sub ExportToFile(ByVal filePath As String)
  154.             Using textWriter = New StreamWriter(filePath, False, Me.utf8WithoutBOM)
  155.                 Me.ExportStart()
  156.                 Me.textWriter.Close()
  157.             End Using
  158.         End Sub
  159.  
  160.         Public Sub ExportToTextWriter(ByVal tw As TextWriter)
  161.             textWriter = tw
  162.             ExportStart()
  163.         End Sub
  164.  
  165.         Public Sub ExportToMemoryStream(ByVal ms As MemoryStream)
  166.             ExportToMemoryStream(ms, True)
  167.         End Sub
  168.  
  169.         Public Sub ExportToMemoryStream(ByVal ms As MemoryStream, ByVal resetMemoryStreamPosition As Boolean)
  170.             If resetMemoryStreamPosition Then
  171.                 If ms Is Nothing Then ms = New MemoryStream()
  172.                 If ms.Length > 0 Then ms = New MemoryStream()
  173.                 ms.Position = 0L
  174.             End If
  175.  
  176.             textWriter = New StreamWriter(ms, textEncoding)
  177.             ExportStart()
  178.         End Sub
  179.  
  180.         Private Sub ExportStart()
  181.             Try
  182.                 Export_InitializeVariables()
  183.                 Dim stage As Integer = 1
  184.  
  185.                 While stage < 11
  186.                     If stopProcess Then Exit While
  187.  
  188.                     Select Case stage
  189.                         Case 1
  190.                             Export_BasicInfo()
  191.                         Case 2
  192.                             Export_CreateDatabase()
  193.                         Case 3
  194.                             Export_DocumentHeader()
  195.                         Case 4
  196.                             Export_TableRows()
  197.                         Case 5
  198.                             Export_Functions()
  199.                         Case 6
  200.                             Export_Procedures()
  201.                         Case 7
  202.                             Export_Events()
  203.                         Case 8
  204.                             Export_Views()
  205.                         Case 9
  206.                             Export_Triggers()
  207.                         Case 10
  208.                             Export_DocumentFooter()
  209.                         Case Else
  210.                     End Select
  211.  
  212.                     textWriter.Flush()
  213.                     stage = stage + 1
  214.                 End While
  215.  
  216.                 If stopProcess Then
  217.                     processCompletionType = ProcessEndType.Cancelled
  218.                 Else
  219.                     processCompletionType = ProcessEndType.Complete
  220.                 End If
  221.  
  222.             Catch ex As Exception
  223.                 _lastError = ex
  224.                 StopAllProcess()
  225.                 Throw
  226.             End Try
  227.  
  228.             ReportEndProcess()
  229.         End Sub
  230.  
  231.         Private Sub Export_InitializeVariables()
  232.             If Command Is Nothing Then
  233.                 Throw New Exception("MySqlCommand is not initialized. Object not set to an instance of an object.")
  234.             End If
  235.  
  236.             If Command.Connection Is Nothing Then
  237.                 Throw New Exception("MySqlCommand.Connection is not initialized. Object not set to an instance of an object.")
  238.             End If
  239.  
  240.             If Command.Connection.State <> System.Data.ConnectionState.Open Then
  241.                 Throw New Exception("MySqlCommand.Connection is not opened.")
  242.             End If
  243.  
  244.             If ExportInfo.BlobExportMode = BlobDataExportMode.BinaryChar AndAlso Not ExportInfo.BlobExportModeForBinaryStringAllow Then
  245.                 Throw New Exception("[ExportInfo.BlobExportMode = BlobDataExportMode.BinaryString] is still under development. Please join the discussion at https://github.com/MySqlBackupNET/MySqlBackup.Net/issues (Title: Help requires. Unable to export BLOB in Char Format)")
  246.             End If
  247.  
  248.             timeStart = DateTime.Now
  249.             stopProcess = False
  250.             processCompletionType = ProcessEndType.UnknownStatus
  251.             currentProcess = ProcessType.Export
  252.             _lastError = Nothing
  253.             timerReport.Interval = ExportInfo.IntervalForProgressReport
  254.             _database.GetDatabaseInfo(Command, ExportInfo.GetTotalRowsMode)
  255.             _server.GetServerInfo(Command)
  256.             _currentTableName = ""
  257.             _totalRowsInCurrentTable = 0L
  258.             _totalRowsInAllTables = 0L
  259.             Dim dicTables = Export_GetTablesToBeExported()
  260.  
  261.             For Each kv In dicTables
  262.                 _totalRowsInAllTables = _totalRowsInAllTables + _database.Tables(kv.Key).TotalRows
  263.             Next
  264.  
  265.             _currentRowIndexInCurrentTable = 0
  266.             _currentRowIndexInAllTable = 0
  267.             _totalTables = 0
  268.             _currentTableIndex = 0
  269.         End Sub
  270.  
  271.         Private Sub Export_BasicInfo()
  272.             Export_WriteComment(String.Format("MySqlBackup.NET {0}", MySqlBackup.Version))
  273.  
  274.             If ExportInfo.RecordDumpTime Then
  275.                 Export_WriteComment(String.Format("Dump Time: {0}", timeStart.ToString("yyyy-MM-dd HH:mm:ss")))
  276.             Else
  277.                 Export_WriteComment("")
  278.             End If
  279.  
  280.             Export_WriteComment("--------------------------------------")
  281.             Export_WriteComment(String.Format("Server version {0}", _server.Version))
  282.             textWriter.WriteLine()
  283.         End Sub
  284.  
  285.         Private Sub Export_CreateDatabase()
  286.             If Not ExportInfo.AddCreateDatabase AndAlso Not ExportInfo.AddDropDatabase Then Return
  287.             textWriter.WriteLine()
  288.             textWriter.WriteLine()
  289.             If ExportInfo.AddDropDatabase Then Export_WriteLine(String.Format("DROP DATABASE `{0}`;", _database.Name))
  290.  
  291.             If ExportInfo.AddCreateDatabase Then
  292.                 Export_WriteLine(_database.CreateDatabaseSQL)
  293.                 Export_WriteLine(String.Format("USE `{0}`;", _database.Name))
  294.             End If
  295.  
  296.             textWriter.WriteLine()
  297.             textWriter.WriteLine()
  298.         End Sub
  299.  
  300.         Private Sub Export_DocumentHeader()
  301.             textWriter.WriteLine()
  302.             Dim lstHeaders As List(Of String) = ExportInfo.GetDocumentHeaders(Command)
  303.  
  304.             If lstHeaders.Count > 0 Then
  305.  
  306.                 For Each s As String In lstHeaders
  307.                     Export_WriteLine(s)
  308.                 Next
  309.  
  310.                 textWriter.WriteLine()
  311.                 textWriter.WriteLine()
  312.             End If
  313.         End Sub
  314.  
  315.         Private Sub Export_TableRows()
  316.             Dim dicTables As Dictionary(Of String, String) = Export_GetTablesToBeExported()
  317.             _totalTables = dicTables.Count
  318.  
  319.             If ExportInfo.ExportTableStructure OrElse ExportInfo.ExportRows Then
  320.                 If ExportProgressChanged IsNot Nothing Then timerReport.Start()
  321.  
  322.                 For Each kvTable As KeyValuePair(Of String, String) In dicTables
  323.                     If stopProcess Then Return
  324.                     Dim tableName As String = kvTable.Key
  325.                     Dim selectSQL As String = kvTable.Value
  326.                     Dim exclude As Boolean = Export_ThisTableIsExcluded(tableName)
  327.  
  328.                     If exclude Then
  329.                         Continue For
  330.                     End If
  331.  
  332.                     _currentTableName = tableName
  333.                     _currentTableIndex = _currentTableIndex + 1
  334.                     _totalRowsInCurrentTable = _database.Tables(tableName).TotalRows
  335.                     If ExportInfo.ExportTableStructure Then Export_TableStructure(tableName)
  336.                     If ExportInfo.ExportRows Then Export_Rows(tableName, selectSQL)
  337.                 Next
  338.             End If
  339.         End Sub
  340.  
  341.         Private Function Export_ThisTableIsExcluded(ByVal tableName As String) As Boolean
  342.             Dim tableNameLower As String = tableName.ToLower()
  343.  
  344.             For Each blacklistedTable As String In ExportInfo.ExcludeTables
  345.                 If blacklistedTable.ToLower() = tableNameLower Then Return True
  346.             Next
  347.  
  348.             Return False
  349.         End Function
  350.  
  351.         Private Sub Export_TableStructure(ByVal tableName As String)
  352.             If stopProcess Then Return
  353.             Export_WriteComment("")
  354.             Export_WriteComment(String.Format("Definition of {0}", tableName))
  355.             Export_WriteComment("")
  356.             textWriter.WriteLine()
  357.             If ExportInfo.AddDropTable Then Export_WriteLine(String.Format("DROP TABLE IF EXISTS `{0}`;", tableName))
  358.  
  359.             If ExportInfo.ResetAutoIncrement Then
  360.                 Export_WriteLine(_database.Tables(tableName).CreateTableSqlWithoutAutoIncrement)
  361.             Else
  362.                 Export_WriteLine(_database.Tables(tableName).CreateTableSql)
  363.             End If
  364.  
  365.             textWriter.WriteLine()
  366.             textWriter.Flush()
  367.         End Sub
  368.  
  369.         Private Function Export_GetTablesToBeExported() As Dictionary(Of String, String)
  370.             Dim dic = New Dictionary(Of String, String)()
  371.  
  372.             If ExportInfo.TablesToBeExportedDic Is Nothing OrElse ExportInfo.TablesToBeExportedDic.Count = 0 Then
  373.  
  374.                 For Each table As MySqlTable In _database.Tables
  375.                     dic(table.Name) = String.Format("SELECT * FROM `{0}`;", table.Name)
  376.                 Next
  377.             Else
  378.  
  379.                 For Each kv As KeyValuePair(Of String, String) In ExportInfo.TablesToBeExportedDic
  380.  
  381.                     For Each kv2 In _database.Tables
  382.  
  383.                         If kv2.Name = kv.Key Then
  384.                             dic(kv.Key) = kv.Value
  385.                             Continue For
  386.                         End If
  387.                     Next
  388.                 Next
  389.             End If
  390.  
  391.             Dim dic2 As Dictionary(Of String, String) = New Dictionary(Of String, String)()
  392.  
  393.             For Each kv In dic
  394.                 dic2(kv.Key) = _database.Tables(kv.Key).CreateTableSql
  395.             Next
  396.  
  397.             Dim lst = Export_ReArrangeDependencies(dic2, "foreign key", "`")
  398.             dic2.Clear()
  399.  
  400.             For Each tbname In lst
  401.                 dic2.Add(tbname, dic(tbname))
  402.             Next
  403.  
  404.             Return dic2
  405.         End Function
  406.  
  407.         Private Function Export_ReArrangeDependencies(ByVal dic1 As Dictionary(Of String, String), ByVal splitKeyword As String, ByVal keyNameWrapper As String) As List(Of String)
  408.             Dim lst As List(Of String) = New List(Of String)()
  409.             Dim requireLoop As Boolean = True
  410.  
  411.             While requireLoop
  412.                 requireLoop = False
  413.  
  414.                 For Each kv In dic1
  415.                     If lst.Contains(kv.Key) Then Continue For
  416.                     Dim allReferencedAdded As Boolean = True
  417.                     Dim createSql As String = kv.Value.ToLower()
  418.                     Dim referenceInfo As String = ""
  419.                     Dim referenceTaken As Boolean = False
  420.  
  421.                     If splitKeyword IsNot Nothing AndAlso splitKeyword <> "" Then
  422.  
  423.                         If createSql.Contains(String.Format(" {0} ", splitKeyword)) Then
  424.                             Dim sa As String() = createSql.Split(New String() {String.Format(" {0} ", splitKeyword)}, StringSplitOptions.RemoveEmptyEntries)
  425.                             referenceInfo = sa(sa.Length - 1)
  426.                             referenceTaken = True
  427.                         End If
  428.                     End If
  429.  
  430.                     If Not referenceTaken Then referenceInfo = createSql
  431.  
  432.                     For Each kv2 In dic1
  433.                         If kv.Key = kv2.Key Then Continue For
  434.                         If lst.Contains(kv2.Key) Then Continue For
  435.                         Dim _thisTBname As String = String.Format("{0}{1}{0}", keyNameWrapper, kv2.Key.ToLower())
  436.  
  437.                         If referenceInfo.Contains(_thisTBname) Then
  438.                             allReferencedAdded = False
  439.                             Exit For
  440.                         End If
  441.                     Next
  442.  
  443.                     If allReferencedAdded Then
  444.  
  445.                         If Not lst.Contains(kv.Key) Then
  446.                             lst.Add(kv.Key)
  447.                             requireLoop = True
  448.                             Exit For
  449.                         End If
  450.                     End If
  451.                 Next
  452.             End While
  453.  
  454.             For Each kv In dic1
  455.  
  456.                 If Not lst.Contains(kv.Key) Then
  457.                     lst.Add(kv.Key)
  458.                 End If
  459.             Next
  460.  
  461.             Return lst
  462.         End Function
  463.  
  464.         Private Sub Export_Rows(ByVal tableName As String, ByVal selectSQL As String)
  465.             Export_WriteComment("")
  466.             Export_WriteComment(String.Format("Dumping data for table {0}", tableName))
  467.             Export_WriteComment("")
  468.             textWriter.WriteLine()
  469.             Export_WriteLine(String.Format("/*!40000 ALTER TABLE `{0}` DISABLE KEYS */;", tableName))
  470.             If ExportInfo.WrapWithinTransaction Then Export_WriteLine("START TRANSACTION;")
  471.             Export_RowsData(tableName, selectSQL)
  472.             If ExportInfo.WrapWithinTransaction Then Export_WriteLine("COMMIT;")
  473.             Export_WriteLine(String.Format("/*!40000 ALTER TABLE `{0}` ENABLE KEYS */;", tableName))
  474.             textWriter.WriteLine()
  475.             textWriter.Flush()
  476.         End Sub
  477.  
  478.         Private Sub Export_RowsData(ByVal tableName As String, ByVal selectSQL As String)
  479.             _currentRowIndexInCurrentTable = 0L
  480.  
  481.             If ExportInfo.RowsExportMode = RowsDataExportMode.Insert OrElse ExportInfo.RowsExportMode = RowsDataExportMode.InsertIgnore OrElse ExportInfo.RowsExportMode = RowsDataExportMode.Replace Then
  482.                 Export_RowsData_Insert_Ignore_Replace(tableName, selectSQL)
  483.             ElseIf ExportInfo.RowsExportMode = RowsDataExportMode.OnDuplicateKeyUpdate Then
  484.                 Export_RowsData_OnDuplicateKeyUpdate(tableName, selectSQL)
  485.             ElseIf ExportInfo.RowsExportMode = RowsDataExportMode.Update Then
  486.                 Export_RowsData_Update(tableName, selectSQL)
  487.             End If
  488.         End Sub
  489.  
  490.         Private Sub Export_RowsData_Insert_Ignore_Replace(ByVal tableName As String, ByVal selectSQL As String)
  491.             Dim table As MySqlTable = _database.Tables(tableName)
  492.             Command.CommandText = selectSQL
  493.             Dim rdr As MySqlDataReader = Command.ExecuteReader()
  494.             Dim insertStatementHeader As String = Nothing
  495.             Dim sb = New StringBuilder(CInt(ExportInfo.MaxSqlLength))
  496.  
  497.             While rdr.Read()
  498.                 If stopProcess Then Return
  499.                 _currentRowIndexInAllTable = _currentRowIndexInAllTable + 1
  500.                 _currentRowIndexInCurrentTable = _currentRowIndexInCurrentTable + 1
  501.  
  502.                 If insertStatementHeader Is Nothing Then
  503.                     insertStatementHeader = Export_GetInsertStatementHeader(ExportInfo.RowsExportMode, tableName, rdr)
  504.                 End If
  505.  
  506.                 Dim sqlDataRow As String = Export_GetValueString(rdr, table)
  507.  
  508.                 If sb.Length = 0 Then
  509.                     sb.AppendLine(insertStatementHeader)
  510.                     sb.Append(sqlDataRow)
  511.                 ElseIf CLng(sb.Length) + CLng(sqlDataRow.Length) < ExportInfo.MaxSqlLength Then
  512.                     sb.AppendLine(",")
  513.                     sb.Append(sqlDataRow)
  514.                 Else
  515.                     sb.AppendFormat(";")
  516.                     Export_WriteLine(sb.ToString())
  517.                     textWriter.Flush()
  518.                     sb = New StringBuilder(CInt(ExportInfo.MaxSqlLength))
  519.                     sb.AppendLine(insertStatementHeader)
  520.                     sb.Append(sqlDataRow)
  521.                 End If
  522.             End While
  523.  
  524.             rdr.Close()
  525.  
  526.             If sb.Length > 0 Then
  527.                 sb.Append(";")
  528.             End If
  529.  
  530.             Export_WriteLine(sb.ToString())
  531.             textWriter.Flush()
  532.             sb = Nothing
  533.         End Sub
  534.  
  535.         Private Sub Export_RowsData_OnDuplicateKeyUpdate(ByVal tableName As String, ByVal selectSQL As String)
  536.             Dim table As MySqlTable = _database.Tables(tableName)
  537.             Dim allPrimaryField As Boolean = True
  538.  
  539.             For Each col In table.Columns
  540.  
  541.                 If Not col.IsPrimaryKey Then
  542.                     allPrimaryField = False
  543.                     Exit For
  544.                 End If
  545.             Next
  546.  
  547.             Command.CommandText = selectSQL
  548.             Dim rdr As MySqlDataReader = Command.ExecuteReader()
  549.  
  550.             While rdr.Read()
  551.                 If stopProcess Then Return
  552.                 _currentRowIndexInAllTable = _currentRowIndexInAllTable + 1
  553.                 _currentRowIndexInCurrentTable = _currentRowIndexInCurrentTable + 1
  554.                 Dim sb As StringBuilder = New StringBuilder()
  555.  
  556.                 If allPrimaryField Then
  557.                     sb.Append(Export_GetInsertStatementHeader(RowsDataExportMode.InsertIgnore, tableName, rdr))
  558.                     sb.Append(Export_GetValueString(rdr, table))
  559.                 Else
  560.                     sb.Append(Export_GetInsertStatementHeader(RowsDataExportMode.Insert, tableName, rdr))
  561.                     sb.Append(Export_GetValueString(rdr, table))
  562.                     sb.Append(" ON DUPLICATE KEY UPDATE ")
  563.                     Export_GetUpdateString(rdr, table, sb)
  564.                 End If
  565.  
  566.                 sb.Append(";")
  567.                 Export_WriteLine(sb.ToString())
  568.                 textWriter.Flush()
  569.             End While
  570.  
  571.             rdr.Close()
  572.         End Sub
  573.  
  574.         Private Sub Export_RowsData_Update(ByVal tableName As String, ByVal selectSQL As String)
  575.             Dim table As MySqlTable = _database.Tables(tableName)
  576.             Dim allPrimaryField As Boolean = True
  577.  
  578.             For Each col In table.Columns
  579.  
  580.                 If Not col.IsPrimaryKey Then
  581.                     allPrimaryField = False
  582.                     Exit For
  583.                 End If
  584.             Next
  585.  
  586.             If allPrimaryField Then Return
  587.             Dim allNonPrimaryField As Boolean = True
  588.  
  589.             For Each col In table.Columns
  590.  
  591.                 If col.IsPrimaryKey Then
  592.                     allNonPrimaryField = False
  593.                     Exit For
  594.                 End If
  595.             Next
  596.  
  597.             If allNonPrimaryField Then Return
  598.             Command.CommandText = selectSQL
  599.             Dim rdr As MySqlDataReader = Command.ExecuteReader()
  600.  
  601.             While rdr.Read()
  602.                 If stopProcess Then Return
  603.                 _currentRowIndexInAllTable = _currentRowIndexInAllTable + 1
  604.                 _currentRowIndexInCurrentTable = _currentRowIndexInCurrentTable + 1
  605.                 Dim sb As StringBuilder = New StringBuilder()
  606.                 sb.Append("UPDATE `")
  607.                 sb.Append(tableName)
  608.                 sb.Append("` SET ")
  609.                 Export_GetUpdateString(rdr, table, sb)
  610.                 sb.Append(" WHERE ")
  611.                 Export_GetConditionString(rdr, table, sb)
  612.                 sb.Append(";")
  613.                 Export_WriteLine(sb.ToString())
  614.                 textWriter.Flush()
  615.             End While
  616.  
  617.             rdr.Close()
  618.         End Sub
  619.  
  620.         Private Function Export_GetInsertStatementHeader(ByVal rowsExportMode As RowsDataExportMode, ByVal tableName As String, ByVal rdr As MySqlDataReader) As String
  621.             Dim sb As StringBuilder = New StringBuilder()
  622.  
  623.             If rowsExportMode = RowsDataExportMode.Insert Then
  624.                 sb.Append("INSERT INTO `")
  625.             ElseIf rowsExportMode = RowsDataExportMode.InsertIgnore Then
  626.                 sb.Append("INSERT IGNORE INTO `")
  627.             ElseIf rowsExportMode = RowsDataExportMode.Replace Then
  628.                 sb.Append("REPLACE INTO `")
  629.             End If
  630.  
  631.             sb.Append(tableName)
  632.             sb.Append("`(")
  633.  
  634.             For i As Integer = 0 To rdr.FieldCount - 1
  635.                 Dim _colname As String = rdr.GetName(i)
  636.                 If _database.Tables(tableName).Columns(_colname).IsGeneratedColumn Then Continue For
  637.                 If i > 0 Then sb.Append(",")
  638.                 sb.Append("`")
  639.                 sb.Append(rdr.GetName(i))
  640.                 sb.Append("`")
  641.             Next
  642.  
  643.             sb.Append(") VALUES")
  644.             Return sb.ToString()
  645.         End Function
  646.  
  647.         Private Function Export_GetValueString(ByVal rdr As MySqlDataReader, ByVal table As MySqlTable) As String
  648.             Dim sb As StringBuilder = New StringBuilder()
  649.  
  650.             For i As Integer = 0 To rdr.FieldCount - 1
  651.                 Dim columnName As String = rdr.GetName(i)
  652.                 If table.Columns(columnName).IsGeneratedColumn Then Continue For
  653.  
  654.                 If sb.Length = 0 Then
  655.                     sb.AppendFormat("(")
  656.                 Else
  657.                     sb.AppendFormat(",")
  658.                 End If
  659.  
  660.                 Dim ob As Object = rdr(i)
  661.                 Dim col = table.Columns(columnName)
  662.                 sb.Append(QueryExpress.ConvertToSqlFormat(ob, True, True, col, ExportInfo.BlobExportMode))
  663.             Next
  664.  
  665.             sb.AppendFormat(")")
  666.             Return sb.ToString()
  667.         End Function
  668.  
  669.         Private Sub Export_GetUpdateString(ByVal rdr As MySqlDataReader, ByVal table As MySqlTable, ByVal sb As StringBuilder)
  670.             Dim isFirst As Boolean = True
  671.  
  672.             For i As Integer = 0 To rdr.FieldCount - 1
  673.                 Dim colName As String = rdr.GetName(i)
  674.                 Dim col = table.Columns(colName)
  675.  
  676.                 If Not col.IsPrimaryKey Then
  677.  
  678.                     If isFirst Then
  679.                         isFirst = False
  680.                     Else
  681.                         sb.Append(",")
  682.                     End If
  683.  
  684.                     sb.Append("`")
  685.                     sb.Append(colName)
  686.                     sb.Append("`=")
  687.                     sb.Append(QueryExpress.ConvertToSqlFormat(rdr(i), True, True, col, ExportInfo.BlobExportMode))
  688.                 End If
  689.             Next
  690.         End Sub
  691.  
  692.         Private Sub Export_GetConditionString(ByVal rdr As MySqlDataReader, ByVal table As MySqlTable, ByVal sb As StringBuilder)
  693.             Dim isFirst As Boolean = True
  694.  
  695.             For i As Integer = 0 To rdr.FieldCount - 1
  696.                 Dim colName As String = rdr.GetName(i)
  697.                 Dim col = table.Columns(colName)
  698.  
  699.                 If col.IsPrimaryKey Then
  700.  
  701.                     If isFirst Then
  702.                         isFirst = False
  703.                     Else
  704.                         sb.Append(" and ")
  705.                     End If
  706.  
  707.                     sb.Append("`")
  708.                     sb.Append(colName)
  709.                     sb.Append("`=")
  710.                     sb.Append(QueryExpress.ConvertToSqlFormat(rdr(i), True, True, col, ExportInfo.BlobExportMode))
  711.                 End If
  712.             Next
  713.         End Sub
  714.  
  715.         Private Sub Export_Procedures()
  716.             If Not ExportInfo.ExportProcedures OrElse _database.Procedures.Count = 0 Then Return
  717.             Export_WriteComment("")
  718.             Export_WriteComment("Dumping procedures")
  719.             Export_WriteComment("")
  720.             textWriter.WriteLine()
  721.  
  722.             For Each procedure As MySqlProcedure In _database.Procedures
  723.                 If stopProcess Then Return
  724.                 If procedure.CreateProcedureSQLWithoutDefiner.Trim().Length = 0 OrElse procedure.CreateProcedureSQL.Trim().Length = 0 Then Continue For
  725.                 Export_WriteLine(String.Format("DROP PROCEDURE IF EXISTS `{0}`;", procedure.Name))
  726.                 Export_WriteLine("DELIMITER " & ExportInfo.ScriptsDelimiter)
  727.  
  728.                 If ExportInfo.ExportRoutinesWithoutDefiner Then
  729.                     Export_WriteLine(procedure.CreateProcedureSQLWithoutDefiner & " " + ExportInfo.ScriptsDelimiter)
  730.                 Else
  731.                     Export_WriteLine(procedure.CreateProcedureSQL & " " + ExportInfo.ScriptsDelimiter)
  732.                 End If
  733.  
  734.                 Export_WriteLine("DELIMITER ;")
  735.                 textWriter.WriteLine()
  736.             Next
  737.  
  738.             textWriter.Flush()
  739.         End Sub
  740.  
  741.         Private Sub Export_Functions()
  742.             If Not ExportInfo.ExportFunctions OrElse _database.Functions.Count = 0 Then Return
  743.             Export_WriteComment("")
  744.             Export_WriteComment("Dumping functions")
  745.             Export_WriteComment("")
  746.             textWriter.WriteLine()
  747.  
  748.             For Each [function] As MySqlFunction In _database.Functions
  749.                 If stopProcess Then Return
  750.                 If [function].CreateFunctionSQL.Trim().Length = 0 OrElse [function].CreateFunctionSQLWithoutDefiner.Trim().Length = 0 Then Continue For
  751.                 Export_WriteLine(String.Format("DROP FUNCTION IF EXISTS `{0}`;", [function].Name))
  752.                 Export_WriteLine("DELIMITER " & ExportInfo.ScriptsDelimiter)
  753.  
  754.                 If ExportInfo.ExportRoutinesWithoutDefiner Then
  755.                     Export_WriteLine([function].CreateFunctionSQLWithoutDefiner & " " + ExportInfo.ScriptsDelimiter)
  756.                 Else
  757.                     Export_WriteLine([function].CreateFunctionSQL & " " + ExportInfo.ScriptsDelimiter)
  758.                 End If
  759.  
  760.                 Export_WriteLine("DELIMITER ;")
  761.                 textWriter.WriteLine()
  762.             Next
  763.  
  764.             textWriter.Flush()
  765.         End Sub
  766.  
  767.         Private Sub Export_Views()
  768.             If Not ExportInfo.ExportViews OrElse _database.Views.Count = 0 Then Return
  769.             Dim dicView_Create As Dictionary(Of String, String) = New Dictionary(Of String, String)()
  770.  
  771.             For Each view In _database.Views
  772.                 dicView_Create(view.Name) = view.CreateViewSQL
  773.             Next
  774.  
  775.             Dim lst = Export_ReArrangeDependencies(dicView_Create, Nothing, "`")
  776.             Export_WriteComment("")
  777.             Export_WriteComment("Dumping views")
  778.             Export_WriteComment("")
  779.             textWriter.WriteLine()
  780.  
  781.             For Each viewname In lst
  782.                 If stopProcess Then Return
  783.                 Dim view = _database.Views(viewname)
  784.                 If view.CreateViewSQL.Trim().Length = 0 OrElse view.CreateViewSQLWithoutDefiner.Trim().Length = 0 Then Continue For
  785.                 Export_WriteLine(String.Format("DROP TABLE IF EXISTS `{0}`;", view.Name))
  786.                 Export_WriteLine(String.Format("DROP VIEW IF EXISTS `{0}`;", view.Name))
  787.  
  788.                 If ExportInfo.ExportRoutinesWithoutDefiner Then
  789.                     Export_WriteLine(view.CreateViewSQLWithoutDefiner)
  790.                 Else
  791.                     Export_WriteLine(view.CreateViewSQL)
  792.                 End If
  793.  
  794.                 textWriter.WriteLine()
  795.             Next
  796.  
  797.             textWriter.WriteLine()
  798.             textWriter.Flush()
  799.         End Sub
  800.  
  801.         Private Sub Export_Events()
  802.             If Not ExportInfo.ExportEvents OrElse _database.Events.Count = 0 Then Return
  803.             Export_WriteComment("")
  804.             Export_WriteComment("Dumping events")
  805.             Export_WriteComment("")
  806.             textWriter.WriteLine()
  807.  
  808.             For Each e As MySqlEvent In _database.Events
  809.                 If stopProcess Then Return
  810.                 If e.CreateEventSql.Trim().Length = 0 OrElse e.CreateEventSqlWithoutDefiner.Trim().Length = 0 Then Continue For
  811.                 Export_WriteLine(String.Format("DROP EVENT IF EXISTS `{0}`;", e.Name))
  812.                 Export_WriteLine("DELIMITER " & ExportInfo.ScriptsDelimiter)
  813.  
  814.                 If ExportInfo.ExportRoutinesWithoutDefiner Then
  815.                     Export_WriteLine(e.CreateEventSqlWithoutDefiner & " " + ExportInfo.ScriptsDelimiter)
  816.                 Else
  817.                     Export_WriteLine(e.CreateEventSql & " " + ExportInfo.ScriptsDelimiter)
  818.                 End If
  819.  
  820.                 Export_WriteLine("DELIMITER ;")
  821.                 textWriter.WriteLine()
  822.             Next
  823.  
  824.             textWriter.Flush()
  825.         End Sub
  826.  
  827.         Private Sub Export_Triggers()
  828.             If Not ExportInfo.ExportTriggers OrElse _database.Triggers.Count = 0 Then Return
  829.             Export_WriteComment("")
  830.             Export_WriteComment("Dumping triggers")
  831.             Export_WriteComment("")
  832.             textWriter.WriteLine()
  833.  
  834.             For Each trigger As MySqlTrigger In _database.Triggers
  835.                 If stopProcess Then Return
  836.                 If trigger.CreateTriggerSQL.Trim().Length = 0 OrElse trigger.CreateTriggerSQLWithoutDefiner.Trim().Length = 0 Then Continue For
  837.                 Export_WriteLine(String.Format("DROP TRIGGER /*!50030 IF EXISTS */ `{0}`;", trigger.Name))
  838.                 Export_WriteLine("DELIMITER " & ExportInfo.ScriptsDelimiter)
  839.  
  840.                 If ExportInfo.ExportRoutinesWithoutDefiner Then
  841.                     Export_WriteLine(trigger.CreateTriggerSQLWithoutDefiner & " " + ExportInfo.ScriptsDelimiter)
  842.                 Else
  843.                     Export_WriteLine(trigger.CreateTriggerSQL & " " + ExportInfo.ScriptsDelimiter)
  844.                 End If
  845.  
  846.                 Export_WriteLine("DELIMITER ;")
  847.                 textWriter.WriteLine()
  848.             Next
  849.  
  850.             textWriter.Flush()
  851.         End Sub
  852.  
  853.         Private Sub Export_DocumentFooter()
  854.             textWriter.WriteLine()
  855.             Dim lstFooters As List(Of String) = ExportInfo.GetDocumentFooters()
  856.  
  857.             If lstFooters.Count > 0 Then
  858.  
  859.                 For Each s As String In lstFooters
  860.                     Export_WriteLine(s)
  861.                 Next
  862.             End If
  863.  
  864.             timeEnd = DateTime.Now
  865.  
  866.             If ExportInfo.RecordDumpTime Then
  867.                 Dim ts As TimeSpan = timeEnd - timeStart
  868.                 textWriter.WriteLine()
  869.                 textWriter.WriteLine()
  870.                 Export_WriteComment(String.Format("Dump completed on {0}", timeEnd.ToString("yyyy-MM-dd HH:mm:ss")))
  871.                 Export_WriteComment(String.Format("Total time: {0}:{1}:{2}:{3}:{4} (d:h:m:s:ms)", ts.Days, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds))
  872.             End If
  873.  
  874.             textWriter.Flush()
  875.         End Sub
  876.  
  877.         Private Sub Export_WriteComment(ByVal text As String)
  878.             Export_WriteLine(String.Format("-- {0}", text))
  879.         End Sub
  880.  
  881.         Private Sub Export_WriteLine(ByVal text As String)
  882.             textWriter.WriteLine(text)
  883.         End Sub
  884.  
  885.         Public Sub ImportFromString(ByVal sqldumptext As String)
  886.             Using ms As MemoryStream = New MemoryStream()
  887.  
  888.                 Using thisWriter As StreamWriter = New StreamWriter(ms)
  889.                     thisWriter.Write(sqldumptext)
  890.                     thisWriter.Flush()
  891.                     ms.Position = 0L
  892.                     ImportFromMemoryStream(ms)
  893.                 End Using
  894.             End Using
  895.         End Sub
  896.  
  897.         Public Sub ImportFromFile(ByVal filePath As String)
  898.             Dim fi As System.IO.FileInfo = New FileInfo(filePath)
  899.  
  900.             Using tr As TextReader = New StreamReader(filePath)
  901.                 ImportFromTextReaderStream(tr, fi)
  902.             End Using
  903.         End Sub
  904.  
  905.         Public Sub ImportFromTextReader(ByVal tr As TextReader)
  906.             ImportFromTextReaderStream(tr, Nothing)
  907.         End Sub
  908.  
  909.         Public Sub ImportFromMemoryStream(ByVal ms As MemoryStream)
  910.             ms.Position = 0
  911.             _totalBytes = ms.Length
  912.             textReader = New StreamReader(ms)
  913.             Import_Start()
  914.         End Sub
  915.  
  916.         Private Sub ImportFromTextReaderStream(ByVal tr As TextReader, ByVal fileInfo As FileInfo)
  917.             If fileInfo IsNot Nothing Then
  918.                 _totalBytes = fileInfo.Length
  919.             Else
  920.                 _totalBytes = 0L
  921.             End If
  922.  
  923.             textReader = tr
  924.             Import_Start()
  925.         End Sub
  926.  
  927.         Private Sub Import_Start()
  928.             Import_InitializeVariables()
  929.             Dim line As String = ""
  930.  
  931.             While line IsNot Nothing
  932.  
  933.                 If stopProcess Then
  934.                     processCompletionType = ProcessEndType.Cancelled
  935.                     Exit While
  936.                 End If
  937.  
  938.                 Try
  939.                     line = Import_GetLine()
  940.                     If line Is Nothing Then Exit While
  941.                     If line.Length = 0 Then Continue While
  942.                     Import_ProcessLine(line)
  943.                 Catch ex As Exception
  944.                     line = ""
  945.                     _lastError = ex
  946.                     _lastErrorSql = _sbImport.ToString()
  947.  
  948.                     If Not String.IsNullOrEmpty(ImportInfo.ErrorLogFile) Then
  949.                         File.AppendAllText(ImportInfo.ErrorLogFile, ex.ToString() & Environment.NewLine & Environment.NewLine)
  950.                     End If
  951.  
  952.                     _sbImport = New StringBuilder()
  953.  
  954.                     If ImportInfo.IgnoreSqlError Then
  955.                     Else
  956.                         StopAllProcess()
  957.                         Throw
  958.                     End If
  959.                 End Try
  960.             End While
  961.  
  962.             ReportEndProcess()
  963.         End Sub
  964.  
  965.         Private Sub Import_InitializeVariables()
  966.             If Command Is Nothing Then
  967.                 Throw New Exception("MySqlCommand is not initialized. Object not set to an instance of an object.")
  968.             End If
  969.  
  970.             If Command.Connection Is Nothing Then
  971.                 Throw New Exception("MySqlCommand.Connection is not initialized. Object not set to an instance of an object.")
  972.             End If
  973.  
  974.             If Command.Connection.State <> System.Data.ConnectionState.Open Then
  975.                 Throw New Exception("MySqlCommand.Connection is not opened.")
  976.             End If
  977.  
  978.             stopProcess = False
  979.             _lastError = Nothing
  980.             timeStart = DateTime.Now
  981.             _currentBytes = 0L
  982.             _sbImport = New StringBuilder()
  983.             _mySqlScript = New MySqlScript(Command.Connection)
  984.             currentProcess = ProcessType.Import
  985.             processCompletionType = ProcessEndType.Complete
  986.             _delimiter = ";"
  987.             _lastErrorSql = ""
  988.             If ImportProgressChanged IsNot Nothing Then timerReport.Start()
  989.  
  990.  
  991.         End Sub
  992.  
  993.         Private Function Import_GetLine() As String
  994.             Dim line As String = textReader.ReadLine()
  995.             If line Is Nothing Then Return Nothing
  996.  
  997.             If ImportProgressChanged IsNot Nothing Then
  998.                 _currentBytes = _currentBytes + CLng(line.Length)
  999.             End If
  1000.  
  1001.             line = line.Trim()
  1002.  
  1003.             If Import_IsEmptyLine(line) Then
  1004.                 Return String.Empty
  1005.             End If
  1006.  
  1007.             Return line
  1008.         End Function
  1009.  
  1010.         Private Sub Import_ProcessLine(ByVal line As String)
  1011.             Dim nextAction As NextImportAction = Import_AnalyseNextAction(line)
  1012.  
  1013.             Select Case nextAction
  1014.                 Case NextImportAction.Ignore
  1015.                 Case NextImportAction.AppendLine
  1016.                     Import_AppendLine(line)
  1017.                 Case NextImportAction.ChangeDelimiter
  1018.                     Import_ChangeDelimiter(line)
  1019.                 Case NextImportAction.AppendLineAndExecute
  1020.                     Import_AppendLineAndExecute(line)
  1021.                 Case Else
  1022.             End Select
  1023.         End Sub
  1024.  
  1025.         Private Function Import_AnalyseNextAction(ByVal line As String) As NextImportAction
  1026.             If line Is Nothing Then Return NextImportAction.Ignore
  1027.             If line = String.Empty Then Return NextImportAction.Ignore
  1028.             If line.StartsWith("DELIMITER ", StringComparison.OrdinalIgnoreCase) Then Return NextImportAction.ChangeDelimiter
  1029.             If line.EndsWith(_delimiter) Then Return NextImportAction.AppendLineAndExecute
  1030.             Return NextImportAction.AppendLine
  1031.         End Function
  1032.  
  1033.         Private Sub Import_AppendLine(ByVal line As String)
  1034.             _sbImport.AppendLine(line)
  1035.         End Sub
  1036.  
  1037.         Private Sub Import_ChangeDelimiter(ByVal line As String)
  1038.             Dim nextDelimiter As String = line.Substring(9)
  1039.             _delimiter = nextDelimiter.Replace(" ", String.Empty)
  1040.         End Sub
  1041.  
  1042.         Private Sub Import_AppendLineAndExecute(ByVal line As String)
  1043.             _sbImport.AppendLine(line)
  1044.             Dim _importQuery As String = _sbImport.ToString()
  1045.             _mySqlScript.Query = _importQuery
  1046.             _mySqlScript.Delimiter = _delimiter
  1047.             _mySqlScript.Execute()
  1048.             _sbImport = New StringBuilder()
  1049.             GC.Collect()
  1050.         End Sub
  1051.  
  1052.         Private Function Import_IsEmptyLine(ByVal line As String) As Boolean
  1053.             If line Is Nothing Then Return True
  1054.             If line = String.Empty Then Return True
  1055.             If line.Length = 0 Then Return True
  1056.             If line.StartsWith("--") Then Return True
  1057.             If line = Environment.NewLine Then Return True
  1058.             If line = vbCr Then Return True
  1059.             If line = vbLf Then Return True
  1060.             Return False
  1061.         End Function
  1062.  
  1063.         Private Sub ReportEndProcess()
  1064.             timeEnd = DateTime.Now
  1065.             StopAllProcess()
  1066.  
  1067.             If currentProcess = ProcessType.Export Then
  1068.                 ReportProgress()
  1069.  
  1070.                 If ExportCompleted IsNot Nothing Then
  1071.                     Dim arg As ExportCompleteArgs = New ExportCompleteArgs(timeStart, timeEnd, processCompletionType, _lastError)
  1072.                     ExportCompleted(Me, arg)
  1073.                 End If
  1074.             ElseIf currentProcess = ProcessType.Import Then
  1075.                 _currentBytes = _totalBytes
  1076.                 ReportProgress()
  1077.  
  1078.                 If ImportCompleted IsNot Nothing Then
  1079.                     Dim arg As ImportCompleteArgs = New ImportCompleteArgs()
  1080.                     ImportCompleted(Me, arg)
  1081.                 End If
  1082.             End If
  1083.         End Sub
  1084.  
  1085.         Private Sub timerReport_Elapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs)
  1086.             ReportProgress()
  1087.         End Sub
  1088.  
  1089.         Private Sub ReportProgress()
  1090.             If currentProcess = ProcessType.Export Then
  1091.  
  1092.                 If ExportProgressChanged IsNot Nothing Then
  1093.                     Dim arg As ExportProgressArgs = New ExportProgressArgs(_currentTableName, _totalRowsInCurrentTable, _totalRowsInAllTables, _currentRowIndexInCurrentTable, _currentRowIndexInAllTable, _totalTables, _currentTableIndex)
  1094.                     ExportProgressChanged(Me, arg)
  1095.                 End If
  1096.             ElseIf currentProcess = ProcessType.Import Then
  1097.  
  1098.                 If ImportProgressChanged IsNot Nothing Then
  1099.                     Dim arg As ImportProgressArgs = New ImportProgressArgs(_currentBytes, _totalBytes)
  1100.                     ImportProgressChanged(Me, arg)
  1101.  
  1102.                 End If
  1103.             End If
  1104.         End Sub
  1105.  
  1106.         Public Sub StopAllProcess()
  1107.             stopProcess = True
  1108.             timerReport.[Stop]()
  1109.         End Sub
  1110.  
  1111.         Public Sub Dispose()
  1112.             Try
  1113.                 _database.Dispose()
  1114.             Catch
  1115.             End Try
  1116.  
  1117.             Try
  1118.                 _server = Nothing
  1119.             Catch
  1120.             End Try
  1121.  
  1122.             Try
  1123.                 _mySqlScript = Nothing
  1124.             Catch
  1125.             End Try
  1126.         End Sub
  1127.  
  1128.         Private Class CSharpImpl
  1129.             <Obsolete("Please refactor calling code to use normal Visual Basic assignment")>
  1130.             Shared Function __Assign(Of T)(ByRef target As T, value As T) As T
  1131.                 target = value
  1132.                 Return value
  1133.             End Function
  1134.         End Class
  1135.  
  1136.         Public Sub Dispose1() Implements IDisposable.Dispose
  1137.  
  1138.         End Sub
  1139.     End Class
  1140. End Namespace
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement