OA_Optimizer.bas 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. Option Compare Database
  2. Option Explicit
  3. '****
  4. '*
  5. '* Optimizer for Open Access: only import/export objects which were updated since last import/export
  6. '*
  7. '****
  8. ' *** activates the optimizer
  9. Private p_optimizer As Boolean
  10. 'needs_export
  11. Public Const NoExportNeeded = 0
  12. Public Const MissingFiles = 1
  13. Public Const UpdateNeeded = 2
  14. Public Sub activate_optimizer()
  15. p_optimizer = True
  16. End Sub
  17. Public Function optimizer_activated()
  18. optimizer_activated = p_optimizer
  19. End Function
  20. '***
  21. '*** main methods
  22. Public Function needs_export(acType As Integer, name As String) As Integer
  23. ' a file needs to be export if it has been updated since last export, or if its source files are missing
  24. ' returns an integer (see constants)
  25. If Not files_exist_for(acType, name) Then
  26. needs_export = MissingFiles
  27. ElseIf get_last_update_date(acType, name) > get_sources_date() Then
  28. needs_export = UpdateNeeded
  29. Else
  30. needs_export = NoExportNeeded
  31. End If
  32. End Function
  33. Public Function get_last_update_date(ByVal acType As Integer, ByVal name As String)
  34. On Error GoTo err
  35. 'get the date of the last update of an object
  36. Select Case acType
  37. 'case table or query: get [DateUpdate] in MSysObjects
  38. Case acTable
  39. get_last_update_date = DFirst("DateUpdate", "MSysObjects", "([Type]=1 or [Type]=4 or [Type]=6) and [name]='" & name & "'")
  40. Case acQuery
  41. get_last_update_date = DFirst("DateUpdate", "MSysObjects", "[Type]=5 and [name]='" & name & "'")
  42. 'MSysObjects is not reliable for other objects,
  43. 'So we used the DateModified property:
  44. Case acForm
  45. get_last_update_date = CurrentProject.AllForms(name).DateModified
  46. Case acReport
  47. get_last_update_date = CurrentProject.AllReports(name).DateModified
  48. Case acMacro
  49. get_last_update_date = CurrentProject.AllMacros(name).DateModified
  50. Case acModule
  51. get_last_update_date = CurrentProject.AllModules(name).DateModified
  52. End Select
  53. Exit Function
  54. err:
  55. Debug.Print "get_last_update_date - erreur - " & acType & ", " & name & ": " & err.Description
  56. get_last_update_date = #1/1/1900#
  57. End Function
  58. '*** displays modified (dirties) objects
  59. Public Function list_to_export(acType As Integer)
  60. ' returns a list (string with ';' separator) of the objects wich will be exported
  61. Dim sources_date As Date
  62. list_to_export = ""
  63. sources_date = get_sources_date()
  64. Dim rs As DAO.Recordset
  65. Set rs = CurrentDb.OpenRecordset("SELECT * FROM MSysObjects WHERE " & msys_type_filter(acType) & ";", _
  66. dbOpenSnapshot)
  67. If rs.RecordCount = 0 Then GoTo emptylist
  68. rs.MoveFirst
  69. Do Until rs.EOF
  70. If Left$(rs![name], 4) <> "MSys" And _
  71. Left$(rs![name], 1) <> "~" Then
  72. If get_last_update_date(acType, rs![name]) > sources_date Or _
  73. Not files_exist_for(acType, rs![name]) Then
  74. If Len(list_to_export) > 0 Then
  75. list_to_export = list_to_export & ";" & rs![name]
  76. Else
  77. list_to_export = rs![name]
  78. End If
  79. End If
  80. End If
  81. rs.MoveNext
  82. Loop
  83. Exit Function
  84. emptylist:
  85. End Function
  86. Public Function msg_list_to_export() As String
  87. 'returns a formatted text listing all of the objects which were updated since last export of the sources
  88. Dim lstmod, obj_type_split, obj_type_label, obj_type_num As String
  89. Dim obj_type, objname As Variant
  90. msg_list_to_export = ""
  91. For Each obj_type In Split( _
  92. "tables|" & acTable & "," & _
  93. "queries|" & acQuery & "," & _
  94. "forms|" & acForm & "," & _
  95. "reports|" & acReport & "," & _
  96. "macros|" & acMacro & "," & _
  97. "modules|" & acModule _
  98. , "," _
  99. )
  100. obj_type_split = Split(obj_type, "|")
  101. obj_type_label = obj_type_split(0)
  102. obj_type_num = obj_type_split(1)
  103. lstmod = list_to_export(CInt(obj_type_num))
  104. If Len(lstmod) > 0 Then
  105. msg_list_to_export = msg_list_to_export & "> " & UCase(obj_type_label) & ":" & vbNewLine
  106. For Each objname In Split(lstmod, ";")
  107. msg_list_to_export = msg_list_to_export & objname
  108. msg_list_to_export = msg_list_to_export & ", "
  109. Next objname
  110. msg_list_to_export = Left(msg_list_to_export, Len(msg_list_to_export) - 2) & vbNewLine & vbNewLine
  111. End If
  112. Next obj_type
  113. End Function
  114. '******
  115. '*** sources_date is the date of the last export of the sources files
  116. Public Function get_sources_date() As Date
  117. ' get the registered sources date
  118. get_sources_date = CDate(oa_param("sources_date", "01/01/1900 00:00:00"))
  119. End Function
  120. Public Sub update_sources_date()
  121. ' update the sources date with Now()
  122. Dim new_val As String
  123. new_val = CStr(Now)
  124. Call update_oa_param("sources_date", CStr(Now))
  125. logger "update_sources_date", "DEBUG", "Source's date updated to " & new_val
  126. End Sub
  127. '*****
  128. '**** cleans sources or objects after differential import/export
  129. Public Function CleanDirs(Optional ByVal sim As Boolean = False)
  130. ' cleans the directories after a differential export
  131. ' returns a list of the deleted relative file paths (string with '|' separator)
  132. ' if 'sim' is set to True, doesn't process to the delete but still return the list
  133. CleanDirs = ""
  134. Dim source_path As String
  135. source_path = VCS_Dir.ProjectPath() & "source\"
  136. logger "CleanDirs", "INFO", "Optimizer ON: cleans the directories from " & source_path
  137. Dim rsSys As DAO.Recordset
  138. Dim sql As String
  139. sql = "SELECT name, type FROM MSysObjects;"
  140. Set rsSys = CurrentDb.OpenRecordset(sql, dbOpenSnapshot)
  141. Dim subdir, filename, objectname, obj_type_label As String
  142. Dim obj_type, obj_type_split As Variant
  143. Dim obj_type_num As Integer
  144. Dim oFSO As Scripting.FileSystemObject
  145. Dim oFld As Scripting.Folder
  146. Dim file As Scripting.file
  147. 'Instanciation du FSO
  148. Set oFSO = New Scripting.FileSystemObject
  149. For Each obj_type In Split( _
  150. "forms|" & acForm & "," & _
  151. "reports|" & acReport & "," & _
  152. "macros|" & acMacro & "," & _
  153. "modules|" & acModule _
  154. , "," _
  155. )
  156. obj_type_split = Split(obj_type, "|")
  157. obj_type_label = obj_type_split(0)
  158. obj_type_num = obj_type_split(1)
  159. subdir = source_path & obj_type_label
  160. If Not oFSO.FolderExists(subdir) Then GoTo next_obj_type
  161. Set oFld = oFSO.GetFolder(subdir)
  162. For Each file In oFld.Files
  163. objectname = remove_ext(file.name)
  164. rsSys.FindFirst (msys_type_filter(obj_type_num) & " AND [name]='" & objectname & "'")
  165. If rsSys.NoMatch Then
  166. 'object doesn't exist anymore
  167. If Len(CleanDirs) > 0 Then CleanDirs = CleanDirs & "|"
  168. CleanDirs = CleanDirs & (Replace(file.path, CurrentProject.path, "."))
  169. If Not sim Then
  170. oFSO.DeleteFile file
  171. logger "CleanDirs", "DEBUG", "> removed: " & file
  172. End If
  173. End If
  174. Next file
  175. next_obj_type:
  176. Next obj_type
  177. End Function
  178. Public Function files_exist_for(acType As Integer, name As String) As Boolean
  179. 'does the object has its files in sources
  180. Dim source_path As String
  181. source_path = VCS_Dir.ProjectPath() & "source\"
  182. Select Case acType
  183. Case acForm
  184. files_exist_for = (dir(source_path & "forms\" & name & ".bas") <> "")
  185. Case acReport
  186. files_exist_for = (dir(source_path & "reports\" & name & ".bas") <> "" _
  187. And _
  188. dir(source_path & "reports\" & name & ".pv") <> "")
  189. Case acQuery
  190. files_exist_for = (dir(source_path & "queries\" & name & ".bas") <> "")
  191. Case acTable
  192. files_exist_for = ( _
  193. dir(source_path & "tbldef\" & name & ".sql") <> "" _
  194. Or _
  195. dir(source_path & "tbldef\" & name & ".lnkd") <> "" _
  196. )
  197. Case acMacro
  198. files_exist_for = (dir(source_path & "macros\" & name & ".bas") <> "")
  199. Case acModule
  200. files_exist_for = (dir(source_path & "modules\" & name & ".bas") <> "")
  201. End Select
  202. End Function