You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
7.8KB

  1. <%
  2. '=======================================================================================================================
  3. ' AREA REPOSITORY
  4. ' Areas (cities, regions...) and which businesses cover them. A business can be linked to any number of areas
  5. ' through business_areas (business_id, area_id).
  6. '=======================================================================================================================
  7. Class AreaRepository_Class
  8. ' All areas with the number of businesses in each: list of Dictionary(id, name, n)
  9. Public Function All()
  10. Dim list, rs, d
  11. Set list = CreateObject("Scripting.Dictionary")
  12. Set rs = Db_Query("SELECT a.id, a.name, COUNT(ba.business_id) AS n FROM areas a LEFT JOIN business_areas ba ON ba.area_id = a.id GROUP BY a.id, a.name ORDER BY a.name", Array())
  13. Do While Not rs.EOF
  14. Set d = CreateObject("Scripting.Dictionary")
  15. d("id") = CLng(rs(0)) : d("name") = rs(1) & "" : d("n") = CLng(rs(2))
  16. list.Add list.Count, d
  17. rs.MoveNext
  18. Loop
  19. rs.Close
  20. Set All = list
  21. End Function
  22. ' Businesses not linked to any area.
  23. Public Function UnassignedCount()
  24. Dim rs
  25. Set rs = Db_Query("SELECT COUNT(*) FROM businesses b WHERE NOT EXISTS (SELECT ba.area_id FROM business_areas ba WHERE ba.business_id = b.id)", Array())
  26. UnassignedCount = CLng(rs(0))
  27. rs.Close
  28. End Function
  29. Public Function Find(id)
  30. Dim rs
  31. Set rs = Db_Query("SELECT a.id, a.name, (SELECT COUNT(*) FROM business_areas ba WHERE ba.area_id = a.id) AS n FROM areas a WHERE a.id = ?", Array(Db_PI(id)))
  32. If rs.EOF Then
  33. Set Find = Nothing
  34. Else
  35. Dim d : Set d = CreateObject("Scripting.Dictionary")
  36. d("id") = CLng(rs(0)) : d("name") = rs(1) & "" : d("n") = CLng(rs(2))
  37. Set Find = d
  38. End If
  39. rs.Close
  40. End Function
  41. ' True when another area (not excludeId) already has this name (case-insensitive).
  42. Public Function NameTaken(name, excludeId)
  43. Dim rs
  44. Set rs = Db_Query("SELECT COUNT(*) FROM areas WHERE name = ? AND id <> ?", Array(Db_PS(name), Db_PI(excludeId)))
  45. NameTaken = (CLng(rs(0)) > 0)
  46. rs.Close
  47. End Function
  48. Public Sub Create(name)
  49. Db_Exec "INSERT INTO areas (name) VALUES (?)", Array(Db_PS(name))
  50. End Sub
  51. ' Returns the area id for a name, creating the area when it does not exist. Null for a blank name.
  52. Public Function FindOrCreate(ByVal name)
  53. Dim rs
  54. name = Left(Trim(name), 100)
  55. If Len(name) = 0 Then
  56. FindOrCreate = Null
  57. Exit Function
  58. End If
  59. Set rs = Db_Query("SELECT id FROM areas WHERE name = ?", Array(Db_PS(name)))
  60. If Not rs.EOF Then
  61. FindOrCreate = CLng(rs(0))
  62. rs.Close
  63. Exit Function
  64. End If
  65. rs.Close
  66. Create name
  67. Set rs = Db_Query("SELECT @@IDENTITY", Array())
  68. FindOrCreate = CLng(rs(0))
  69. rs.Close
  70. End Function
  71. Public Sub Rename(id, name)
  72. Db_Exec "UPDATE areas SET name = ? WHERE id = ?", Array(Db_PS(name), Db_PI(id))
  73. End Sub
  74. ' Moves every business from sourceId to targetId (a business already in both keeps one link), then deletes
  75. ' sourceId. Returns the number of businesses that were in sourceId.
  76. Public Function Merge(sourceId, targetId)
  77. Dim conn, moved, rs, msg
  78. Set conn = DAL().Connection
  79. Set rs = Db_Query("SELECT COUNT(*) FROM business_areas WHERE area_id = ?", Array(Db_PI(sourceId)))
  80. moved = CLng(rs(0))
  81. rs.Close
  82. conn.BeginTrans
  83. On Error Resume Next
  84. ' Ids inlined as CLng: Access binds ? markers inside a subquery ahead of the outer ones.
  85. Db_Exec "DELETE FROM business_areas WHERE area_id = " & CLng(sourceId) & _
  86. " AND business_id IN (SELECT x.business_id FROM business_areas x WHERE x.area_id = " & CLng(targetId) & ")", Array()
  87. If Err.Number = 0 Then Db_Exec "UPDATE business_areas SET area_id = ? WHERE area_id = ?", Array(Db_PI(targetId), Db_PI(sourceId))
  88. If Err.Number = 0 Then Db_Exec "DELETE FROM areas WHERE id = ?", Array(Db_PI(sourceId))
  89. If Err.Number <> 0 Then
  90. msg = Err.Description
  91. Err.Clear
  92. conn.RollbackTrans
  93. On Error GoTo 0
  94. Err.Raise 5, "AreaRepository.Merge", msg
  95. End If
  96. conn.CommitTrans
  97. On Error GoTo 0
  98. Merge = moved
  99. End Function
  100. Public Sub Delete(id)
  101. Db_Exec "DELETE FROM areas WHERE id = ?", Array(Db_PI(id))
  102. End Sub
  103. '---------------------------------------------------------------------------------------------------------------------
  104. ' Links to businesses
  105. '---------------------------------------------------------------------------------------------------------------------
  106. ' Areas of one business: list of Dictionary(id, name), by name.
  107. Public Function ForBusiness(businessId)
  108. Dim list, rs, d
  109. Set list = CreateObject("Scripting.Dictionary")
  110. Set rs = Db_Query("SELECT a.id, a.name FROM business_areas ba INNER JOIN areas a ON a.id = ba.area_id WHERE ba.business_id = ? ORDER BY a.name", Array(Db_PI(businessId)))
  111. Do While Not rs.EOF
  112. Set d = CreateObject("Scripting.Dictionary")
  113. d("id") = CLng(rs(0)) : d("name") = rs(1) & ""
  114. list.Add list.Count, d
  115. rs.MoveNext
  116. Loop
  117. rs.Close
  118. Set ForBusiness = list
  119. End Function
  120. ' Area names for many businesses at once: Dictionary CStr(business id) -> "Name, Name". ids is a comma-separated
  121. ' list of numeric ids (callers build it from CLng values) or "" for every business.
  122. Public Function NamesByBusiness(ids)
  123. Dim names, rs, sql, k
  124. Set names = CreateObject("Scripting.Dictionary")
  125. sql = "SELECT ba.business_id, a.name FROM business_areas ba INNER JOIN areas a ON a.id = ba.area_id"
  126. If Len(ids) > 0 Then sql = sql & " WHERE ba.business_id IN (" & ids & ")"
  127. Set rs = Db_Query(sql & " ORDER BY ba.business_id, a.name", Array())
  128. Do While Not rs.EOF
  129. k = CStr(rs(0))
  130. If names.Exists(k) Then names(k) = names(k) & ", " & rs(1) Else names(k) = rs(1) & ""
  131. rs.MoveNext
  132. Loop
  133. rs.Close
  134. Set NamesByBusiness = names
  135. End Function
  136. ' Replaces the areas of a business with areaIds (Dictionary whose keys are area ids). Unknown ids are ignored.
  137. Public Sub SetForBusiness(businessId, areaIds)
  138. Dim conn, known, rs, k, msg
  139. Set known = CreateObject("Scripting.Dictionary")
  140. Set rs = Db_Query("SELECT id FROM areas", Array())
  141. Do While Not rs.EOF
  142. known(CStr(rs(0))) = True
  143. rs.MoveNext
  144. Loop
  145. rs.Close
  146. Set conn = DAL().Connection
  147. conn.BeginTrans
  148. On Error Resume Next
  149. Db_Exec "DELETE FROM business_areas WHERE business_id = ?", Array(Db_PI(businessId))
  150. For Each k In areaIds.Keys
  151. If Err.Number <> 0 Then Exit For
  152. If known.Exists(CStr(k)) Then
  153. Db_Exec "INSERT INTO business_areas (business_id, area_id) VALUES (?, ?)", Array(Db_PI(businessId), Db_PI(k))
  154. End If
  155. Next
  156. If Err.Number <> 0 Then
  157. msg = Err.Description
  158. Err.Clear
  159. conn.RollbackTrans
  160. On Error GoTo 0
  161. Err.Raise 5, "AreaRepository.SetForBusiness", msg
  162. End If
  163. conn.CommitTrans
  164. On Error GoTo 0
  165. End Sub
  166. End Class
  167. Dim AreaRepository_Class__Singleton
  168. Function AreaRepository()
  169. If IsEmpty(AreaRepository_Class__Singleton) Then
  170. Set AreaRepository_Class__Singleton = New AreaRepository_Class
  171. End If
  172. Set AreaRepository = AreaRepository_Class__Singleton
  173. End Function
  174. %>

Powered by TurnKey Linux.