motion-yapper 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.lock +63 -0
  6. data/README.md +16 -0
  7. data/Rakefile +20 -0
  8. data/app/app_delegate.rb +5 -0
  9. data/lib/yapper.rb +30 -0
  10. data/lib/yapper/attachment.rb +48 -0
  11. data/lib/yapper/bson.rb +20 -0
  12. data/lib/yapper/config.rb +18 -0
  13. data/lib/yapper/db.rb +151 -0
  14. data/lib/yapper/document.rb +54 -0
  15. data/lib/yapper/document/attachment.rb +26 -0
  16. data/lib/yapper/document/callbacks.rb +86 -0
  17. data/lib/yapper/document/persistance.rb +171 -0
  18. data/lib/yapper/document/relation.rb +84 -0
  19. data/lib/yapper/document/selection.rb +100 -0
  20. data/lib/yapper/extensions.rb +80 -0
  21. data/lib/yapper/log.rb +5 -0
  22. data/lib/yapper/sync.rb +134 -0
  23. data/lib/yapper/sync/data.rb +12 -0
  24. data/lib/yapper/sync/event.rb +194 -0
  25. data/lib/yapper/sync/queue.rb +164 -0
  26. data/lib/yapper/timestamps.rb +16 -0
  27. data/lib/yapper/version.rb +3 -0
  28. data/lib/yapper/yapper.rb +2 -0
  29. data/spec/helpers/time_helper.rb +3 -0
  30. data/spec/integration/all_spec.rb +40 -0
  31. data/spec/integration/callback_spec.rb +87 -0
  32. data/spec/integration/db_spec.rb +40 -0
  33. data/spec/integration/find_spec.rb +51 -0
  34. data/spec/integration/persistance_spec.rb +118 -0
  35. data/spec/integration/relation_spec.rb +174 -0
  36. data/spec/integration/sync_spec.rb +42 -0
  37. data/spec/integration/timestamps_spec.rb +34 -0
  38. data/spec/integration/types_spec.rb +23 -0
  39. data/spec/integration/when_spec.rb +29 -0
  40. data/spec/integration/where_spec.rb +132 -0
  41. data/vendor/Podfile.lock +24 -0
  42. data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPClient.h +641 -0
  43. data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPClient.m +1396 -0
  44. data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.h +133 -0
  45. data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m +327 -0
  46. data/vendor/Pods/AFNetworking/AFNetworking/AFImageRequestOperation.h +113 -0
  47. data/vendor/Pods/AFNetworking/AFNetworking/AFImageRequestOperation.m +321 -0
  48. data/vendor/Pods/AFNetworking/AFNetworking/AFJSONRequestOperation.h +71 -0
  49. data/vendor/Pods/AFNetworking/AFNetworking/AFJSONRequestOperation.m +150 -0
  50. data/vendor/Pods/AFNetworking/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  51. data/vendor/Pods/AFNetworking/AFNetworking/AFNetworkActivityIndicatorManager.m +157 -0
  52. data/vendor/Pods/AFNetworking/AFNetworking/AFNetworking.h +43 -0
  53. data/vendor/Pods/AFNetworking/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  54. data/vendor/Pods/AFNetworking/AFNetworking/AFPropertyListRequestOperation.m +143 -0
  55. data/vendor/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h +370 -0
  56. data/vendor/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.m +848 -0
  57. data/vendor/Pods/AFNetworking/AFNetworking/AFXMLRequestOperation.h +89 -0
  58. data/vendor/Pods/AFNetworking/AFNetworking/AFXMLRequestOperation.m +167 -0
  59. data/vendor/Pods/AFNetworking/AFNetworking/UIImageView+AFNetworking.h +78 -0
  60. data/vendor/Pods/AFNetworking/AFNetworking/UIImageView+AFNetworking.m +191 -0
  61. data/vendor/Pods/AFNetworking/LICENSE +19 -0
  62. data/vendor/Pods/AFNetworking/README.md +208 -0
  63. data/vendor/Pods/BuildHeaders/AFNetworking/AFHTTPClient.h +641 -0
  64. data/vendor/Pods/BuildHeaders/AFNetworking/AFHTTPRequestOperation.h +133 -0
  65. data/vendor/Pods/BuildHeaders/AFNetworking/AFImageRequestOperation.h +113 -0
  66. data/vendor/Pods/BuildHeaders/AFNetworking/AFJSONRequestOperation.h +71 -0
  67. data/vendor/Pods/BuildHeaders/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  68. data/vendor/Pods/BuildHeaders/AFNetworking/AFNetworking.h +43 -0
  69. data/vendor/Pods/BuildHeaders/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  70. data/vendor/Pods/BuildHeaders/AFNetworking/AFURLConnectionOperation.h +370 -0
  71. data/vendor/Pods/BuildHeaders/AFNetworking/AFXMLRequestOperation.h +89 -0
  72. data/vendor/Pods/BuildHeaders/AFNetworking/UIImageView+AFNetworking.h +78 -0
  73. data/vendor/Pods/BuildHeaders/CocoaLumberjack/ContextFilterLogFormatter.h +65 -0
  74. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDASLLogger.h +41 -0
  75. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDAbstractDatabaseLogger.h +102 -0
  76. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDFileLogger.h +334 -0
  77. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDLog.h +601 -0
  78. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDTTYLogger.h +167 -0
  79. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DispatchQueueLogFormatter.h +116 -0
  80. data/vendor/Pods/BuildHeaders/NSData+MD5Digest/NSData+MD5Digest.h +18 -0
  81. data/vendor/Pods/BuildHeaders/Reachability/Reachability.h +109 -0
  82. data/vendor/Pods/BuildHeaders/YapDatabase/YapCache.h +90 -0
  83. data/vendor/Pods/BuildHeaders/YapDatabase/YapCollectionKey.h +20 -0
  84. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabase.h +547 -0
  85. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseConnection.h +447 -0
  86. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseConnectionState.h +29 -0
  87. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseDefaults.h +37 -0
  88. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtension.h +15 -0
  89. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionConnection.h +11 -0
  90. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionPrivate.h +440 -0
  91. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionTransaction.h +11 -0
  92. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredView.h +108 -0
  93. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewConnection.h +12 -0
  94. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewPrivate.h +19 -0
  95. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewTransaction.h +39 -0
  96. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearch.h +89 -0
  97. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchConnection.h +32 -0
  98. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchPrivate.h +69 -0
  99. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchSnippetOptions.h +79 -0
  100. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchTransaction.h +68 -0
  101. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseLogging.h +158 -0
  102. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseManager.h +17 -0
  103. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabasePrivate.h +424 -0
  104. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseQuery.h +42 -0
  105. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndex.h +100 -0
  106. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexConnection.h +33 -0
  107. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexPrivate.h +73 -0
  108. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexSetup.h +33 -0
  109. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexTransaction.h +58 -0
  110. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseStatement.h +13 -0
  111. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseString.h +121 -0
  112. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseTransaction.h +541 -0
  113. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseView.h +186 -0
  114. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewChange.h +272 -0
  115. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewChangePrivate.h +94 -0
  116. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewConnection.h +115 -0
  117. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewMappings.h +825 -0
  118. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewMappingsPrivate.h +72 -0
  119. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewOptions.h +56 -0
  120. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPage.h +36 -0
  121. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPageMetadata.h +27 -0
  122. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPrivate.h +153 -0
  123. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewRangeOptions.h +330 -0
  124. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewRangeOptionsPrivate.h +17 -0
  125. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewTransaction.h +447 -0
  126. data/vendor/Pods/BuildHeaders/YapDatabase/YapMemoryTable.h +74 -0
  127. data/vendor/Pods/BuildHeaders/YapDatabase/YapNull.h +17 -0
  128. data/vendor/Pods/BuildHeaders/YapDatabase/YapSet.h +41 -0
  129. data/vendor/Pods/BuildHeaders/YapDatabase/YapTouch.h +15 -0
  130. data/vendor/Pods/CocoaLumberjack/LICENSE.txt +18 -0
  131. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h +41 -0
  132. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m +99 -0
  133. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h +102 -0
  134. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m +727 -0
  135. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h +334 -0
  136. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m +1353 -0
  137. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDLog.h +601 -0
  138. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDLog.m +1083 -0
  139. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h +167 -0
  140. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m +1479 -0
  141. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.h +65 -0
  142. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.m +191 -0
  143. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.h +116 -0
  144. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.m +251 -0
  145. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt +7 -0
  146. data/vendor/Pods/CocoaLumberjack/README.markdown +37 -0
  147. data/vendor/Pods/Headers/AFNetworking/AFHTTPClient.h +641 -0
  148. data/vendor/Pods/Headers/AFNetworking/AFHTTPRequestOperation.h +133 -0
  149. data/vendor/Pods/Headers/AFNetworking/AFImageRequestOperation.h +113 -0
  150. data/vendor/Pods/Headers/AFNetworking/AFJSONRequestOperation.h +71 -0
  151. data/vendor/Pods/Headers/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  152. data/vendor/Pods/Headers/AFNetworking/AFNetworking.h +43 -0
  153. data/vendor/Pods/Headers/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  154. data/vendor/Pods/Headers/AFNetworking/AFURLConnectionOperation.h +370 -0
  155. data/vendor/Pods/Headers/AFNetworking/AFXMLRequestOperation.h +89 -0
  156. data/vendor/Pods/Headers/AFNetworking/UIImageView+AFNetworking.h +78 -0
  157. data/vendor/Pods/Headers/CocoaLumberjack/ContextFilterLogFormatter.h +65 -0
  158. data/vendor/Pods/Headers/CocoaLumberjack/DDASLLogger.h +41 -0
  159. data/vendor/Pods/Headers/CocoaLumberjack/DDAbstractDatabaseLogger.h +102 -0
  160. data/vendor/Pods/Headers/CocoaLumberjack/DDFileLogger.h +334 -0
  161. data/vendor/Pods/Headers/CocoaLumberjack/DDLog.h +601 -0
  162. data/vendor/Pods/Headers/CocoaLumberjack/DDTTYLogger.h +167 -0
  163. data/vendor/Pods/Headers/CocoaLumberjack/DispatchQueueLogFormatter.h +116 -0
  164. data/vendor/Pods/Headers/NSData+MD5Digest/NSData+MD5Digest.h +18 -0
  165. data/vendor/Pods/Headers/Reachability/Reachability.h +109 -0
  166. data/vendor/Pods/Headers/YapDatabase/YapCache.h +90 -0
  167. data/vendor/Pods/Headers/YapDatabase/YapCollectionKey.h +20 -0
  168. data/vendor/Pods/Headers/YapDatabase/YapDatabase.h +547 -0
  169. data/vendor/Pods/Headers/YapDatabase/YapDatabaseConnection.h +447 -0
  170. data/vendor/Pods/Headers/YapDatabase/YapDatabaseConnectionState.h +29 -0
  171. data/vendor/Pods/Headers/YapDatabase/YapDatabaseDefaults.h +37 -0
  172. data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtension.h +15 -0
  173. data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtensionConnection.h +11 -0
  174. data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtensionPrivate.h +440 -0
  175. data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtensionTransaction.h +11 -0
  176. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredView.h +108 -0
  177. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewConnection.h +12 -0
  178. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewPrivate.h +19 -0
  179. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewTransaction.h +39 -0
  180. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearch.h +89 -0
  181. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchConnection.h +32 -0
  182. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchPrivate.h +69 -0
  183. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchSnippetOptions.h +79 -0
  184. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchTransaction.h +68 -0
  185. data/vendor/Pods/Headers/YapDatabase/YapDatabaseLogging.h +158 -0
  186. data/vendor/Pods/Headers/YapDatabase/YapDatabaseManager.h +17 -0
  187. data/vendor/Pods/Headers/YapDatabase/YapDatabasePrivate.h +424 -0
  188. data/vendor/Pods/Headers/YapDatabase/YapDatabaseQuery.h +42 -0
  189. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndex.h +100 -0
  190. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexConnection.h +33 -0
  191. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexPrivate.h +73 -0
  192. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexSetup.h +33 -0
  193. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexTransaction.h +58 -0
  194. data/vendor/Pods/Headers/YapDatabase/YapDatabaseStatement.h +13 -0
  195. data/vendor/Pods/Headers/YapDatabase/YapDatabaseString.h +121 -0
  196. data/vendor/Pods/Headers/YapDatabase/YapDatabaseTransaction.h +541 -0
  197. data/vendor/Pods/Headers/YapDatabase/YapDatabaseView.h +186 -0
  198. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewChange.h +272 -0
  199. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewChangePrivate.h +94 -0
  200. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewConnection.h +115 -0
  201. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewMappings.h +825 -0
  202. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewMappingsPrivate.h +72 -0
  203. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewOptions.h +56 -0
  204. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewPage.h +36 -0
  205. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewPageMetadata.h +27 -0
  206. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewPrivate.h +153 -0
  207. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewRangeOptions.h +330 -0
  208. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewRangeOptionsPrivate.h +17 -0
  209. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewTransaction.h +447 -0
  210. data/vendor/Pods/Headers/YapDatabase/YapMemoryTable.h +74 -0
  211. data/vendor/Pods/Headers/YapDatabase/YapNull.h +17 -0
  212. data/vendor/Pods/Headers/YapDatabase/YapSet.h +41 -0
  213. data/vendor/Pods/Headers/YapDatabase/YapTouch.h +15 -0
  214. data/vendor/Pods/Headers/____Pods-AFNetworking-prefix.h +17 -0
  215. data/vendor/Pods/Headers/____Pods-CocoaLumberjack-prefix.h +5 -0
  216. data/vendor/Pods/Headers/____Pods-NSData+MD5Digest-prefix.h +5 -0
  217. data/vendor/Pods/Headers/____Pods-Reachability-prefix.h +5 -0
  218. data/vendor/Pods/Headers/____Pods-YapDatabase-prefix.h +5 -0
  219. data/vendor/Pods/Headers/____Pods-environment.h +38 -0
  220. data/vendor/Pods/Manifest.lock +24 -0
  221. data/vendor/Pods/NSData+MD5Digest/NSData+MD5Digest/NSData+MD5Digest.h +18 -0
  222. data/vendor/Pods/NSData+MD5Digest/NSData+MD5Digest/NSData+MD5Digest.m +39 -0
  223. data/vendor/Pods/NSData+MD5Digest/README.md +11 -0
  224. data/vendor/Pods/Pods-AFNetworking-Private.xcconfig +5 -0
  225. data/vendor/Pods/Pods-AFNetworking-dummy.m +5 -0
  226. data/vendor/Pods/Pods-AFNetworking-prefix.pch +17 -0
  227. data/vendor/Pods/Pods-AFNetworking.xcconfig +1 -0
  228. data/vendor/Pods/Pods-Acknowledgements.markdown +96 -0
  229. data/vendor/Pods/Pods-Acknowledgements.plist +142 -0
  230. data/vendor/Pods/Pods-CocoaLumberjack-Private.xcconfig +5 -0
  231. data/vendor/Pods/Pods-CocoaLumberjack-dummy.m +5 -0
  232. data/vendor/Pods/Pods-CocoaLumberjack-prefix.pch +5 -0
  233. data/vendor/Pods/Pods-CocoaLumberjack.xcconfig +0 -0
  234. data/vendor/Pods/Pods-NSData+MD5Digest-Private.xcconfig +5 -0
  235. data/vendor/Pods/Pods-NSData+MD5Digest-dummy.m +5 -0
  236. data/vendor/Pods/Pods-NSData+MD5Digest-prefix.pch +5 -0
  237. data/vendor/Pods/Pods-NSData+MD5Digest.xcconfig +0 -0
  238. data/vendor/Pods/Pods-Reachability-Private.xcconfig +5 -0
  239. data/vendor/Pods/Pods-Reachability-dummy.m +5 -0
  240. data/vendor/Pods/Pods-Reachability-prefix.pch +5 -0
  241. data/vendor/Pods/Pods-Reachability.xcconfig +1 -0
  242. data/vendor/Pods/Pods-YapDatabase-Private.xcconfig +5 -0
  243. data/vendor/Pods/Pods-YapDatabase-dummy.m +5 -0
  244. data/vendor/Pods/Pods-YapDatabase-prefix.pch +5 -0
  245. data/vendor/Pods/Pods-YapDatabase.xcconfig +1 -0
  246. data/vendor/Pods/Pods-dummy.m +5 -0
  247. data/vendor/Pods/Pods-environment.h +38 -0
  248. data/vendor/Pods/Pods-resources.sh +68 -0
  249. data/vendor/Pods/Pods.bridgesupport +5096 -0
  250. data/vendor/Pods/Pods.xcconfig +5 -0
  251. data/vendor/Pods/Pods.xcodeproj/project.pbxproj +5536 -0
  252. data/vendor/Pods/Reachability/LICENCE.txt +24 -0
  253. data/vendor/Pods/Reachability/README.md +65 -0
  254. data/vendor/Pods/Reachability/Reachability.h +109 -0
  255. data/vendor/Pods/Reachability/Reachability.m +527 -0
  256. data/vendor/Pods/YapDatabase/LICENSE.txt +18 -0
  257. data/vendor/Pods/YapDatabase/README.md +30 -0
  258. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/Internal/YapDatabaseFilteredViewPrivate.h +19 -0
  259. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredView.h +108 -0
  260. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredView.m +175 -0
  261. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewConnection.h +12 -0
  262. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewConnection.m +41 -0
  263. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTransaction.h +39 -0
  264. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTransaction.m +966 -0
  265. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/Internal/YapDatabaseFullTextSearchPrivate.h +69 -0
  266. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearch.h +89 -0
  267. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearch.m +146 -0
  268. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchConnection.h +32 -0
  269. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchConnection.m +298 -0
  270. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchSnippetOptions.h +79 -0
  271. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchSnippetOptions.m +95 -0
  272. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchTransaction.h +68 -0
  273. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchTransaction.m +1352 -0
  274. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/Internal/YapDatabaseExtensionPrivate.h +440 -0
  275. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtension.h +15 -0
  276. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtension.m +58 -0
  277. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionConnection.h +11 -0
  278. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionConnection.m +46 -0
  279. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.h +11 -0
  280. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.m +180 -0
  281. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/Internal/YapDatabaseSecondaryIndexPrivate.h +73 -0
  282. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndex.h +100 -0
  283. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndex.m +149 -0
  284. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexConnection.h +33 -0
  285. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexConnection.m +330 -0
  286. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexSetup.h +33 -0
  287. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexSetup.m +184 -0
  288. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexTransaction.h +58 -0
  289. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexTransaction.m +1166 -0
  290. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewChangePrivate.h +94 -0
  291. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewMappingsPrivate.h +72 -0
  292. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPage.h +36 -0
  293. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPage.mm +296 -0
  294. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPageMetadata.h +27 -0
  295. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPageMetadata.m +28 -0
  296. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPrivate.h +153 -0
  297. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewRangeOptionsPrivate.h +17 -0
  298. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewChange.h +272 -0
  299. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewChange.m +2494 -0
  300. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewMappings.h +825 -0
  301. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewMappings.m +1567 -0
  302. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewRangeOptions.h +330 -0
  303. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewRangeOptions.m +141 -0
  304. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseView.h +186 -0
  305. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseView.m +191 -0
  306. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewConnection.h +115 -0
  307. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewConnection.m +897 -0
  308. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewOptions.h +56 -0
  309. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewOptions.m +27 -0
  310. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewTransaction.h +447 -0
  311. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewTransaction.m +4505 -0
  312. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapCache.h +90 -0
  313. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapCache.m +453 -0
  314. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseConnectionState.h +29 -0
  315. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseConnectionState.m +48 -0
  316. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseDefaults.h +37 -0
  317. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseDefaults.m +83 -0
  318. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseLogging.h +158 -0
  319. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseLogging.m +73 -0
  320. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseManager.h +17 -0
  321. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseManager.m +56 -0
  322. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabasePrivate.h +424 -0
  323. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseStatement.h +13 -0
  324. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseStatement.m +26 -0
  325. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseString.h +121 -0
  326. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapMemoryTable.h +74 -0
  327. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapMemoryTable.m +603 -0
  328. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapNull.h +17 -0
  329. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapNull.m +31 -0
  330. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapTouch.h +15 -0
  331. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapTouch.m +31 -0
  332. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapCollectionKey.h +20 -0
  333. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapCollectionKey.m +194 -0
  334. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapDatabaseQuery.h +42 -0
  335. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapDatabaseQuery.m +96 -0
  336. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapSet.h +41 -0
  337. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapSet.m +82 -0
  338. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabase.h +547 -0
  339. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabase.m +2022 -0
  340. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseConnection.h +447 -0
  341. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseConnection.m +3874 -0
  342. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseTransaction.h +541 -0
  343. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseTransaction.m +5282 -0
  344. data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.bridgesupport +16 -0
  345. data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.h +13 -0
  346. data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.m +20 -0
  347. data/yapper.gemspec +24 -0
  348. metadata +458 -0
