motion-yapper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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