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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +6 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +63 -0
- data/README.md +16 -0
- data/Rakefile +20 -0
- data/app/app_delegate.rb +5 -0
- data/lib/yapper.rb +30 -0
- data/lib/yapper/attachment.rb +48 -0
- data/lib/yapper/bson.rb +20 -0
- data/lib/yapper/config.rb +18 -0
- data/lib/yapper/db.rb +151 -0
- data/lib/yapper/document.rb +54 -0
- data/lib/yapper/document/attachment.rb +26 -0
- data/lib/yapper/document/callbacks.rb +86 -0
- data/lib/yapper/document/persistance.rb +171 -0
- data/lib/yapper/document/relation.rb +84 -0
- data/lib/yapper/document/selection.rb +100 -0
- data/lib/yapper/extensions.rb +80 -0
- data/lib/yapper/log.rb +5 -0
- data/lib/yapper/sync.rb +134 -0
- data/lib/yapper/sync/data.rb +12 -0
- data/lib/yapper/sync/event.rb +194 -0
- data/lib/yapper/sync/queue.rb +164 -0
- data/lib/yapper/timestamps.rb +16 -0
- data/lib/yapper/version.rb +3 -0
- data/lib/yapper/yapper.rb +2 -0
- data/spec/helpers/time_helper.rb +3 -0
- data/spec/integration/all_spec.rb +40 -0
- data/spec/integration/callback_spec.rb +87 -0
- data/spec/integration/db_spec.rb +40 -0
- data/spec/integration/find_spec.rb +51 -0
- data/spec/integration/persistance_spec.rb +118 -0
- data/spec/integration/relation_spec.rb +174 -0
- data/spec/integration/sync_spec.rb +42 -0
- data/spec/integration/timestamps_spec.rb +34 -0
- data/spec/integration/types_spec.rb +23 -0
- data/spec/integration/when_spec.rb +29 -0
- data/spec/integration/where_spec.rb +132 -0
- data/vendor/Podfile.lock +24 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPClient.h +641 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPClient.m +1396 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.h +133 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m +327 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFImageRequestOperation.h +113 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFImageRequestOperation.m +321 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFJSONRequestOperation.h +71 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFJSONRequestOperation.m +150 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFNetworkActivityIndicatorManager.m +157 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFNetworking.h +43 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFPropertyListRequestOperation.h +68 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFPropertyListRequestOperation.m +143 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h +370 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.m +848 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFXMLRequestOperation.h +89 -0
- data/vendor/Pods/AFNetworking/AFNetworking/AFXMLRequestOperation.m +167 -0
- data/vendor/Pods/AFNetworking/AFNetworking/UIImageView+AFNetworking.h +78 -0
- data/vendor/Pods/AFNetworking/AFNetworking/UIImageView+AFNetworking.m +191 -0
- data/vendor/Pods/AFNetworking/LICENSE +19 -0
- data/vendor/Pods/AFNetworking/README.md +208 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFHTTPClient.h +641 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFHTTPRequestOperation.h +133 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFImageRequestOperation.h +113 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFJSONRequestOperation.h +71 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFNetworking.h +43 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFPropertyListRequestOperation.h +68 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFURLConnectionOperation.h +370 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/AFXMLRequestOperation.h +89 -0
- data/vendor/Pods/BuildHeaders/AFNetworking/UIImageView+AFNetworking.h +78 -0
- data/vendor/Pods/BuildHeaders/CocoaLumberjack/ContextFilterLogFormatter.h +65 -0
- data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDASLLogger.h +41 -0
- data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDAbstractDatabaseLogger.h +102 -0
- data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDFileLogger.h +334 -0
- data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDLog.h +601 -0
- data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDTTYLogger.h +167 -0
- data/vendor/Pods/BuildHeaders/CocoaLumberjack/DispatchQueueLogFormatter.h +116 -0
- data/vendor/Pods/BuildHeaders/NSData+MD5Digest/NSData+MD5Digest.h +18 -0
- data/vendor/Pods/BuildHeaders/Reachability/Reachability.h +109 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapCache.h +90 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapCollectionKey.h +20 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabase.h +547 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseConnection.h +447 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseConnectionState.h +29 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseDefaults.h +37 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtension.h +15 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionConnection.h +11 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionPrivate.h +440 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionTransaction.h +11 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredView.h +108 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewConnection.h +12 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewPrivate.h +19 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewTransaction.h +39 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearch.h +89 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchConnection.h +32 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchPrivate.h +69 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchSnippetOptions.h +79 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchTransaction.h +68 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseLogging.h +158 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseManager.h +17 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabasePrivate.h +424 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseQuery.h +42 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndex.h +100 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexConnection.h +33 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexPrivate.h +73 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexSetup.h +33 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexTransaction.h +58 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseStatement.h +13 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseString.h +121 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseTransaction.h +541 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseView.h +186 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewChange.h +272 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewChangePrivate.h +94 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewConnection.h +115 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewMappings.h +825 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewMappingsPrivate.h +72 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewOptions.h +56 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPage.h +36 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPageMetadata.h +27 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPrivate.h +153 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewRangeOptions.h +330 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewRangeOptionsPrivate.h +17 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewTransaction.h +447 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapMemoryTable.h +74 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapNull.h +17 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapSet.h +41 -0
- data/vendor/Pods/BuildHeaders/YapDatabase/YapTouch.h +15 -0
- data/vendor/Pods/CocoaLumberjack/LICENSE.txt +18 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h +41 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m +99 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h +102 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m +727 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h +334 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m +1353 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDLog.h +601 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDLog.m +1083 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h +167 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m +1479 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.h +65 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.m +191 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.h +116 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.m +251 -0
- data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt +7 -0
- data/vendor/Pods/CocoaLumberjack/README.markdown +37 -0
- data/vendor/Pods/Headers/AFNetworking/AFHTTPClient.h +641 -0
- data/vendor/Pods/Headers/AFNetworking/AFHTTPRequestOperation.h +133 -0
- data/vendor/Pods/Headers/AFNetworking/AFImageRequestOperation.h +113 -0
- data/vendor/Pods/Headers/AFNetworking/AFJSONRequestOperation.h +71 -0
- data/vendor/Pods/Headers/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
- data/vendor/Pods/Headers/AFNetworking/AFNetworking.h +43 -0
- data/vendor/Pods/Headers/AFNetworking/AFPropertyListRequestOperation.h +68 -0
- data/vendor/Pods/Headers/AFNetworking/AFURLConnectionOperation.h +370 -0
- data/vendor/Pods/Headers/AFNetworking/AFXMLRequestOperation.h +89 -0
- data/vendor/Pods/Headers/AFNetworking/UIImageView+AFNetworking.h +78 -0
- data/vendor/Pods/Headers/CocoaLumberjack/ContextFilterLogFormatter.h +65 -0
- data/vendor/Pods/Headers/CocoaLumberjack/DDASLLogger.h +41 -0
- data/vendor/Pods/Headers/CocoaLumberjack/DDAbstractDatabaseLogger.h +102 -0
- data/vendor/Pods/Headers/CocoaLumberjack/DDFileLogger.h +334 -0
- data/vendor/Pods/Headers/CocoaLumberjack/DDLog.h +601 -0
- data/vendor/Pods/Headers/CocoaLumberjack/DDTTYLogger.h +167 -0
- data/vendor/Pods/Headers/CocoaLumberjack/DispatchQueueLogFormatter.h +116 -0
- data/vendor/Pods/Headers/NSData+MD5Digest/NSData+MD5Digest.h +18 -0
- data/vendor/Pods/Headers/Reachability/Reachability.h +109 -0
- data/vendor/Pods/Headers/YapDatabase/YapCache.h +90 -0
- data/vendor/Pods/Headers/YapDatabase/YapCollectionKey.h +20 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabase.h +547 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseConnection.h +447 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseConnectionState.h +29 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseDefaults.h +37 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtension.h +15 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtensionConnection.h +11 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtensionPrivate.h +440 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtensionTransaction.h +11 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredView.h +108 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewConnection.h +12 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewPrivate.h +19 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewTransaction.h +39 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearch.h +89 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchConnection.h +32 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchPrivate.h +69 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchSnippetOptions.h +79 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchTransaction.h +68 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseLogging.h +158 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseManager.h +17 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabasePrivate.h +424 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseQuery.h +42 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndex.h +100 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexConnection.h +33 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexPrivate.h +73 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexSetup.h +33 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexTransaction.h +58 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseStatement.h +13 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseString.h +121 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseTransaction.h +541 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseView.h +186 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewChange.h +272 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewChangePrivate.h +94 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewConnection.h +115 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewMappings.h +825 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewMappingsPrivate.h +72 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewOptions.h +56 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewPage.h +36 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewPageMetadata.h +27 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewPrivate.h +153 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewRangeOptions.h +330 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewRangeOptionsPrivate.h +17 -0
- data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewTransaction.h +447 -0
- data/vendor/Pods/Headers/YapDatabase/YapMemoryTable.h +74 -0
- data/vendor/Pods/Headers/YapDatabase/YapNull.h +17 -0
- data/vendor/Pods/Headers/YapDatabase/YapSet.h +41 -0
- data/vendor/Pods/Headers/YapDatabase/YapTouch.h +15 -0
- data/vendor/Pods/Headers/____Pods-AFNetworking-prefix.h +17 -0
- data/vendor/Pods/Headers/____Pods-CocoaLumberjack-prefix.h +5 -0
- data/vendor/Pods/Headers/____Pods-NSData+MD5Digest-prefix.h +5 -0
- data/vendor/Pods/Headers/____Pods-Reachability-prefix.h +5 -0
- data/vendor/Pods/Headers/____Pods-YapDatabase-prefix.h +5 -0
- data/vendor/Pods/Headers/____Pods-environment.h +38 -0
- data/vendor/Pods/Manifest.lock +24 -0
- data/vendor/Pods/NSData+MD5Digest/NSData+MD5Digest/NSData+MD5Digest.h +18 -0
- data/vendor/Pods/NSData+MD5Digest/NSData+MD5Digest/NSData+MD5Digest.m +39 -0
- data/vendor/Pods/NSData+MD5Digest/README.md +11 -0
- data/vendor/Pods/Pods-AFNetworking-Private.xcconfig +5 -0
- data/vendor/Pods/Pods-AFNetworking-dummy.m +5 -0
- data/vendor/Pods/Pods-AFNetworking-prefix.pch +17 -0
- data/vendor/Pods/Pods-AFNetworking.xcconfig +1 -0
- data/vendor/Pods/Pods-Acknowledgements.markdown +96 -0
- data/vendor/Pods/Pods-Acknowledgements.plist +142 -0
- data/vendor/Pods/Pods-CocoaLumberjack-Private.xcconfig +5 -0
- data/vendor/Pods/Pods-CocoaLumberjack-dummy.m +5 -0
- data/vendor/Pods/Pods-CocoaLumberjack-prefix.pch +5 -0
- data/vendor/Pods/Pods-CocoaLumberjack.xcconfig +0 -0
- data/vendor/Pods/Pods-NSData+MD5Digest-Private.xcconfig +5 -0
- data/vendor/Pods/Pods-NSData+MD5Digest-dummy.m +5 -0
- data/vendor/Pods/Pods-NSData+MD5Digest-prefix.pch +5 -0
- data/vendor/Pods/Pods-NSData+MD5Digest.xcconfig +0 -0
- data/vendor/Pods/Pods-Reachability-Private.xcconfig +5 -0
- data/vendor/Pods/Pods-Reachability-dummy.m +5 -0
- data/vendor/Pods/Pods-Reachability-prefix.pch +5 -0
- data/vendor/Pods/Pods-Reachability.xcconfig +1 -0
- data/vendor/Pods/Pods-YapDatabase-Private.xcconfig +5 -0
- data/vendor/Pods/Pods-YapDatabase-dummy.m +5 -0
- data/vendor/Pods/Pods-YapDatabase-prefix.pch +5 -0
- data/vendor/Pods/Pods-YapDatabase.xcconfig +1 -0
- data/vendor/Pods/Pods-dummy.m +5 -0
- data/vendor/Pods/Pods-environment.h +38 -0
- data/vendor/Pods/Pods-resources.sh +68 -0
- data/vendor/Pods/Pods.bridgesupport +5096 -0
- data/vendor/Pods/Pods.xcconfig +5 -0
- data/vendor/Pods/Pods.xcodeproj/project.pbxproj +5536 -0
- data/vendor/Pods/Reachability/LICENCE.txt +24 -0
- data/vendor/Pods/Reachability/README.md +65 -0
- data/vendor/Pods/Reachability/Reachability.h +109 -0
- data/vendor/Pods/Reachability/Reachability.m +527 -0
- data/vendor/Pods/YapDatabase/LICENSE.txt +18 -0
- data/vendor/Pods/YapDatabase/README.md +30 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/Internal/YapDatabaseFilteredViewPrivate.h +19 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredView.h +108 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredView.m +175 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewConnection.h +12 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewConnection.m +41 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTransaction.h +39 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTransaction.m +966 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/Internal/YapDatabaseFullTextSearchPrivate.h +69 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearch.h +89 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearch.m +146 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchConnection.h +32 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchConnection.m +298 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchSnippetOptions.h +79 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchSnippetOptions.m +95 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchTransaction.h +68 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchTransaction.m +1352 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/Internal/YapDatabaseExtensionPrivate.h +440 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtension.h +15 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtension.m +58 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionConnection.h +11 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionConnection.m +46 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.h +11 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.m +180 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/Internal/YapDatabaseSecondaryIndexPrivate.h +73 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndex.h +100 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndex.m +149 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexConnection.h +33 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexConnection.m +330 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexSetup.h +33 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexSetup.m +184 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexTransaction.h +58 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexTransaction.m +1166 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewChangePrivate.h +94 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewMappingsPrivate.h +72 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPage.h +36 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPage.mm +296 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPageMetadata.h +27 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPageMetadata.m +28 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPrivate.h +153 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewRangeOptionsPrivate.h +17 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewChange.h +272 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewChange.m +2494 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewMappings.h +825 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewMappings.m +1567 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewRangeOptions.h +330 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewRangeOptions.m +141 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseView.h +186 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseView.m +191 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewConnection.h +115 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewConnection.m +897 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewOptions.h +56 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewOptions.m +27 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewTransaction.h +447 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewTransaction.m +4505 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapCache.h +90 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapCache.m +453 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseConnectionState.h +29 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseConnectionState.m +48 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseDefaults.h +37 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseDefaults.m +83 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseLogging.h +158 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseLogging.m +73 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseManager.h +17 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseManager.m +56 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabasePrivate.h +424 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseStatement.h +13 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseStatement.m +26 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseString.h +121 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapMemoryTable.h +74 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapMemoryTable.m +603 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapNull.h +17 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapNull.m +31 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapTouch.h +15 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapTouch.m +31 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapCollectionKey.h +20 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapCollectionKey.m +194 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapDatabaseQuery.h +42 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapDatabaseQuery.m +96 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapSet.h +41 -0
- data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapSet.m +82 -0
- data/vendor/Pods/YapDatabase/YapDatabase/YapDatabase.h +547 -0
- data/vendor/Pods/YapDatabase/YapDatabase/YapDatabase.m +2022 -0
- data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseConnection.h +447 -0
- data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseConnection.m +3874 -0
- data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseTransaction.h +541 -0
- data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseTransaction.m +5282 -0
- data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.bridgesupport +16 -0
- data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.h +13 -0
- data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.m +20 -0
- data/yapper.gemspec +24 -0
- metadata +458 -0
data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexSetup.h
ADDED
|
@@ -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
|
data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexSetup.m
ADDED
|
@@ -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
|