@@ -0,0 +1,33 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ @class YapDatabaseSecondaryIndexColumn;
4
+
5
+ typedef enum {
6
+ YapDatabaseSecondaryIndexTypeInteger,
7
+ YapDatabaseSecondaryIndexTypeReal,
8
+ YapDatabaseSecondaryIndexTypeText
9
+ } YapDatabaseSecondaryIndexType;
10
+
11
+
12
+ @interface YapDatabaseSecondaryIndexSetup : NSObject <NSCopying, NSFastEnumeration>
13
+
14
+ - (id)init;
15
+ - (id)initWithCapacity:(NSUInteger)capacity;
16
+
17
+ - (void)addColumn:(NSString *)name withType:(YapDatabaseSecondaryIndexType)type;
18
+
19
+ - (NSUInteger)count;
20
+ - (YapDatabaseSecondaryIndexColumn *)columnAtIndex:(NSUInteger)index;
21
+
22
+ - (NSArray *)columnNames;
23
+
24
+ @end
25
+
26
+ #pragma mark -
27
+
28
+ @interface YapDatabaseSecondaryIndexColumn : NSObject
29
+
30
+ @property (nonatomic, copy, readonly) NSString *name;
31
+ @property (nonatomic, assign, readonly) YapDatabaseSecondaryIndexType type;
32
+
33
+ @end
@@ -0,0 +1,184 @@
1
+ #import "YapDatabaseSecondaryIndexSetup.h"
2
+ #import "YapDatabaseLogging.h"
3
+
4
+ #if ! __has_feature(objc_arc)
5
+ #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
6
+ #endif
7
+
8
+ /**
9
+ * Define log level for this file: OFF, ERROR, WARN, INFO, VERBOSE
10
+ * See YapDatabaseLogging.h for more information.
11
+ **/
12
+ #if DEBUG
13
+ static const int ydbLogLevel = YDB_LOG_LEVEL_WARN;
14
+ #else
15
+ static const int ydbLogLevel = YDB_LOG_LEVEL_WARN;
16
+ #endif
17
+
18
+
19
+ @interface YapDatabaseSecondaryIndexColumn ()
20
+ - (id)initWithName:(NSString *)name type:(YapDatabaseSecondaryIndexType)type;
21
+ @end
22
+
23
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24
+ #pragma mark -
25
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26
+
27
+ @implementation YapDatabaseSecondaryIndexSetup
28
+ {
29
+ NSMutableArray *setup;
30
+ }
31
+
32
+ - (id)init
33
+ {
34
+ return [self initWithCapacity:0];
35
+ }
36
+
37
+ - (id)initWithCapacity:(NSUInteger)capacity
38
+ {
39
+ if ((self = [super init]))
40
+ {
41
+ if (capacity > 0)
42
+ setup = [[NSMutableArray alloc] initWithCapacity:capacity];
43
+ else
44
+ setup = [[NSMutableArray alloc] init];
45
+ }
46
+ return self;
47
+ }
48
+
49
+ - (id)initForCopy
50
+ {
51
+ self = [super init];
52
+ return self;
53
+ }
54
+
55
+ - (BOOL)isReservedName:(NSString *)columnName
56
+ {
57
+ if ([columnName caseInsensitiveCompare:@"rowid"] == NSOrderedSame)
58
+ return YES;
59
+
60
+ if ([columnName caseInsensitiveCompare:@"oid"] == NSOrderedSame)
61
+ return YES;
62
+
63
+ if ([columnName caseInsensitiveCompare:@"_rowid_"] == NSOrderedSame)
64
+ return YES;
65
+
66
+ return NO;
67
+ }
68
+
69
+ - (BOOL)isExistingName:(NSString *)columnName
70
+ {
71
+ // SQLite column names are not case sensitive.
72
+
73
+ for (YapDatabaseSecondaryIndexColumn *column in setup)
74
+ {
75
+ if ([column.name caseInsensitiveCompare:columnName] == NSOrderedSame)
76
+ {
77
+ return YES;
78
+ }
79
+ }
80
+
81
+ return NO;
82
+ }
83
+
84
+ - (void)addColumn:(NSString *)columnName withType:(YapDatabaseSecondaryIndexType)type
85
+ {
86
+ if (columnName == nil)
87
+ {
88
+ NSAssert(NO, @"Invalid columnName: nil");
89
+
90
+ YDBLogError(@"%@: Invalid columnName: nil", THIS_METHOD);
91
+ return;
92
+ }
93
+
94
+ if ([self isReservedName:columnName])
95
+ {
96
+ NSAssert(NO, @"Invalid columnName: columnName is reserved");
97
+
98
+ YDBLogError(@"Invalid columnName: columnName is reserved");
99
+ return;
100
+ }
101
+
102
+ if ([self isExistingName:columnName])
103
+ {
104
+ NSAssert(NO, @"Invalid columnName: columnName already exists");
105
+
106
+ YDBLogError(@"Invalid columnName: columnName already exists");
107
+ return;
108
+ }
109
+
110
+ if (type != YapDatabaseSecondaryIndexTypeInteger &&
111
+ type != YapDatabaseSecondaryIndexTypeReal &&
112
+ type != YapDatabaseSecondaryIndexTypeText)
113
+ {
114
+ NSAssert(NO, @"Invalid type");
115
+
116
+ YDBLogError(@"%@: Invalid type", THIS_METHOD);
117
+ return;
118
+ }
119
+
120
+ YapDatabaseSecondaryIndexColumn *column =
121
+ [[YapDatabaseSecondaryIndexColumn alloc] initWithName:columnName type:type];
122
+
123
+ [setup addObject:column];
124
+ }
125
+
126
+ - (NSUInteger)count
127
+ {
128
+ return [setup count];
129
+ }
130
+
131
+ - (YapDatabaseSecondaryIndexColumn *)columnAtIndex:(NSUInteger)index
132
+ {
133
+ return [setup objectAtIndex:index];
134
+ }
135
+
136
+ - (NSArray *)columnNames
137
+ {
138
+ NSMutableArray *columnNames = [NSMutableArray arrayWithCapacity:[setup count]];
139
+
140
+ for (YapDatabaseSecondaryIndexColumn *column in setup)
141
+ {
142
+ [columnNames addObject:column.name];
143
+ }
144
+
145
+ return [columnNames copy];
146
+ }
147
+
148
+ - (id)copyWithZone:(NSZone *)zone
149
+ {
150
+ YapDatabaseSecondaryIndexSetup *copy = [[YapDatabaseSecondaryIndexSetup alloc] initForCopy];
151
+ copy->setup = [setup mutableCopy];
152
+
153
+ return copy;
154
+ }
155
+
156
+ - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
157
+ objects:(__unsafe_unretained id [])buffer
158
+ count:(NSUInteger)length
159
+ {
160
+ return [setup countByEnumeratingWithState:state objects:buffer count:length];
161
+ }
162
+
163
+ @end
164
+
165
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
166
+ #pragma mark -
167
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
168
+
169
+ @implementation YapDatabaseSecondaryIndexColumn
170
+
171
+ @synthesize name = name;
172
+ @synthesize type = type;
173
+
174
+ - (id)initWithName:(NSString *)inName type:(YapDatabaseSecondaryIndexType)inType
175
+ {
176
+ if ((self = [super init]))
177
+ {
178
+ name = [inName copy];
179
+ type = inType;
180
+ }
181
+ return self;
182
+ }
183
+
184
+ @end
@@ -0,0 +1,58 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ #import "YapDatabaseExtensionTransaction.h"
4
+ #import "YapDatabaseQuery.h"
5
+
6
+
7
+ @interface YapDatabaseSecondaryIndexTransaction : YapDatabaseExtensionTransaction
8
+
9
+ /**
10
+ * These methods allow you to enumerates matches from the secondary index(es) using a given query.
11
+ *
12
+ * The query that you input is an SQL style query (appropriate for SQLite semantics),
13
+ * excluding the "SELECT ... FROM 'tableName'" component.
14
+ *
15
+ * For example:
16
+ *
17
+ * query = [YapDatabaseQuery queryWithFormat:@"WHERE age >= 62"];
18
+ * [[transaction ext:@"idx"] enumerateKeysMatchingQuery:query usingBlock:^(NSString *key, BOOL *stop) {
19
+ *
20
+ * // ...
21
+ * }];
22
+ *
23
+ * You can also pass parameters to the query using the standard SQLite placeholder:
24
+ *
25
+ * query = [YapDatabaseQuery queryWithFormat:@"WHERE age >= ? AND state == ?", @(age), state];
26
+ * [[transaction ext:@"idx"] enumerateKeysMatchingQuery:query usingBlock:^(NSString *key, BOOL *stop) {
27
+ *
28
+ * // ...
29
+ * }];
30
+ *
31
+ * For more information, and more examples, please see YapDatabaseQuery.
32
+ *
33
+ * @return NO if there was a problem with the given query. YES otherwise.
34
+ *
35
+ * @see YapDatabaseQuery
36
+ **/
37
+
38
+ - (BOOL)enumerateKeysMatchingQuery:(YapDatabaseQuery *)query
39
+ usingBlock:(void (^)(NSString *collection, NSString *key, BOOL *stop))block;
40
+
41
+ - (BOOL)enumerateKeysAndMetadataMatchingQuery:(YapDatabaseQuery *)query
42
+ usingBlock:
43
+ (void (^)(NSString *collection, NSString *key, id metadata, BOOL *stop))block;
44
+
45
+ - (BOOL)enumerateKeysAndObjectsMatchingQuery:(YapDatabaseQuery *)query
46
+ usingBlock:
47
+ (void (^)(NSString *collection, NSString *key, id object, BOOL *stop))block;
48
+
49
+ - (BOOL)enumerateRowsMatchingQuery:(YapDatabaseQuery *)query
50
+ usingBlock:
51
+ (void (^)(NSString *collection, NSString *key, id object, id metadata, BOOL *stop))block;
52
+ /**
53
+ * Skips the enumeration process, and just gives you the count of matching rows.
54
+ **/
55
+
56
+ - (BOOL)getNumberOfRows:(NSUInteger *)count matchingQuery:(YapDatabaseQuery *)query;
57
+
58
+ @end
@@ -0,0 +1,1166 @@
1
+ #import "YapDatabaseSecondaryIndexTransaction.h"
2
+ #import "YapDatabaseSecondaryIndexPrivate.h"
3
+ #import "YapDatabaseStatement.h"
4
+
5
+ #import "YapDatabasePrivate.h"
6
+ #import "YapDatabaseExtensionPrivate.h"
7
+
8
+ #import "YapDatabaseLogging.h"
9
+
10
+ #if ! __has_feature(objc_arc)
11
+ #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
12
+ #endif
13
+
14
+ /**
15
+ * Define log level for this file: OFF, ERROR, WARN, INFO, VERBOSE
16
+ * See YapDatabaseLogging.h for more information.
17
+ **/
18
+ #if DEBUG
19
+ static const int ydbLogLevel = YDB_LOG_LEVEL_WARN;
20
+ #else
21
+ static const int ydbLogLevel = YDB_LOG_LEVEL_WARN;
22
+ #endif
23
+
24
+ /**
25
+ * This version number is stored in the yap2 table.
26
+ * If there is a major re-write to this class, then the version number will be incremented,
27
+ * and the class can automatically rebuild the tables as needed.
28
+ **/
29
+ #define YAP_DATABASE_SECONDARY_INDEX_CLASS_VERSION 1
30
+
31
+
32
+ @implementation YapDatabaseSecondaryIndexTransaction
33
+
34
+ - (id)initWithSecondaryIndexConnection:(YapDatabaseSecondaryIndexConnection *)inSecondaryIndexConnection
35
+ databaseTransaction:(YapDatabaseReadTransaction *)inDatabaseTransaction
36
+ {
37
+ if ((self = [super init]))
38
+ {
39
+ secondaryIndexConnection = inSecondaryIndexConnection;
40
+ databaseTransaction = inDatabaseTransaction;
41
+ }
42
+ return self;
43
+ }
44
+
45
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46
+ #pragma mark Extension Lifecycle
47
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
48
+
49
+ /**
50
+ * Required override method from YapDatabaseExtensionTransaction.
51
+ *
52
+ * This method is called to create any necessary tables (if needed),
53
+ * as well as populate the view (if needed) by enumerating over the existing rows in the database.
54
+ **/
55
+ - (BOOL)createIfNeeded
56
+ {
57
+ int oldClassVersion = [self intValueForExtensionKey:@"classVersion"];
58
+ int classVersion = YAP_DATABASE_SECONDARY_INDEX_CLASS_VERSION;
59
+
60
+ if (oldClassVersion != classVersion)
61
+ {
62
+ // First time registration
63
+
64
+ [self upgradeFromForOldClassVersion:oldClassVersion];
65
+
66
+ if (![self createTable]) return NO;
67
+ if (![self populate]) return NO;
68
+
69
+ [self setIntValue:classVersion forExtensionKey:@"classVersion"];
70
+
71
+ int userSuppliedConfigVersion = secondaryIndexConnection->secondaryIndex->version;
72
+ [self setIntValue:userSuppliedConfigVersion forExtensionKey:@"version"];
73
+ }
74
+ else
75
+ {
76
+ // Check user-supplied config version.
77
+ // We may need to re-populate the database if the groupingBlock or sortingBlock changed.
78
+
79
+ int oldVersion = [self intValueForExtensionKey:@"version"];
80
+ int newVersion = secondaryIndexConnection->secondaryIndex->version;
81
+
82
+ if (oldVersion != newVersion)
83
+ {
84
+ if (![self dropTable]) return NO;
85
+ if (![self createTable]) return NO;
86
+ if (![self populate]) return NO;
87
+
88
+ [self setIntValue:newVersion forExtensionKey:@"version"];
89
+ }
90
+ }
91
+
92
+ return YES;
93
+ }
94
+
95
+ /**
96
+ * Required override method from YapDatabaseExtensionTransaction.
97
+ *
98
+ * This method is called to prepare the transaction for use.
99
+ *
100
+ * Remember, an extension transaction is a very short lived object.
101
+ * Thus it stores the majority of its state within the extension connection (the parent).
102
+ *
103
+ * Return YES if completed successfully, or if already prepared.
104
+ * Return NO if some kind of error occured.
105
+ **/
106
+ - (BOOL)prepareIfNeeded
107
+ {
108
+ return YES;
109
+ }
110
+
111
+ /**
112
+ * Internal method.
113
+ *
114
+ * This method is used to handle the upgrade process from earlier architectures of this class.
115
+ **/
116
+ - (void)upgradeFromForOldClassVersion:(int)oldClassVersion
117
+ {
118
+ // Reserved for future use...
119
+ }
120
+
121
+ /**
122
+ * Internal method.
123
+ *
124
+ * This method is called, if needed, to drop the old table.
125
+ **/
126
+ - (BOOL)dropTable
127
+ {
128
+ sqlite3 *db = databaseTransaction->connection->db;
129
+
130
+ NSString *tableName = [self tableName];
131
+ NSString *dropTable = [NSString stringWithFormat:@"DROP TABLE IF EXISTS \"%@\";", tableName];
132
+
133
+ int status = sqlite3_exec(db, [dropTable UTF8String], NULL, NULL, NULL);
134
+ if (status != SQLITE_OK)
135
+ {
136
+ YDBLogError(@"%@ - Failed dropping secondary index table (%@): %d %s",
137
+ THIS_METHOD, dropTable, status, sqlite3_errmsg(db));
138
+ return NO;
139
+ }
140
+
141
+ return YES;
142
+ }
143
+
144
+ /**
145
+ * Internal method.
146
+ *
147
+ * This method is called, if needed, to create the tables for the view.
148
+ **/
149
+ - (BOOL)createTable
150
+ {
151
+ sqlite3 *db = databaseTransaction->connection->db;
152
+
153
+ NSString *tableName = [self tableName];
154
+ YapDatabaseSecondaryIndexSetup *setup = secondaryIndexConnection->secondaryIndex->setup;
155
+
156
+ YDBLogVerbose(@"Creating secondary index table for registeredName(%@): %@", [self registeredName], tableName);
157
+
158
+ // CREATE TABLE IF NOT EXISTS "tableName" ("rowid" INTEGER PRIMARY KEY, index1, index2...);
159
+
160
+ NSMutableString *createTable = [NSMutableString stringWithCapacity:100];
161
+ [createTable appendFormat:@"CREATE TABLE IF NOT EXISTS \"%@\" (\"rowid\" INTEGER PRIMARY KEY", tableName];
162
+
163
+ for (YapDatabaseSecondaryIndexColumn *column in setup)
164
+ {
165
+ if (column.type == YapDatabaseSecondaryIndexTypeInteger)
166
+ {
167
+ [createTable appendFormat:@", \"%@\" INTEGER", column.name];
168
+ }
169
+ else if (column.type == YapDatabaseSecondaryIndexTypeReal)
170
+ {
171
+ [createTable appendFormat:@", \"%@\" REAL", column.name];
172
+ }
173
+ else if (column.type == YapDatabaseSecondaryIndexTypeText)
174
+ {
175
+ [createTable appendFormat:@", \"%@\" TEXT", column.name];
176
+ }
177
+ }
178
+
179
+ [createTable appendString:@");"];
180
+
181
+ int status = sqlite3_exec(db, [createTable UTF8String], NULL, NULL, NULL);
182
+ if (status != SQLITE_OK)
183
+ {
184
+ YDBLogError(@"%@ - Failed creating secondary index table (%@): %d %s",
185
+ THIS_METHOD, tableName, status, sqlite3_errmsg(db));
186
+ return NO;
187
+ }
188
+
189
+ for (YapDatabaseSecondaryIndexColumn *column in setup)
190
+ {
191
+ NSString *createIndex =
192
+ [NSString stringWithFormat:@"CREATE INDEX IF NOT EXISTS \"%@\" ON \"%@\" (\"%@\");",
193
+ column.name, tableName, column.name];
194
+
195
+ status = sqlite3_exec(db, [createIndex UTF8String], NULL, NULL, NULL);
196
+ if (status != SQLITE_OK)
197
+ {
198
+ YDBLogError(@"Failed creating index on '%@': %d %s", column.name, status, sqlite3_errmsg(db));
199
+ return NO;
200
+ }
201
+ }
202
+
203
+ return YES;
204
+ }
205
+
206
+ /**
207
+ * Internal method.
208
+ *
209
+ * This method is called, if needed, to populate the FTS indexes.
210
+ * It does so by enumerating the rows in the database, and invoking the usual blocks and insertion methods.
211
+ **/
212
+ - (BOOL)populate
213
+ {
214
+ // Remove everything from the database
215
+
216
+ [self removeAllRowids];
217
+
218
+ // Enumerate the existing rows in the database and populate the indexes
219
+
220
+ __unsafe_unretained YapDatabaseSecondaryIndex *secondaryIndex = secondaryIndexConnection->secondaryIndex;
221
+
222
+ if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithKey)
223
+ {
224
+ __unsafe_unretained YapDatabaseSecondaryIndexWithKeyBlock block =
225
+ (YapDatabaseSecondaryIndexWithKeyBlock)secondaryIndex->block;
226
+
227
+ [databaseTransaction _enumerateKeysInAllCollectionsUsingBlock:
228
+ ^(int64_t rowid, NSString *collection, NSString *key, BOOL *stop) {
229
+
230
+ block(secondaryIndexConnection->blockDict, collection, key);
231
+
232
+ if ([secondaryIndexConnection->blockDict count] > 0)
233
+ {
234
+ [self addRowid:rowid isNew:YES];
235
+ [secondaryIndexConnection->blockDict removeAllObjects];
236
+ }
237
+ }];
238
+ }
239
+ else if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithObject)
240
+ {
241
+ __unsafe_unretained YapDatabaseSecondaryIndexWithObjectBlock block =
242
+ (YapDatabaseSecondaryIndexWithObjectBlock)secondaryIndex->block;
243
+
244
+ [databaseTransaction _enumerateKeysAndObjectsInAllCollectionsUsingBlock:
245
+ ^(int64_t rowid, NSString *collection, NSString *key, id object, BOOL *stop) {
246
+
247
+ block(secondaryIndexConnection->blockDict, collection, key, object);
248
+
249
+ if ([secondaryIndexConnection->blockDict count] > 0)
250
+ {
251
+ [self addRowid:rowid isNew:YES];
252
+ [secondaryIndexConnection->blockDict removeAllObjects];
253
+ }
254
+ }];
255
+ }
256
+ else if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithMetadata)
257
+ {
258
+ __unsafe_unretained YapDatabaseSecondaryIndexWithMetadataBlock block =
259
+ (YapDatabaseSecondaryIndexWithMetadataBlock)secondaryIndex->block;
260
+
261
+ [databaseTransaction _enumerateKeysAndMetadataInAllCollectionsUsingBlock:
262
+ ^(int64_t rowid, NSString *collection, NSString *key, id metadata, BOOL *stop) {
263
+
264
+ block(secondaryIndexConnection->blockDict, collection, key, metadata);
265
+
266
+ if ([secondaryIndexConnection->blockDict count] > 0)
267
+ {
268
+ [self addRowid:rowid isNew:YES];
269
+ [secondaryIndexConnection->blockDict removeAllObjects];
270
+ }
271
+ }];
272
+ }
273
+ else // if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithRow)
274
+ {
275
+ __unsafe_unretained YapDatabaseSecondaryIndexWithRowBlock block =
276
+ (YapDatabaseSecondaryIndexWithRowBlock)secondaryIndex->block;
277
+
278
+ [databaseTransaction _enumerateRowsInAllCollectionsUsingBlock:
279
+ ^(int64_t rowid, NSString *collection, NSString *key, id object, id metadata, BOOL *stop) {
280
+
281
+ block(secondaryIndexConnection->blockDict, collection, key, object, metadata);
282
+
283
+ if ([secondaryIndexConnection->blockDict count] > 0)
284
+ {
285
+ [self addRowid:rowid isNew:YES];
286
+ [secondaryIndexConnection->blockDict removeAllObjects];
287
+ }
288
+ }];
289
+ }
290
+
291
+ return YES;
292
+ }
293
+
294
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
295
+ #pragma mark Accessors
296
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
297
+
298
+ /**
299
+ * Required override method from YapDatabaseExtensionTransaction.
300
+ **/
301
+ - (YapDatabaseReadTransaction *)databaseTransaction
302
+ {
303
+ return databaseTransaction;
304
+ }
305
+
306
+ /**
307
+ * Required override method from YapDatabaseExtensionTransaction.
308
+ **/
309
+ - (YapDatabaseExtensionConnection *)extensionConnection
310
+ {
311
+ return secondaryIndexConnection;
312
+ }
313
+
314
+ - (NSString *)registeredName
315
+ {
316
+ return [secondaryIndexConnection->secondaryIndex registeredName];
317
+ }
318
+
319
+ - (NSString *)tableName
320
+ {
321
+ return [secondaryIndexConnection->secondaryIndex tableName];
322
+ }
323
+
324
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
325
+ #pragma mark Logic
326
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
327
+
328
+ /**
329
+ * Adds a row to the table, using the given rowid along with the values in the 'blockDict' ivar.
330
+ **/
331
+ - (void)addRowid:(int64_t)rowid isNew:(BOOL)isNew
332
+ {
333
+ YDBLogAutoTrace();
334
+
335
+ sqlite3_stmt *statement = NULL;
336
+ if (isNew)
337
+ statement = [secondaryIndexConnection insertStatement];
338
+ else
339
+ statement = [secondaryIndexConnection updateStatement];
340
+
341
+ if (statement == NULL)
342
+ return;
343
+
344
+ // isNew : INSERT INTO "tableName" ("rowid", "column1", "column2", ...) VALUES (?, ?, ? ...);
345
+ // !isNew : UPDATE "tableName" SET "column1" = ?, "column2" = ?, ... WHERE "rowid" = ?;
346
+
347
+ int i = 1;
348
+
349
+ if (isNew) {
350
+ sqlite3_bind_int64(statement, i, rowid);
351
+ i++;
352
+ }
353
+
354
+ for (YapDatabaseSecondaryIndexColumn *column in secondaryIndexConnection->secondaryIndex->setup)
355
+ {
356
+ id columnValue = [secondaryIndexConnection->blockDict objectForKey:column.name];
357
+ if (columnValue)
358
+ {
359
+ if (column.type == YapDatabaseSecondaryIndexTypeInteger)
360
+ {
361
+ if ([columnValue isKindOfClass:[NSNumber class]])
362
+ {
363
+ __unsafe_unretained NSNumber *cast = (NSNumber *)columnValue;
364
+
365
+ int64_t num = [cast longLongValue];
366
+ sqlite3_bind_int64(statement, i, (sqlite3_int64)num);
367
+ }
368
+ else
369
+ {
370
+ YDBLogWarn(@"Unable to bind value for column(name=%@, type=integer) with unsupported class: %@."
371
+ @" Column requires NSNumber.",
372
+ column.name, NSStringFromClass([columnValue class]));
373
+ }
374
+ }
375
+ else if (column.type == YapDatabaseSecondaryIndexTypeReal)
376
+ {
377
+ if ([columnValue isKindOfClass:[NSNumber class]])
378
+ {
379
+ __unsafe_unretained NSNumber *cast = (NSNumber *)columnValue;
380
+
381
+ double num = [cast doubleValue];
382
+ sqlite3_bind_double(statement, i, num);
383
+ }
384
+ else if ([columnValue isKindOfClass:[NSDate class]])
385
+ {
386
+ __unsafe_unretained NSDate *cast = (NSDate *)columnValue;
387
+
388
+ double num = [cast timeIntervalSinceReferenceDate];
389
+ sqlite3_bind_double(statement, i, num);
390
+ }
391
+ else
392
+ {
393
+ YDBLogWarn(@"Unable to bind value for column(name=%@, type=real) with unsupported class: %@."
394
+ @" Column requires NSNumber or NSDate.",
395
+ column.name, NSStringFromClass([columnValue class]));
396
+ }
397
+ }
398
+ else // if (column.type == YapDatabaseSecondaryIndexTypeText)
399
+ {
400
+ if ([columnValue isKindOfClass:[NSString class]])
401
+ {
402
+ __unsafe_unretained NSString *cast = (NSString *)columnValue;
403
+
404
+ sqlite3_bind_text(statement, i, [cast UTF8String], -1, SQLITE_TRANSIENT);
405
+ }
406
+ else
407
+ {
408
+ YDBLogWarn(@"Unable to bind value for column(name=%@, type=text) with unsupported class: %@."
409
+ @" Column requires NSString.",
410
+ column.name, NSStringFromClass([columnValue class]));
411
+ }
412
+ }
413
+ }
414
+
415
+ i++;
416
+ }
417
+
418
+ if (!isNew) {
419
+ sqlite3_bind_int64(statement, i, rowid);
420
+ i++;
421
+ }
422
+
423
+ int status = sqlite3_step(statement);
424
+ if (status != SQLITE_DONE)
425
+ {
426
+ YDBLogError(@"Error executing '%s': %d %s",
427
+ isNew ? "insertStatement" : "updateStatement",
428
+ status, sqlite3_errmsg(databaseTransaction->connection->db));
429
+ }
430
+
431
+ sqlite3_clear_bindings(statement);
432
+ sqlite3_reset(statement);
433
+
434
+ isMutated = YES;
435
+ }
436
+
437
+ - (void)removeRowid:(int64_t)rowid
438
+ {
439
+ YDBLogAutoTrace();
440
+
441
+ sqlite3_stmt *statement = [secondaryIndexConnection removeStatement];
442
+ if (statement == NULL) return;
443
+
444
+ // DELETE FROM "tableName" WHERE "rowid" = ?;
445
+
446
+ sqlite3_bind_int64(statement, 1, rowid);
447
+
448
+ int status = sqlite3_step(statement);
449
+ if (status != SQLITE_DONE)
450
+ {
451
+ YDBLogError(@"Error executing 'removeStatement': %d %s",
452
+ status, sqlite3_errmsg(databaseTransaction->connection->db));
453
+ }
454
+
455
+ sqlite3_clear_bindings(statement);
456
+ sqlite3_reset(statement);
457
+
458
+ isMutated = YES;
459
+ }
460
+
461
+ - (void)removeRowids:(NSArray *)rowids
462
+ {
463
+ YDBLogAutoTrace();
464
+
465
+ NSUInteger count = [rowids count];
466
+
467
+ if (count == 0) return;
468
+ if (count == 1)
469
+ {
470
+ int64_t rowid = [[rowids objectAtIndex:0] longLongValue];
471
+
472
+ [self removeRowid:rowid];
473
+ return;
474
+ }
475
+
476
+ // DELETE FROM "tableName" WHERE "rowid" in (?, ?, ...);
477
+ //
478
+ // Note: We don't have to worry sqlite's max number of host parameters.
479
+ // YapDatabase gives us the rowids in batches where each batch is already capped at this number.
480
+
481
+ NSUInteger capacity = 50 + (count * 3);
482
+ NSMutableString *query = [NSMutableString stringWithCapacity:capacity];
483
+
484
+ [query appendFormat:@"DELETE FROM \"%@\" WHERE \"rowid\" IN (", [self tableName]];
485
+
486
+ NSUInteger i;
487
+ for (i = 0; i < count; i++)
488
+ {
489
+ if (i == 0)
490
+ [query appendFormat:@"?"];
491
+ else
492
+ [query appendFormat:@", ?"];
493
+ }
494
+
495
+ [query appendString:@");"];
496
+
497
+ sqlite3_stmt *statement;
498
+
499
+ int status = sqlite3_prepare_v2(databaseTransaction->connection->db, [query UTF8String], -1, &statement, NULL);
500
+ if (status != SQLITE_OK)
501
+ {
502
+ YDBLogError(@"Error creating 'removeRowids' statement: %d %s",
503
+ status, sqlite3_errmsg(databaseTransaction->connection->db));
504
+ return;
505
+ }
506
+
507
+ for (i = 0; i < count; i++)
508
+ {
509
+ int64_t rowid = [[rowids objectAtIndex:i] longLongValue];
510
+
511
+ sqlite3_bind_int64(statement, (int)(i + 1), rowid);
512
+ }
513
+
514
+ status = sqlite3_step(statement);
515
+ if (status != SQLITE_DONE)
516
+ {
517
+ YDBLogError(@"Error executing 'removeRowids' statement: %d %s",
518
+ status, sqlite3_errmsg(databaseTransaction->connection->db));
519
+ }
520
+
521
+ sqlite3_finalize(statement);
522
+
523
+ isMutated = YES;
524
+ }
525
+
526
+ - (void)removeAllRowids
527
+ {
528
+ YDBLogAutoTrace();
529
+
530
+ sqlite3_stmt *statement = [secondaryIndexConnection removeAllStatement];
531
+ if (statement == NULL)
532
+ return;
533
+
534
+ int status;
535
+
536
+ // DELETE FROM "tableName";
537
+
538
+ YDBLogVerbose(@"DELETE FROM '%@';", [self tableName]);
539
+
540
+ status = sqlite3_step(statement);
541
+ if (status != SQLITE_DONE)
542
+ {
543
+ YDBLogError(@"%@ (%@): Error in removeAllStatement: %d %s",
544
+ THIS_METHOD, [self registeredName],
545
+ status, sqlite3_errmsg(databaseTransaction->connection->db));
546
+ }
547
+
548
+ sqlite3_reset(statement);
549
+
550
+ isMutated = YES;
551
+ }
552
+
553
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
554
+ #pragma mark Cleanup & Commit
555
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
556
+
557
+ /**
558
+ * Required override method from YapDatabaseExtension
559
+ **/
560
+ - (void)commitTransaction
561
+ {
562
+ // An extensionTransaction is only valid within the scope of its encompassing databaseTransaction.
563
+ // I imagine this may occasionally be misunderstood, and developers may attempt to store the extension in an ivar,
564
+ // and then use it outside the context of the database transaction block.
565
+ // Thus, this code is here as a safety net to ensure that such accidental misuse doesn't do any damage.
566
+
567
+ secondaryIndexConnection = nil; // Do not remove !
568
+ databaseTransaction = nil; // Do not remove !
569
+ }
570
+
571
+ /**
572
+ * Required override method from YapDatabaseExtension
573
+ **/
574
+ - (void)rollbackTransaction
575
+ {
576
+ // An extensionTransaction is only valid within the scope of its encompassing databaseTransaction.
577
+ // I imagine this may occasionally be misunderstood, and developers may attempt to store the extension in an ivar,
578
+ // and then use it outside the context of the database transaction block.
579
+ // Thus, this code is here as a safety net to ensure that such accidental misuse doesn't do any damage.
580
+
581
+ secondaryIndexConnection = nil; // Do not remove !
582
+ databaseTransaction = nil; // Do not remove !
583
+ }
584
+
585
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
586
+ #pragma mark YapDatabaseExtensionTransaction_Hooks
587
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
588
+
589
+ /**
590
+ * YapDatabase extension hook.
591
+ * This method is invoked by a YapDatabaseReadWriteTransaction as a post-operation-hook.
592
+ **/
593
+ - (void)handleInsertObject:(id)object
594
+ forKey:(NSString *)key
595
+ inCollection:(NSString *)collection
596
+ withMetadata:(id)metadata
597
+ rowid:(int64_t)rowid
598
+ {
599
+ YDBLogAutoTrace();
600
+
601
+ __unsafe_unretained YapDatabaseSecondaryIndex *secondaryIndex = secondaryIndexConnection->secondaryIndex;
602
+
603
+ // Invoke the block to find out if the object should be included in the index.
604
+
605
+ if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithKey)
606
+ {
607
+ __unsafe_unretained YapDatabaseSecondaryIndexWithKeyBlock block =
608
+ (YapDatabaseSecondaryIndexWithKeyBlock)secondaryIndex->block;
609
+
610
+ block(secondaryIndexConnection->blockDict, collection, key);
611
+ }
612
+ else if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithObject)
613
+ {
614
+ __unsafe_unretained YapDatabaseSecondaryIndexWithObjectBlock block =
615
+ (YapDatabaseSecondaryIndexWithObjectBlock)secondaryIndex->block;
616
+
617
+ block(secondaryIndexConnection->blockDict, collection, key, object);
618
+ }
619
+ else if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithMetadata)
620
+ {
621
+ __unsafe_unretained YapDatabaseSecondaryIndexWithMetadataBlock block =
622
+ (YapDatabaseSecondaryIndexWithMetadataBlock)secondaryIndex->block;
623
+
624
+ block(secondaryIndexConnection->blockDict, collection, key, metadata);
625
+ }
626
+ else
627
+ {
628
+ __unsafe_unretained YapDatabaseSecondaryIndexWithRowBlock block =
629
+ (YapDatabaseSecondaryIndexWithRowBlock)secondaryIndex->block;
630
+
631
+ block(secondaryIndexConnection->blockDict, collection, key, object, metadata);
632
+ }
633
+
634
+ if ([secondaryIndexConnection->blockDict count] == 0)
635
+ {
636
+ // This was an insert operation, so we don't have to worry about removing anything.
637
+ }
638
+ else
639
+ {
640
+ // Add values to index.
641
+ // This was an insert operation, so we know we can insert rather than update.
642
+
643
+ [self addRowid:rowid isNew:YES];
644
+ [secondaryIndexConnection->blockDict removeAllObjects];
645
+ }
646
+ }
647
+
648
+ /**
649
+ * YapDatabase extension hook.
650
+ * This method is invoked by a YapDatabaseReadWriteTransaction as a post-operation-hook.
651
+ **/
652
+ - (void)handleUpdateObject:(id)object
653
+ forKey:(NSString *)key
654
+ inCollection:(NSString *)collection
655
+ withMetadata:(id)metadata
656
+ rowid:(int64_t)rowid
657
+ {
658
+ YDBLogAutoTrace();
659
+
660
+ __unsafe_unretained YapDatabaseSecondaryIndex *secondaryIndex = secondaryIndexConnection->secondaryIndex;
661
+
662
+ // Invoke the block to find out if the object should be included in the index.
663
+
664
+ if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithKey)
665
+ {
666
+ __unsafe_unretained YapDatabaseSecondaryIndexWithKeyBlock block =
667
+ (YapDatabaseSecondaryIndexWithKeyBlock)secondaryIndex->block;
668
+
669
+ block(secondaryIndexConnection->blockDict, collection, key);
670
+ }
671
+ else if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithObject)
672
+ {
673
+ __unsafe_unretained YapDatabaseSecondaryIndexWithObjectBlock block =
674
+ (YapDatabaseSecondaryIndexWithObjectBlock)secondaryIndex->block;
675
+
676
+ block(secondaryIndexConnection->blockDict, collection, key, object);
677
+ }
678
+ else if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithMetadata)
679
+ {
680
+ __unsafe_unretained YapDatabaseSecondaryIndexWithMetadataBlock block =
681
+ (YapDatabaseSecondaryIndexWithMetadataBlock)secondaryIndex->block;
682
+
683
+ block(secondaryIndexConnection->blockDict, collection, key, metadata);
684
+ }
685
+ else
686
+ {
687
+ __unsafe_unretained YapDatabaseSecondaryIndexWithRowBlock block =
688
+ (YapDatabaseSecondaryIndexWithRowBlock)secondaryIndex->block;
689
+
690
+ block(secondaryIndexConnection->blockDict, collection, key, object, metadata);
691
+ }
692
+
693
+ if ([secondaryIndexConnection->blockDict count] == 0)
694
+ {
695
+ // Remove associated values from index (if needed).
696
+ // This was an update operation, so the rowid may have previously had values in the index.
697
+
698
+ [self removeRowid:rowid];
699
+ }
700
+ else
701
+ {
702
+ // Add values to index (or update them).
703
+ // This was an update operation, so we need to insert or update.
704
+
705
+ [self addRowid:rowid isNew:NO];
706
+ [secondaryIndexConnection->blockDict removeAllObjects];
707
+ }
708
+ }
709
+
710
+ /**
711
+ * YapDatabase extension hook.
712
+ * This method is invoked by a YapDatabaseReadWriteTransaction as a post-operation-hook.
713
+ **/
714
+ - (void)handleUpdateMetadata:(id)metadata
715
+ forKey:(NSString *)key
716
+ inCollection:(NSString *)collection
717
+ withRowid:(int64_t)rowid
718
+ {
719
+ YDBLogAutoTrace();
720
+
721
+ __unsafe_unretained YapDatabaseSecondaryIndex *secondaryIndex = secondaryIndexConnection->secondaryIndex;
722
+
723
+ // Invoke the block to find out if the object should be included in the index.
724
+
725
+ id object = nil;
726
+
727
+ if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithKey ||
728
+ secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithObject)
729
+ {
730
+ // Index values are based on the key or object.
731
+ // Neither have changed, and thus the values haven't changed.
732
+
733
+ return;
734
+ }
735
+ else
736
+ {
737
+ // Index values are based on metadata or objectAndMetadata.
738
+ // Invoke block to see what the new values are.
739
+
740
+ if (secondaryIndex->blockType == YapDatabaseSecondaryIndexBlockTypeWithMetadata)
741
+ {
742
+ __unsafe_unretained YapDatabaseSecondaryIndexWithMetadataBlock block =
743
+ (YapDatabaseSecondaryIndexWithMetadataBlock)secondaryIndex->block;
744
+
745
+ block(secondaryIndexConnection->blockDict, collection, key, metadata);
746
+ }
747
+ else
748
+ {
749
+ __unsafe_unretained YapDatabaseSecondaryIndexWithRowBlock block =
750
+ (YapDatabaseSecondaryIndexWithRowBlock)secondaryIndex->block;
751
+
752
+ object = [databaseTransaction objectForKey:key inCollection:collection];
753
+ block(secondaryIndexConnection->blockDict, collection, key, object, metadata);
754
+ }
755
+
756
+ if ([secondaryIndexConnection->blockDict count] == 0)
757
+ {
758
+ // Remove associated values from index (if needed).
759
+ // This was an update operation, so the rowid may have previously had values in the index.
760
+
761
+ [self removeRowid:rowid];
762
+ }
763
+ else
764
+ {
765
+ // Add values to index (or update them).
766
+ // This was an update operation, so we need to insert or update.
767
+
768
+ [self addRowid:rowid isNew:NO];
769
+ [secondaryIndexConnection->blockDict removeAllObjects];
770
+ }
771
+ }
772
+ }
773
+
774
+ /**
775
+ * YapDatabase extension hook.
776
+ * This method is invoked by a YapDatabaseReadWriteTransaction as a post-operation-hook.
777
+ **/
778
+ - (void)handleTouchObjectForKey:(NSString *)key inCollection:(NSString *)collection withRowid:(int64_t)rowid
779
+ {
780
+ // Nothing to do for this extension
781
+ }
782
+
783
+ /**
784
+ * YapDatabase extension hook.
785
+ * This method is invoked by a YapDatabaseReadWriteTransaction as a post-operation-hook.
786
+ **/
787
+ - (void)handleTouchMetadataForKey:(NSString *)key inCollection:(NSString *)collection withRowid:(int64_t)rowid
788
+ {
789
+ // Nothing to do for this extension
790
+ }
791
+
792
+ /**
793
+ * YapDatabase extension hook.
794
+ * This method is invoked by a YapDatabaseReadWriteTransaction as a post-operation-hook.
795
+ **/
796
+ - (void)handleRemoveObjectForKey:(NSString *)key inCollection:(NSString *)collection withRowid:(int64_t)rowid
797
+ {
798
+ YDBLogAutoTrace();
799
+
800
+ [self removeRowid:rowid];
801
+ }
802
+
803
+ /**
804
+ * YapDatabase extension hook.
805
+ * This method is invoked by a YapDatabaseReadWriteTransaction as a post-operation-hook.
806
+ **/
807
+ - (void)handleRemoveObjectsForKeys:(NSArray *)keys inCollection:(NSString *)collection withRowids:(NSArray *)rowids
808
+ {
809
+ YDBLogAutoTrace();
810
+
811
+ [self removeRowids:rowids];
812
+ }
813
+
814
+ /**
815
+ * YapDatabase extension hook.
816
+ * This method is invoked by a YapDatabaseReadWriteTransaction as a post-operation-hook.
817
+ **/
818
+ - (void)handleRemoveAllObjectsInAllCollections
819
+ {
820
+ YDBLogAutoTrace();
821
+
822
+ [self removeAllRowids];
823
+ }
824
+
825
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
826
+ #pragma mark Enumerate
827
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
828
+
829
+ - (BOOL)_enumerateRowidsMatchingQuery:(YapDatabaseQuery *)query
830
+ usingBlock:(void (^)(int64_t rowid, BOOL *stop))block
831
+ {
832
+ // Create full query using given filtering clause(s)
833
+
834
+ NSString *fullQueryString =
835
+ [NSString stringWithFormat:@"SELECT \"rowid\" FROM \"%@\" %@;", [self tableName], query.queryString];
836
+
837
+ // Turn query into compiled sqlite statement.
838
+ // Use cache if possible.
839
+
840
+ sqlite3_stmt *statement = NULL;
841
+
842
+ YapDatabaseStatement *wrapper = [secondaryIndexConnection->queryCache objectForKey:fullQueryString];
843
+ if (wrapper)
844
+ {
845
+ statement = wrapper.stmt;
846
+ }
847
+ else
848
+ {
849
+ sqlite3 *db = databaseTransaction->connection->db;
850
+
851
+ int status = sqlite3_prepare_v2(db, [fullQueryString UTF8String], -1, &statement, NULL);
852
+ if (status != SQLITE_OK)
853
+ {
854
+ YDBLogError(@"%@: Error creating query:\n query: '%@'\n error: %d %s",
855
+ THIS_METHOD, fullQueryString, status, sqlite3_errmsg(db));
856
+
857
+ return NO;
858
+ }
859
+
860
+ if (secondaryIndexConnection->queryCache)
861
+ {
862
+ wrapper = [[YapDatabaseStatement alloc] initWithStatement:statement];
863
+ [secondaryIndexConnection->queryCache setObject:wrapper forKey:fullQueryString];
864
+ }
865
+ }
866
+
867
+ // Bind query parameters appropriately.
868
+
869
+ int i = 1;
870
+ for (id value in query.queryParameters)
871
+ {
872
+ if ([value isKindOfClass:[NSNumber class]])
873
+ {
874
+ __unsafe_unretained NSNumber *cast = (NSNumber *)value;
875
+
876
+ CFNumberType numType = CFNumberGetType((__bridge CFNumberRef)cast);
877
+
878
+ if (numType == kCFNumberFloatType ||
879
+ numType == kCFNumberFloat32Type ||
880
+ numType == kCFNumberFloat64Type ||
881
+ numType == kCFNumberDoubleType ||
882
+ numType == kCFNumberCGFloatType )
883
+ {
884
+ double num = [cast doubleValue];
885
+ sqlite3_bind_double(statement, i, num);
886
+ }
887
+ else
888
+ {
889
+ int64_t num = [cast longLongValue];
890
+ sqlite3_bind_int64(statement, i, (sqlite3_int64)num);
891
+ }
892
+ }
893
+ else if ([value isKindOfClass:[NSDate class]])
894
+ {
895
+ __unsafe_unretained NSDate *cast = (NSDate *)value;
896
+
897
+ double num = [cast timeIntervalSinceReferenceDate];
898
+ sqlite3_bind_double(statement, i, num);
899
+ }
900
+ else if ([value isKindOfClass:[NSString class]])
901
+ {
902
+ __unsafe_unretained NSString *cast = (NSString *)value;
903
+
904
+ sqlite3_bind_text(statement, i, [cast UTF8String], -1, SQLITE_TRANSIENT);
905
+ }
906
+ else
907
+ {
908
+ YDBLogWarn(@"Unable to bind value for with unsupported class: %@", NSStringFromClass([value class]));
909
+ }
910
+
911
+ i++;
912
+ }
913
+
914
+ // Enumerate query results
915
+
916
+ BOOL stop = NO;
917
+ isMutated = NO; // mutation during enumeration protection
918
+
919
+ int status = sqlite3_step(statement);
920
+ if (status == SQLITE_ROW)
921
+ {
922
+ if (databaseTransaction->connection->needsMarkSqlLevelSharedReadLock)
923
+ [databaseTransaction->connection markSqlLevelSharedReadLockAcquired];
924
+
925
+ do
926
+ {
927
+ int64_t rowid = sqlite3_column_int64(statement, 0);
928
+
929
+ block(rowid, &stop);
930
+
931
+ if (stop || isMutated) break;
932
+
933
+ } while ((status = sqlite3_step(statement)) == SQLITE_ROW);
934
+ }
935
+
936
+ if ((status != SQLITE_DONE) && !stop && !isMutated)
937
+ {
938
+ YDBLogError(@"%@ - sqlite_step error: %d %s", THIS_METHOD,
939
+ status, sqlite3_errmsg(databaseTransaction->connection->db));
940
+ }
941
+
942
+ sqlite3_clear_bindings(statement);
943
+ sqlite3_reset(statement);
944
+
945
+ if (isMutated && !stop)
946
+ {
947
+ @throw [self mutationDuringEnumerationException];
948
+ }
949
+
950
+ return (status == SQLITE_DONE);
951
+ }
952
+
953
+ - (BOOL)enumerateKeysMatchingQuery:(YapDatabaseQuery *)query
954
+ usingBlock:(void (^)(NSString *collection, NSString *key, BOOL *stop))block
955
+ {
956
+ if (query == nil) return NO;
957
+ if (block == nil) return NO;
958
+
959
+ BOOL result = [self _enumerateRowidsMatchingQuery:query usingBlock:^(int64_t rowid, BOOL *stop) {
960
+
961
+ NSString *key = nil;
962
+ NSString *collection = nil;
963
+ [databaseTransaction getKey:&key collection:&collection forRowid:rowid];
964
+
965
+ block(collection, key, stop);
966
+ }];
967
+
968
+ return result;
969
+ }
970
+
971
+ - (BOOL)enumerateKeysAndMetadataMatchingQuery:(YapDatabaseQuery *)query
972
+ usingBlock:
973
+ (void (^)(NSString *collection, NSString *key, id metadata, BOOL *stop))block
974
+ {
975
+ if (query == nil) return NO;
976
+ if (block == nil) return NO;
977
+
978
+ BOOL result = [self _enumerateRowidsMatchingQuery:query usingBlock:^(int64_t rowid, BOOL *stop) {
979
+
980
+ NSString *key = nil;
981
+ NSString *collection = nil;
982
+ id metadata = nil;
983
+ [databaseTransaction getKey:&key collection:&collection metadata:&metadata forRowid:rowid];
984
+
985
+ block(collection, key, metadata, stop);
986
+ }];
987
+
988
+ return result;
989
+ }
990
+
991
+ - (BOOL)enumerateKeysAndObjectsMatchingQuery:(YapDatabaseQuery *)query
992
+ usingBlock:
993
+ (void (^)(NSString *collection, NSString *key, id object, BOOL *stop))block
994
+ {
995
+ if (query == nil) return NO;
996
+ if (block == nil) return NO;
997
+
998
+ BOOL result = [self _enumerateRowidsMatchingQuery:query usingBlock:^(int64_t rowid, BOOL *stop) {
999
+
1000
+ NSString *key = nil;
1001
+ NSString *collection = nil;
1002
+ id object = nil;
1003
+ [databaseTransaction getKey:&key collection:&collection object:&object forRowid:rowid];
1004
+
1005
+ block(collection, key, object, stop);
1006
+ }];
1007
+
1008
+ return result;
1009
+ }
1010
+
1011
+ - (BOOL)enumerateRowsMatchingQuery:(YapDatabaseQuery *)query
1012
+ usingBlock:
1013
+ (void (^)(NSString *collection, NSString *key, id object, id metadata, BOOL *stop))block
1014
+ {
1015
+ if (query == nil) return NO;
1016
+ if (block == nil) return NO;
1017
+
1018
+ BOOL result = [self _enumerateRowidsMatchingQuery:query usingBlock:^(int64_t rowid, BOOL *stop) {
1019
+
1020
+ NSString *key = nil;
1021
+ NSString *collection = nil;
1022
+ id object = nil;
1023
+ id metadata = nil;
1024
+ [databaseTransaction getKey:&key collection:&collection object:&object metadata:&metadata forRowid:rowid];
1025
+
1026
+ block(collection, key, object, metadata, stop);
1027
+ }];
1028
+
1029
+ return result;
1030
+ }
1031
+
1032
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1033
+ #pragma mark Count
1034
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1035
+
1036
+ - (BOOL)getNumberOfRows:(NSUInteger *)countPtr matchingQuery:(YapDatabaseQuery *)query
1037
+ {
1038
+ // Create full query using given filtering clause(s)
1039
+
1040
+ NSString *fullQueryString =
1041
+ [NSString stringWithFormat:@"SELECT COUNT(*) AS NumberOfRows FROM \"%@\" %@;",
1042
+ [self tableName], query.queryString];
1043
+
1044
+ // Turn query into compiled sqlite statement.
1045
+ // Use cache if possible.
1046
+
1047
+ sqlite3_stmt *statement = NULL;
1048
+
1049
+ YapDatabaseStatement *wrapper = [secondaryIndexConnection->queryCache objectForKey:fullQueryString];
1050
+ if (wrapper)
1051
+ {
1052
+ statement = wrapper.stmt;
1053
+ }
1054
+ else
1055
+ {
1056
+ sqlite3 *db = databaseTransaction->connection->db;
1057
+
1058
+ int status = sqlite3_prepare_v2(db, [fullQueryString UTF8String], -1, &statement, NULL);
1059
+ if (status != SQLITE_OK)
1060
+ {
1061
+ YDBLogError(@"%@: Error creating query:\n query: '%@'\n error: %d %s",
1062
+ THIS_METHOD, fullQueryString, status, sqlite3_errmsg(db));
1063
+
1064
+ return NO;
1065
+ }
1066
+
1067
+ if (secondaryIndexConnection->queryCache)
1068
+ {
1069
+ wrapper = [[YapDatabaseStatement alloc] initWithStatement:statement];
1070
+ [secondaryIndexConnection->queryCache setObject:wrapper forKey:fullQueryString];
1071
+ }
1072
+ }
1073
+
1074
+ // Bind query parameters appropriately.
1075
+
1076
+ int i = 1;
1077
+ for (id value in query.queryParameters)
1078
+ {
1079
+ if ([value isKindOfClass:[NSNumber class]])
1080
+ {
1081
+ __unsafe_unretained NSNumber *cast = (NSNumber *)value;
1082
+
1083
+ CFNumberType numType = CFNumberGetType((__bridge CFNumberRef)cast);
1084
+
1085
+ if (numType == kCFNumberFloatType ||
1086
+ numType == kCFNumberFloat32Type ||
1087
+ numType == kCFNumberFloat64Type ||
1088
+ numType == kCFNumberDoubleType ||
1089
+ numType == kCFNumberCGFloatType )
1090
+ {
1091
+ double num = [cast doubleValue];
1092
+ sqlite3_bind_double(statement, i, num);
1093
+ }
1094
+ else
1095
+ {
1096
+ int64_t num = [cast longLongValue];
1097
+ sqlite3_bind_int64(statement, i, (sqlite3_int64)num);
1098
+ }
1099
+ }
1100
+ else if ([value isKindOfClass:[NSDate class]])
1101
+ {
1102
+ __unsafe_unretained NSDate *cast = (NSDate *)value;
1103
+
1104
+ double num = [cast timeIntervalSinceReferenceDate];
1105
+ sqlite3_bind_double(statement, i, num);
1106
+ }
1107
+ else if ([value isKindOfClass:[NSString class]])
1108
+ {
1109
+ __unsafe_unretained NSString *cast = (NSString *)value;
1110
+
1111
+ sqlite3_bind_text(statement, i, [cast UTF8String], -1, SQLITE_TRANSIENT);
1112
+ }
1113
+ else
1114
+ {
1115
+ YDBLogWarn(@"Unable to bind value for with unsupported class: %@", NSStringFromClass([value class]));
1116
+ }
1117
+
1118
+ i++;
1119
+ }
1120
+
1121
+ // Execute query
1122
+
1123
+ BOOL result = YES;
1124
+ NSUInteger count = 0;
1125
+
1126
+ int status = sqlite3_step(statement);
1127
+ if (status == SQLITE_ROW)
1128
+ {
1129
+ if (databaseTransaction->connection->needsMarkSqlLevelSharedReadLock)
1130
+ [databaseTransaction->connection markSqlLevelSharedReadLockAcquired];
1131
+
1132
+ count = (NSUInteger)sqlite3_column_int64(statement, 0);
1133
+ }
1134
+ else if (status == SQLITE_ERROR)
1135
+ {
1136
+ YDBLogError(@"%@ - sqlite_step error: %d %s", THIS_METHOD,
1137
+ status, sqlite3_errmsg(databaseTransaction->connection->db));
1138
+ result = NO;
1139
+ }
1140
+
1141
+ sqlite3_clear_bindings(statement);
1142
+ sqlite3_reset(statement);
1143
+
1144
+ if (countPtr) *countPtr = count;
1145
+ return result;
1146
+ }
1147
+
1148
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1149
+ #pragma mark Exceptions
1150
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1151
+
1152
+ - (NSException *)mutationDuringEnumerationException
1153
+ {
1154
+ NSString *reason = [NSString stringWithFormat:
1155
+ @"SecondaryIndex <RegisteredName=%@> was mutated while being enumerated.", [self registeredName]];
1156
+
1157
+ NSDictionary *userInfo = @{ NSLocalizedRecoverySuggestionErrorKey:
1158
+ @"In general, you cannot modify the database while enumerating it."
1159
+ @" This is similar in concept to an NSMutableArray."
1160
+ @" If you only need to make a single modification, you may do so but you MUST set the 'stop' parameter"
1161
+ @" of the enumeration block to YES (*stop = YES;) immediately after making the modification."};
1162
+
1163
+ return [NSException exceptionWithName:@"YapDatabaseException" reason:reason userInfo:userInfo];
1164
+ }
1165
+
1166
+ @end