From 4ff05c6018435aecd238809ddb2f0e36d697002f Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 21 Jul 2016 15:12:12 +0100 Subject: [PATCH 01/36] Run tests on Xcode8-beta --- .travis.yml | 7 +++++++ CocoaPods/iphoneos-10.0/module.modulemap | 4 ++++ .../iphonesimulator-10.0/module.modulemap | 4 ++++ CocoaPods/macosx-10.12/module.modulemap | 4 ++++ Makefile | 2 +- SQLite.xcodeproj/project.pbxproj | 18 ++++++++++++++++++ 6 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 CocoaPods/iphoneos-10.0/module.modulemap create mode 100644 CocoaPods/iphonesimulator-10.0/module.modulemap create mode 100644 CocoaPods/macosx-10.12/module.modulemap diff --git a/.travis.yml b/.travis.yml index b33f9af3..e4d9fe7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,13 @@ language: objective-c matrix: + include: + - os: osx + osx_image: xcode8 + env: BUILD_SCHEME="SQLite iOS" + - os: osx + osx_image: xcode8 + env: BUILD_SCHEME="SQLite Mac" - env: BUILD_SCHEME="SQLite iOS" - env: BUILD_SCHEME="SQLite Mac" - env: VALIDATOR_SUBSPEC="none" diff --git a/CocoaPods/iphoneos-10.0/module.modulemap b/CocoaPods/iphoneos-10.0/module.modulemap new file mode 100644 index 00000000..67a6c203 --- /dev/null +++ b/CocoaPods/iphoneos-10.0/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/usr/include/sqlite3.h" + export * +} diff --git a/CocoaPods/iphonesimulator-10.0/module.modulemap b/CocoaPods/iphonesimulator-10.0/module.modulemap new file mode 100644 index 00000000..c8b84ab8 --- /dev/null +++ b/CocoaPods/iphonesimulator-10.0/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.0.sdk/usr/include/sqlite3.h" + export * +} diff --git a/CocoaPods/macosx-10.12/module.modulemap b/CocoaPods/macosx-10.12/module.modulemap new file mode 100644 index 00000000..8fc958e6 --- /dev/null +++ b/CocoaPods/macosx-10.12/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Makefile b/Makefile index 7257b9b1..059a20b1 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ BUILD_TOOL = xcodebuild BUILD_SCHEME = SQLite Mac ifeq ($(BUILD_SCHEME),SQLite iOS) - BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" -sdk iphonesimulator + BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" -destination "platform=iOS Simulator,name=iPhone 6" else BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" endif diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index d431ff3c..59bce055 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -686,15 +686,19 @@ }; EE247AD21C3F04ED00AE3E12 = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; EE247ADC1C3F04ED00AE3E12 = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; EE247B3B1C3F3ED000AE3E12 = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; EE247B441C3F3ED000AE3E12 = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; }; }; @@ -1167,8 +1171,11 @@ PRODUCT_NAME = SQLite; SKIP_INSTALL = YES; "SWIFT_INCLUDE_PATHS[sdk=iphoneos*]" = "$(SRCROOT)/CocoaPods/iphoneos"; + "SWIFT_INCLUDE_PATHS[sdk=iphoneos10.0]" = "$(SRCROOT)/CocoaPods/iphoneos-10.0"; "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]" = "$(SRCROOT)/CocoaPods/iphonesimulator"; + "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator10.0]" = "$(SRCROOT)/CocoaPods/iphonesimulator-10.0"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 2.3; }; name = Debug; }; @@ -1189,7 +1196,10 @@ PRODUCT_NAME = SQLite; SKIP_INSTALL = YES; "SWIFT_INCLUDE_PATHS[sdk=iphoneos*]" = "$(SRCROOT)/CocoaPods/iphoneos"; + "SWIFT_INCLUDE_PATHS[sdk=iphoneos10.0]" = "$(SRCROOT)/CocoaPods/iphoneos-10.0"; "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]" = "$(SRCROOT)/CocoaPods/iphonesimulator"; + "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator10.0]" = "$(SRCROOT)/CocoaPods/iphonesimulator-10.0"; + SWIFT_VERSION = 2.3; }; name = Release; }; @@ -1200,6 +1210,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 2.3; }; name = Debug; }; @@ -1210,6 +1221,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 2.3; }; name = Release; }; @@ -1234,6 +1246,8 @@ SKIP_INSTALL = YES; SWIFT_INCLUDE_PATHS = ""; "SWIFT_INCLUDE_PATHS[sdk=macosx*]" = "$(SRCROOT)/CocoaPods/macosx"; + "SWIFT_INCLUDE_PATHS[sdk=macosx10.12]" = "$(SRCROOT)/CocoaPods/macosx-10.12"; + SWIFT_VERSION = 2.3; }; name = Debug; }; @@ -1258,6 +1272,8 @@ SKIP_INSTALL = YES; SWIFT_INCLUDE_PATHS = ""; "SWIFT_INCLUDE_PATHS[sdk=macosx*]" = "$(SRCROOT)/CocoaPods/macosx"; + "SWIFT_INCLUDE_PATHS[sdk=macosx10.12]" = "$(SRCROOT)/CocoaPods/macosx-10.12"; + SWIFT_VERSION = 2.3; }; name = Release; }; @@ -1272,6 +1288,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + SWIFT_VERSION = 2.3; }; name = Debug; }; @@ -1286,6 +1303,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + SWIFT_VERSION = 2.3; }; name = Release; }; From 4cdfd69bf405bf5eb91bc31203af3fd536097851 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 24 Aug 2016 12:12:51 +0100 Subject: [PATCH 02/36] Validate pod on xcode8 --- .travis.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.travis.yml b/.travis.yml index e4d9fe7b..c40d8e39 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,15 @@ matrix: - os: osx osx_image: xcode8 env: BUILD_SCHEME="SQLite Mac" + - os: osx + osx_image: xcode8 + env: VALIDATOR_SUBSPEC="none" + - os: osx + osx_image: xcode8 + env: VALIDATOR_SUBSPEC="standard" + - os: osx + osx_image: xcode8 + env: VALIDATOR_SUBSPEC="standalone" - env: BUILD_SCHEME="SQLite iOS" - env: BUILD_SCHEME="SQLite Mac" - env: VALIDATOR_SUBSPEC="none" From ed8980cf35b1756a1a4453378bb0bcebddc6890b Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 24 Aug 2016 12:57:44 +0100 Subject: [PATCH 03/36] Run tests on iPhone 6 --- CocoaPodsTests/test_running_validator.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CocoaPodsTests/test_running_validator.rb b/CocoaPodsTests/test_running_validator.rb index 10f4db61..ab0e12ed 100644 --- a/CocoaPodsTests/test_running_validator.rb +++ b/CocoaPodsTests/test_running_validator.rb @@ -7,6 +7,14 @@ class TestRunningValidator < Pod::Validator TEST_TARGET = 'Tests' attr_accessor :test_files + attr_accessor :iphone_simulator + attr_accessor :tvos_simulator + + def initialize(spec_or_path, source_urls) + super(spec_or_path, source_urls) + self.iphone_simulator = 'iPhone 6' + self.tvos_simulator = 'Apple TV 1080p' + end def create_app_project super.tap do @@ -67,12 +75,12 @@ def run_tests case consumer.platform_name when :ios command += %w(CODE_SIGN_IDENTITY=- -sdk iphonesimulator) - command += Fourflusher::SimControl.new.destination('iPhone 4s', deployment_target) + command += Fourflusher::SimControl.new.destination(iphone_simulator, deployment_target) when :osx command += %w(LD_RUNPATH_SEARCH_PATHS=@loader_path/../Frameworks) when :tvos command += %w(CODE_SIGN_IDENTITY=- -sdk appletvsimulator) - command += Fourflusher::SimControl.new.destination('Apple TV 1080p', deployment_target) + command += Fourflusher::SimControl.new.destination(tvos_simulator, deployment_target) else return # skip watchos end From 775a26c542cfe21026e9038460669fe6d3df66be Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 24 Aug 2016 13:17:27 +0100 Subject: [PATCH 04/36] =?UTF-8?q?Don=E2=80=99t=20hardcode=20simulator=20ve?= =?UTF-8?q?rsion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CocoaPodsTests/Gemfile | 2 +- CocoaPodsTests/Gemfile.lock | 39 +++++++++++++----------- CocoaPodsTests/test_running_validator.rb | 8 ++--- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/CocoaPodsTests/Gemfile b/CocoaPodsTests/Gemfile index 0a6af5c8..995a10e4 100644 --- a/CocoaPodsTests/Gemfile +++ b/CocoaPodsTests/Gemfile @@ -1,4 +1,4 @@ source 'https://rubygems.org' -gem 'cocoapods' +gem 'cocoapods', '~> 1.1.0.beta1' gem 'minitest' diff --git a/CocoaPodsTests/Gemfile.lock b/CocoaPodsTests/Gemfile.lock index 7173e2c4..36f2a982 100644 --- a/CocoaPodsTests/Gemfile.lock +++ b/CocoaPodsTests/Gemfile.lock @@ -1,36 +1,37 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.2.6) + activesupport (4.2.7.1) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) claide (1.0.0) - cocoapods (1.0.0) - activesupport (>= 4.0.2) + cocoapods (1.1.0.beta.1) + activesupport (>= 4.0.2, < 5) claide (>= 1.0.0, < 2.0) - cocoapods-core (= 1.0.0) + cocoapods-core (= 1.1.0.beta.1) cocoapods-deintegrate (>= 1.0.0, < 2.0) - cocoapods-downloader (>= 1.0.0, < 2.0) + cocoapods-downloader (>= 1.1.0, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) cocoapods-trunk (>= 1.0.0, < 2.0) - cocoapods-try (>= 1.0.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) colored (~> 1.2) escape (~> 0.0.4) - fourflusher (~> 0.3.0) - molinillo (~> 0.4.5) + fourflusher (~> 1.0.1) + gh_inspector (~> 1.0) + molinillo (~> 0.5.0) nap (~> 1.0) - xcodeproj (>= 1.0.0, < 2.0) - cocoapods-core (1.0.0) + xcodeproj (>= 1.2.0, < 2.0) + cocoapods-core (1.1.0.beta.1) activesupport (>= 4.0.2) fuzzy_match (~> 2.0.4) nap (~> 1.0) cocoapods-deintegrate (1.0.0) - cocoapods-downloader (1.0.0) + cocoapods-downloader (1.1.0) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.0) @@ -38,21 +39,22 @@ GEM cocoapods-trunk (1.0.0) nap (>= 0.8, < 2.0) netrc (= 0.7.8) - cocoapods-try (1.0.0) + cocoapods-try (1.1.0) colored (1.2) escape (0.0.4) - fourflusher (0.3.0) + fourflusher (1.0.1) fuzzy_match (2.0.4) + gh_inspector (1.0.2) i18n (0.7.0) json (1.8.3) - minitest (5.8.4) - molinillo (0.4.5) + minitest (5.9.0) + molinillo (0.5.0) nap (1.1.0) netrc (0.7.8) thread_safe (0.3.5) tzinfo (1.2.2) thread_safe (~> 0.1) - xcodeproj (1.0.0) + xcodeproj (1.2.0) activesupport (>= 3) claide (>= 1.0.0, < 2.0) colored (~> 1.2) @@ -61,5 +63,8 @@ PLATFORMS ruby DEPENDENCIES - cocoapods + cocoapods (~> 1.1.0.beta1) minitest + +BUNDLED WITH + 1.10.6 diff --git a/CocoaPodsTests/test_running_validator.rb b/CocoaPodsTests/test_running_validator.rb index ab0e12ed..e866d873 100644 --- a/CocoaPodsTests/test_running_validator.rb +++ b/CocoaPodsTests/test_running_validator.rb @@ -12,8 +12,8 @@ class TestRunningValidator < Pod::Validator def initialize(spec_or_path, source_urls) super(spec_or_path, source_urls) - self.iphone_simulator = 'iPhone 6' - self.tvos_simulator = 'Apple TV 1080p' + self.iphone_simulator = :oldest + self.tvos_simulator = :oldest end def create_app_project @@ -75,12 +75,12 @@ def run_tests case consumer.platform_name when :ios command += %w(CODE_SIGN_IDENTITY=- -sdk iphonesimulator) - command += Fourflusher::SimControl.new.destination(iphone_simulator, deployment_target) + command += Fourflusher::SimControl.new.destination(iphone_simulator, 'iOS', deployment_target) when :osx command += %w(LD_RUNPATH_SEARCH_PATHS=@loader_path/../Frameworks) when :tvos command += %w(CODE_SIGN_IDENTITY=- -sdk appletvsimulator) - command += Fourflusher::SimControl.new.destination(tvos_simulator, deployment_target) + command += Fourflusher::SimControl.new.destination(tvos_simulator, 'tvOS', deployment_target) else return # skip watchos end From 1cc0a535732cd5000a3d23ae703a25d6b58de8ef Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 13 Sep 2016 14:36:00 +0100 Subject: [PATCH 05/36] Bump cocoapods --- CocoaPodsTests/Gemfile | 2 +- CocoaPodsTests/Gemfile.lock | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CocoaPodsTests/Gemfile b/CocoaPodsTests/Gemfile index 995a10e4..86c90369 100644 --- a/CocoaPodsTests/Gemfile +++ b/CocoaPodsTests/Gemfile @@ -1,4 +1,4 @@ source 'https://rubygems.org' -gem 'cocoapods', '~> 1.1.0.beta1' +gem 'cocoapods', '~> 1.1.0.rc.1' gem 'minitest' diff --git a/CocoaPodsTests/Gemfile.lock b/CocoaPodsTests/Gemfile.lock index 36f2a982..4252e155 100644 --- a/CocoaPodsTests/Gemfile.lock +++ b/CocoaPodsTests/Gemfile.lock @@ -8,12 +8,12 @@ GEM thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) claide (1.0.0) - cocoapods (1.1.0.beta.1) + cocoapods (1.1.0.rc.1) activesupport (>= 4.0.2, < 5) claide (>= 1.0.0, < 2.0) - cocoapods-core (= 1.1.0.beta.1) - cocoapods-deintegrate (>= 1.0.0, < 2.0) - cocoapods-downloader (>= 1.1.0, < 2.0) + cocoapods-core (= 1.1.0.rc.1) + cocoapods-deintegrate (>= 1.0.1, < 2.0) + cocoapods-downloader (>= 1.1.1, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) @@ -25,13 +25,13 @@ GEM gh_inspector (~> 1.0) molinillo (~> 0.5.0) nap (~> 1.0) - xcodeproj (>= 1.2.0, < 2.0) - cocoapods-core (1.1.0.beta.1) - activesupport (>= 4.0.2) + xcodeproj (>= 1.3.1, < 2.0) + cocoapods-core (1.1.0.rc.1) + activesupport (>= 4.0.2, < 5) fuzzy_match (~> 2.0.4) nap (~> 1.0) - cocoapods-deintegrate (1.0.0) - cocoapods-downloader (1.1.0) + cocoapods-deintegrate (1.0.1) + cocoapods-downloader (1.1.1) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.0) @@ -48,13 +48,13 @@ GEM i18n (0.7.0) json (1.8.3) minitest (5.9.0) - molinillo (0.5.0) + molinillo (0.5.1) nap (1.1.0) netrc (0.7.8) thread_safe (0.3.5) tzinfo (1.2.2) thread_safe (~> 0.1) - xcodeproj (1.2.0) + xcodeproj (1.3.1) activesupport (>= 3) claide (>= 1.0.0, < 2.0) colored (~> 1.2) @@ -63,7 +63,7 @@ PLATFORMS ruby DEPENDENCIES - cocoapods (~> 1.1.0.beta1) + cocoapods (~> 1.1.0.rc.1) minitest BUNDLED WITH From 0aaf650f4f1530e6d97e39ed454619ce5e9c8aed Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 13 Sep 2016 15:27:18 +0100 Subject: [PATCH 06/36] Set Swift version to 2.3 --- CocoaPodsTests/test_running_validator.rb | 17 ++++++++++++++++- SQLite.xcodeproj/project.pbxproj | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CocoaPodsTests/test_running_validator.rb b/CocoaPodsTests/test_running_validator.rb index e866d873..0c21e90c 100644 --- a/CocoaPodsTests/test_running_validator.rb +++ b/CocoaPodsTests/test_running_validator.rb @@ -20,6 +20,8 @@ def create_app_project super.tap do project = Xcodeproj::Project.open(validation_dir + "#{APP_TARGET}.xcodeproj") create_test_target(project) + set_swift_version(project, '2.3') + project.save end end @@ -45,6 +47,14 @@ def build_pod end private + def set_swift_version(project, version) + project.targets.each do |target| + target.build_configuration_list.build_configurations.each do |configuration| + configuration.build_settings['SWIFT_VERSION'] = version + end + end + end + def create_test_target(project) test_target = project.new_target(:unit_test_bundle, TEST_TARGET, consumer.platform_name, deployment_target) group = project.new_group(TEST_TARGET) @@ -71,7 +81,12 @@ def add_test_target(pod_file) end def run_tests - command = %W(clean test -workspace #{APP_TARGET}.xcworkspace -scheme #{TEST_TARGET} -configuration Debug) + command = [ + 'clean', 'test', + '-workspace', File.join(validation_dir, "#{APP_TARGET}.xcworkspace"), + '-scheme', TEST_TARGET, + '-configuration', 'Debug' + ] case consumer.platform_name when :ios command += %w(CODE_SIGN_IDENTITY=- -sdk iphonesimulator) diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index 59bce055..03d27cd8 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -970,6 +970,7 @@ SKIP_INSTALL = YES; "SWIFT_INCLUDE_PATHS[sdk=appletvos*]" = "$(SRCROOT)/CocoaPods/appletvos"; "SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]" = "$(SRCROOT)/CocoaPods/appletvsimulator"; + SWIFT_VERSION = 2.3; TVOS_DEPLOYMENT_TARGET = 9.1; }; name = Debug; @@ -991,6 +992,7 @@ SKIP_INSTALL = YES; "SWIFT_INCLUDE_PATHS[sdk=appletvos*]" = "$(SRCROOT)/CocoaPods/appletvos"; "SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]" = "$(SRCROOT)/CocoaPods/appletvsimulator"; + SWIFT_VERSION = 2.3; TVOS_DEPLOYMENT_TARGET = 9.1; }; name = Release; From 2588c4440bc9aa36ba52189e5be0fceab46e641f Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 13 Sep 2016 17:32:33 +0100 Subject: [PATCH 07/36] Xcode8 compat changes * Add modulemap for MacOSX 10.11 * Update modulemap * Use iPhone SE simulator to fix test failures (https://github.com/travis-ci/travis-ci/issues/6422) --- .travis.yml | 21 ++++++++++++++++----- CocoaPods/macosx-10.11/module.modulemap | 4 ++++ CocoaPods/macosx/module.modulemap | 2 +- CocoaPodsTests/integration_test.rb | 7 +++++-- CocoaPodsTests/test_running_validator.rb | 12 +++++++----- Makefile | 3 ++- SQLite.swift.podspec | 18 +++++++++++------- SQLite.xcodeproj/project.pbxproj | 6 ++++-- run-tests.sh | 6 +++++- 9 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 CocoaPods/macosx-10.11/module.modulemap diff --git a/.travis.yml b/.travis.yml index c40d8e39..7deffc04 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,30 @@ language: objective-c +rvm: 2.2 matrix: - include: - os: osx osx_image: xcode8 - env: BUILD_SCHEME="SQLite iOS" + env: + - BUILD_SCHEME="SQLite iOS" + - IOS_SIMULATOR="iPhone SE" - os: osx osx_image: xcode8 env: BUILD_SCHEME="SQLite Mac" - os: osx osx_image: xcode8 - env: VALIDATOR_SUBSPEC="none" + env: + - VALIDATOR_SUBSPEC="none" + - IOS_SIMULATOR="iPhone SE" - os: osx osx_image: xcode8 - env: VALIDATOR_SUBSPEC="standard" + env: + - VALIDATOR_SUBSPEC="standard" + - IOS_SIMULATOR="iPhone SE" - os: osx osx_image: xcode8 - env: VALIDATOR_SUBSPEC="standalone" + env: + - VALIDATOR_SUBSPEC="standalone" + - IOS_SIMULATOR="iPhone SE" - env: BUILD_SCHEME="SQLite iOS" - env: BUILD_SCHEME="SQLite Mac" - env: VALIDATOR_SUBSPEC="none" @@ -26,4 +34,7 @@ before_install: - gem install xcpretty --no-document script: - ./run-tests.sh +after_failure: + - find $HOME/Library/Developer/Xcode/DerivedData/ -name '*.log' -print0 | xargs -0 cat + - cat /var/log/system.log osx_image: xcode7.3 diff --git a/CocoaPods/macosx-10.11/module.modulemap b/CocoaPods/macosx-10.11/module.modulemap new file mode 100644 index 00000000..9e091297 --- /dev/null +++ b/CocoaPods/macosx-10.11/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/sqlite3.h" + export * +} diff --git a/CocoaPods/macosx/module.modulemap b/CocoaPods/macosx/module.modulemap index 9e091297..cc8370ec 100644 --- a/CocoaPods/macosx/module.modulemap +++ b/CocoaPods/macosx/module.modulemap @@ -1,4 +1,4 @@ module CSQLite [system] { - header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/sqlite3.h" + header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sqlite3.h" export * } diff --git a/CocoaPodsTests/integration_test.rb b/CocoaPodsTests/integration_test.rb index 429a9c77..c62e066e 100755 --- a/CocoaPodsTests/integration_test.rb +++ b/CocoaPodsTests/integration_test.rb @@ -13,7 +13,6 @@ def test_validate_project def validator @validator ||= TestRunningValidator.new(podspec, []).tap do |validator| - subspec = ENV["VALIDATOR_SUBSPEC"] validator.test_files = Dir["#{project_test_dir}/*.swift"] validator.config.verbose = true validator.no_clean = true @@ -21,11 +20,15 @@ def validator validator.fail_fast = true validator.local = true validator.allow_warnings = true - if subspec == "none" + subspec = ENV['VALIDATOR_SUBSPEC'] + if subspec == 'none' validator.no_subspecs = true else validator.only_subspec = subspec end + if ENV['IOS_SIMULATOR'] + validator.ios_simulator = ENV['IOS_SIMULATOR'] + end end end diff --git a/CocoaPodsTests/test_running_validator.rb b/CocoaPodsTests/test_running_validator.rb index 0c21e90c..17fd88d7 100644 --- a/CocoaPodsTests/test_running_validator.rb +++ b/CocoaPodsTests/test_running_validator.rb @@ -7,12 +7,12 @@ class TestRunningValidator < Pod::Validator TEST_TARGET = 'Tests' attr_accessor :test_files - attr_accessor :iphone_simulator + attr_accessor :ios_simulator attr_accessor :tvos_simulator def initialize(spec_or_path, source_urls) super(spec_or_path, source_urls) - self.iphone_simulator = :oldest + self.ios_simulator = :oldest self.tvos_simulator = :oldest end @@ -61,7 +61,7 @@ def create_test_target(project) test_target.add_file_references(test_files.map { |file| group.new_file(file) }) project.save create_test_scheme(project, test_target) - project + test_target end def create_test_scheme(project, test_target) @@ -90,7 +90,7 @@ def run_tests case consumer.platform_name when :ios command += %w(CODE_SIGN_IDENTITY=- -sdk iphonesimulator) - command += Fourflusher::SimControl.new.destination(iphone_simulator, 'iOS', deployment_target) + command += Fourflusher::SimControl.new.destination(ios_simulator, 'iOS', deployment_target) when :osx command += %w(LD_RUNPATH_SEARCH_PATHS=@loader_path/../Frameworks) when :tvos @@ -100,7 +100,8 @@ def run_tests return # skip watchos end - output, status = Dir.chdir(validation_dir) { _xcodebuild(command) } + output, status = _xcodebuild(command) + unless status.success? message = 'Returned an unsuccessful exit code.' if config.verbose? @@ -110,5 +111,6 @@ def run_tests end error('xcodebuild', message) end + output end end diff --git a/Makefile b/Makefile index 059a20b1..35edf493 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ BUILD_TOOL = xcodebuild BUILD_SCHEME = SQLite Mac +IOS_SIMULATOR = iPhone 6 ifeq ($(BUILD_SCHEME),SQLite iOS) - BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" -destination "platform=iOS Simulator,name=iPhone 6" + BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" -destination "platform=iOS Simulator,name=$(IOS_SIMULATOR)" else BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" endif diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 6e5e25d5..b0fb7965 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -33,13 +33,17 @@ Pod::Spec.new do |s| ss.library = 'sqlite3' ss.preserve_paths = 'CocoaPods/**/*' ss.pod_target_xcconfig = { - 'SWIFT_INCLUDE_PATHS[sdk=macosx*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/macosx', - 'SWIFT_INCLUDE_PATHS[sdk=iphoneos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphoneos', - 'SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphonesimulator', - 'SWIFT_INCLUDE_PATHS[sdk=appletvos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/appletvos', - 'SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/appletvsimulator', - 'SWIFT_INCLUDE_PATHS[sdk=watchos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/watchos', - 'SWIFT_INCLUDE_PATHS[sdk=watchsimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/watchsimulator' + 'SWIFT_INCLUDE_PATHS[sdk=macosx*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/macosx', + 'SWIFT_INCLUDE_PATHS[sdk=macosx10.11]' => '$(SRCROOT)/SQLite.swift/CocoaPods/macosx-10.11', + 'SWIFT_INCLUDE_PATHS[sdk=macosx10.12]' => '$(SRCROOT)/SQLite.swift/CocoaPods/macosx-10.12', + 'SWIFT_INCLUDE_PATHS[sdk=iphoneos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphoneos', + 'SWIFT_INCLUDE_PATHS[sdk=iphoneos10.0]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphoneos-10.0', + 'SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphonesimulator', + 'SWIFT_INCLUDE_PATHS[sdk=iphonesimulator10.0]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphonesimulator-10.0', + 'SWIFT_INCLUDE_PATHS[sdk=appletvos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/appletvos', + 'SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/appletvsimulator', + 'SWIFT_INCLUDE_PATHS[sdk=watchos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/watchos', + 'SWIFT_INCLUDE_PATHS[sdk=watchsimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/watchsimulator' } end diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index 03d27cd8..f7450bd2 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -182,7 +182,7 @@ EE247AF21C3F06E900AE3E12 /* Statement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Statement.swift; sourceTree = ""; }; EE247AF31C3F06E900AE3E12 /* Value.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Value.swift; sourceTree = ""; }; EE247AF51C3F06E900AE3E12 /* FTS4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS4.swift; sourceTree = ""; }; - EE247AF61C3F06E900AE3E12 /* RTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RTree.swift"; sourceTree = ""; }; + EE247AF61C3F06E900AE3E12 /* RTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTree.swift; sourceTree = ""; }; EE247AF71C3F06E900AE3E12 /* Foundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Foundation.swift; sourceTree = ""; }; EE247AF81C3F06E900AE3E12 /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AggregateFunctions.swift; sourceTree = ""; }; @@ -205,7 +205,7 @@ EE247B211C3F137700AE3E12 /* FTS4Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS4Tests.swift; sourceTree = ""; }; EE247B2A1C3F141E00AE3E12 /* OperatorsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperatorsTests.swift; sourceTree = ""; }; EE247B2B1C3F141E00AE3E12 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = ""; }; - EE247B2C1C3F141E00AE3E12 /* RTreeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RTreeTests.swift"; sourceTree = ""; }; + EE247B2C1C3F141E00AE3E12 /* RTreeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTreeTests.swift; sourceTree = ""; }; EE247B2D1C3F141E00AE3E12 /* SchemaTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaTests.swift; sourceTree = ""; }; EE247B321C3F142E00AE3E12 /* StatementTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatementTests.swift; sourceTree = ""; }; EE247B331C3F142E00AE3E12 /* ValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValueTests.swift; sourceTree = ""; }; @@ -1248,6 +1248,7 @@ SKIP_INSTALL = YES; SWIFT_INCLUDE_PATHS = ""; "SWIFT_INCLUDE_PATHS[sdk=macosx*]" = "$(SRCROOT)/CocoaPods/macosx"; + "SWIFT_INCLUDE_PATHS[sdk=macosx10.11]" = "$(SRCROOT)/CocoaPods/macosx-10.11"; "SWIFT_INCLUDE_PATHS[sdk=macosx10.12]" = "$(SRCROOT)/CocoaPods/macosx-10.12"; SWIFT_VERSION = 2.3; }; @@ -1274,6 +1275,7 @@ SKIP_INSTALL = YES; SWIFT_INCLUDE_PATHS = ""; "SWIFT_INCLUDE_PATHS[sdk=macosx*]" = "$(SRCROOT)/CocoaPods/macosx"; + "SWIFT_INCLUDE_PATHS[sdk=macosx10.11]" = "$(SRCROOT)/CocoaPods/macosx-10.11"; "SWIFT_INCLUDE_PATHS[sdk=macosx10.12]" = "$(SRCROOT)/CocoaPods/macosx-10.12"; SWIFT_VERSION = 2.3; }; diff --git a/run-tests.sh b/run-tests.sh index 7a35fb02..bc8cd773 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -1,7 +1,11 @@ #!/bin/bash set -ev if [ -n "$BUILD_SCHEME" ]; then - make test BUILD_SCHEME="$BUILD_SCHEME" + if [ -n "$IOS_SIMULATOR" ]; then + make test BUILD_SCHEME="$BUILD_SCHEME" IOS_SIMULATOR="$IOS_SIMULATOR" + else + make test BUILD_SCHEME="$BUILD_SCHEME" + fi elif [ -n "$VALIDATOR_SUBSPEC" ]; then cd CocoaPodsTests && make test fi From b62880efe87ccb19eb2f44fc39212179c7b908da Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 14 Sep 2016 22:24:03 +0100 Subject: [PATCH 08/36] Update CocoaPods, update repo --- CocoaPodsTests/Gemfile | 2 +- CocoaPodsTests/Gemfile.lock | 10 +++++----- CocoaPodsTests/Makefile | 5 ++++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CocoaPodsTests/Gemfile b/CocoaPodsTests/Gemfile index 86c90369..287dcbfc 100644 --- a/CocoaPodsTests/Gemfile +++ b/CocoaPodsTests/Gemfile @@ -1,4 +1,4 @@ source 'https://rubygems.org' -gem 'cocoapods', '~> 1.1.0.rc.1' +gem 'cocoapods', '~> 1.1.0.rc.2' gem 'minitest' diff --git a/CocoaPodsTests/Gemfile.lock b/CocoaPodsTests/Gemfile.lock index 4252e155..93a54bb9 100644 --- a/CocoaPodsTests/Gemfile.lock +++ b/CocoaPodsTests/Gemfile.lock @@ -8,10 +8,10 @@ GEM thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) claide (1.0.0) - cocoapods (1.1.0.rc.1) + cocoapods (1.1.0.rc.2) activesupport (>= 4.0.2, < 5) claide (>= 1.0.0, < 2.0) - cocoapods-core (= 1.1.0.rc.1) + cocoapods-core (= 1.1.0.rc.2) cocoapods-deintegrate (>= 1.0.1, < 2.0) cocoapods-downloader (>= 1.1.1, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) @@ -23,10 +23,10 @@ GEM escape (~> 0.0.4) fourflusher (~> 1.0.1) gh_inspector (~> 1.0) - molinillo (~> 0.5.0) + molinillo (~> 0.5.1) nap (~> 1.0) xcodeproj (>= 1.3.1, < 2.0) - cocoapods-core (1.1.0.rc.1) + cocoapods-core (1.1.0.rc.2) activesupport (>= 4.0.2, < 5) fuzzy_match (~> 2.0.4) nap (~> 1.0) @@ -63,7 +63,7 @@ PLATFORMS ruby DEPENDENCIES - cocoapods (~> 1.1.0.rc.1) + cocoapods (~> 1.1.0.rc.2) minitest BUNDLED WITH diff --git a/CocoaPodsTests/Makefile b/CocoaPodsTests/Makefile index c9a3182e..26163fdb 100644 --- a/CocoaPodsTests/Makefile +++ b/CocoaPodsTests/Makefile @@ -1,9 +1,12 @@ -test: install +test: install repo_update @set -e; \ for test in *_test.rb; do \ bundle exec ./$$test; \ done +repo_update: + @bundle exec pod repo update --silent + install: @bundle install --path gems From 9fa5b908ae67e033a9bc7d498735c237b7c198b5 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 14 Sep 2016 23:11:26 +0100 Subject: [PATCH 09/36] Use recommended Xcode8 project settings --- SQLite.xcodeproj/project.pbxproj | 17 ++++++++++++++--- .../xcshareddata/xcschemes/SQLite Mac.xcscheme | 2 +- .../xcshareddata/xcschemes/SQLite iOS.xcscheme | 2 +- .../xcshareddata/xcschemes/SQLite tvOS.xcscheme | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index f7450bd2..a69730d4 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -673,7 +673,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0800; TargetAttributes = { 03A65E591C6BB0F50062603F = { CreatedOnToolsVersion = 7.2; @@ -957,6 +957,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -979,6 +980,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1026,6 +1028,7 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1047,6 +1050,7 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1076,8 +1080,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -1126,8 +1132,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -1149,6 +1157,7 @@ MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = ""; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2,3"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -1161,6 +1170,7 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1186,6 +1196,7 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1231,7 +1242,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; - CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1258,7 +1269,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; - CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite Mac.xcscheme b/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite Mac.xcscheme index fa91858e..606b5a10 100644 --- a/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite Mac.xcscheme +++ b/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite Mac.xcscheme @@ -1,6 +1,6 @@ Date: Wed, 14 Sep 2016 22:00:53 +0100 Subject: [PATCH 10/36] travis: use xcode8 as default image --- .travis.yml | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7deffc04..d855fb3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,35 +1,36 @@ language: objective-c rvm: 2.2 +osx_image: xcode8 matrix: include: - - os: osx - osx_image: xcode8 - env: + - env: - BUILD_SCHEME="SQLite iOS" - IOS_SIMULATOR="iPhone SE" - - os: osx - osx_image: xcode8 - env: BUILD_SCHEME="SQLite Mac" - - os: osx - osx_image: xcode8 - env: + - env: BUILD_SCHEME="SQLite Mac" + - env: - VALIDATOR_SUBSPEC="none" - IOS_SIMULATOR="iPhone SE" - - os: osx - osx_image: xcode8 - env: + - env: - VALIDATOR_SUBSPEC="standard" - IOS_SIMULATOR="iPhone SE" - - os: osx - osx_image: xcode8 - env: + - env: - VALIDATOR_SUBSPEC="standalone" - IOS_SIMULATOR="iPhone SE" - - env: BUILD_SCHEME="SQLite iOS" - - env: BUILD_SCHEME="SQLite Mac" - - env: VALIDATOR_SUBSPEC="none" - - env: VALIDATOR_SUBSPEC="standard" - - env: VALIDATOR_SUBSPEC="standalone" + - os: osx + osx_image: xcode7.3 + env: BUILD_SCHEME="SQLite iOS" + - os: osx + osx_image: xcode7.3 + env: BUILD_SCHEME="SQLite Mac" + - os: osx + osx_image: xcode7.3 + env: VALIDATOR_SUBSPEC="none" + - os: osx + osx_image: xcode7.3 + env: VALIDATOR_SUBSPEC="standard" + - os: osx + osx_image: xcode7.3 + env: VALIDATOR_SUBSPEC="standalone" before_install: - gem install xcpretty --no-document script: @@ -37,4 +38,3 @@ script: after_failure: - find $HOME/Library/Developer/Xcode/DerivedData/ -name '*.log' -print0 | xargs -0 cat - cat /var/log/system.log -osx_image: xcode7.3 From 90e662e1e9e502b66d60d658ab076482d1251e3a Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 16 Sep 2016 16:38:55 +0100 Subject: [PATCH 11/36] Add Swift version to xcconfig --- SQLite.swift.podspec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index b0fb7965..89cffff1 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -25,6 +25,9 @@ Pod::Spec.new do |s| s.osx.deployment_target = "10.9" s.watchos.deployment_target = "2.0" s.default_subspec = 'standard' + s.pod_target_xcconfig = { + 'SWIFT_VERSION' => '2.3', + } s.subspec 'standard' do |ss| ss.source_files = 'SQLite/**/*.{c,h,m,swift}' From 494f3c4e8810dc06e9c71b825cc14eb3571d2cc7 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 16 Sep 2016 16:39:30 +0100 Subject: [PATCH 12/36] use Pod::Validator#add_swift_version --- .swift-version | 1 + CocoaPodsTests/test_running_validator.rb | 39 +++++++++++------------- 2 files changed, 18 insertions(+), 22 deletions(-) create mode 100644 .swift-version diff --git a/.swift-version b/.swift-version new file mode 100644 index 00000000..bb576dbd --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +2.3 diff --git a/CocoaPodsTests/test_running_validator.rb b/CocoaPodsTests/test_running_validator.rb index 17fd88d7..1eefa4b8 100644 --- a/CocoaPodsTests/test_running_validator.rb +++ b/CocoaPodsTests/test_running_validator.rb @@ -17,19 +17,26 @@ def initialize(spec_or_path, source_urls) end def create_app_project - super.tap do - project = Xcodeproj::Project.open(validation_dir + "#{APP_TARGET}.xcodeproj") - create_test_target(project) - set_swift_version(project, '2.3') - project.save - end + super + project = Xcodeproj::Project.open(validation_dir + "#{APP_TARGET}.xcodeproj") + create_test_target(project) + project.save + end + + def add_app_project_import + super + project = Xcodeproj::Project.open(validation_dir + 'App.xcodeproj') + group = project.new_group(TEST_TARGET) + test_target = project.targets.last + test_target.add_file_references(test_files.map { |file| group.new_file(file) }) + add_swift_version(test_target) + project.save end def install_pod - super.tap do - if local? - FileUtils.ln_s file.dirname, validation_dir + "Pods/#{spec.name}" - end + super + if local? + FileUtils.ln_s file.dirname, validation_dir + "Pods/#{spec.name}" end end @@ -47,21 +54,9 @@ def build_pod end private - def set_swift_version(project, version) - project.targets.each do |target| - target.build_configuration_list.build_configurations.each do |configuration| - configuration.build_settings['SWIFT_VERSION'] = version - end - end - end - def create_test_target(project) test_target = project.new_target(:unit_test_bundle, TEST_TARGET, consumer.platform_name, deployment_target) - group = project.new_group(TEST_TARGET) - test_target.add_file_references(test_files.map { |file| group.new_file(file) }) - project.save create_test_scheme(project, test_target) - test_target end def create_test_scheme(project, test_target) From 8f9b8a855f9d473c8389d2927b4321217e5622cc Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Fri, 16 Sep 2016 17:45:29 +0800 Subject: [PATCH 13/36] migrating to swift 3 --- SQLite.xcodeproj/project.pbxproj | 20 +- SQLite/Core/Blob.swift | 10 +- SQLite/Core/Connection.swift | 198 ++++++++++--------- SQLite/Core/Statement.swift | 60 +++--- SQLite/Core/Value.swift | 14 +- SQLite/Extensions/FTS4.swift | 114 +++++------ SQLite/Extensions/FTS5.swift | 28 +-- SQLite/Extensions/RTree.swift | 4 +- SQLite/Foundation.swift | 46 ++--- SQLite/Helpers.swift | 32 +-- SQLite/Typed/AggregateFunctions.swift | 4 +- SQLite/Typed/Collation.swift | 16 +- SQLite/Typed/CoreFunctions.swift | 68 +++---- SQLite/Typed/CustomFunctions.swift | 32 +-- SQLite/Typed/Expression.swift | 4 +- SQLite/Typed/Operators.swift | 272 +++++++++++++------------- SQLite/Typed/Query.swift | 130 ++++++------ SQLite/Typed/Schema.swift | 164 ++++++++-------- SQLite/Typed/Setter.swift | 128 ++++++------ SQLiteTests/ConnectionTests.swift | 76 +++---- SQLiteTests/CoreFunctionsTests.swift | 18 +- SQLiteTests/FTS4Tests.swift | 26 +-- SQLiteTests/FTS5Tests.swift | 8 +- SQLiteTests/OperatorsTests.swift | 2 +- SQLiteTests/QueryTests.swift | 4 +- SQLiteTests/SchemaTests.swift | 106 +++++----- SQLiteTests/TestHelpers.swift | 30 +-- 27 files changed, 811 insertions(+), 803 deletions(-) diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index a69730d4..2f13a35f 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -971,7 +971,7 @@ SKIP_INSTALL = YES; "SWIFT_INCLUDE_PATHS[sdk=appletvos*]" = "$(SRCROOT)/CocoaPods/appletvos"; "SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]" = "$(SRCROOT)/CocoaPods/appletvsimulator"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; TVOS_DEPLOYMENT_TARGET = 9.1; }; name = Debug; @@ -994,7 +994,7 @@ SKIP_INSTALL = YES; "SWIFT_INCLUDE_PATHS[sdk=appletvos*]" = "$(SRCROOT)/CocoaPods/appletvos"; "SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]" = "$(SRCROOT)/CocoaPods/appletvsimulator"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; TVOS_DEPLOYMENT_TARGET = 9.1; }; name = Release; @@ -1187,7 +1187,7 @@ "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]" = "$(SRCROOT)/CocoaPods/iphonesimulator"; "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator10.0]" = "$(SRCROOT)/CocoaPods/iphonesimulator-10.0"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -1212,7 +1212,7 @@ "SWIFT_INCLUDE_PATHS[sdk=iphoneos10.0]" = "$(SRCROOT)/CocoaPods/iphoneos-10.0"; "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]" = "$(SRCROOT)/CocoaPods/iphonesimulator"; "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator10.0]" = "$(SRCROOT)/CocoaPods/iphonesimulator-10.0"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -1223,7 +1223,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -1234,7 +1234,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -1261,7 +1261,7 @@ "SWIFT_INCLUDE_PATHS[sdk=macosx*]" = "$(SRCROOT)/CocoaPods/macosx"; "SWIFT_INCLUDE_PATHS[sdk=macosx10.11]" = "$(SRCROOT)/CocoaPods/macosx-10.11"; "SWIFT_INCLUDE_PATHS[sdk=macosx10.12]" = "$(SRCROOT)/CocoaPods/macosx-10.12"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -1288,7 +1288,7 @@ "SWIFT_INCLUDE_PATHS[sdk=macosx*]" = "$(SRCROOT)/CocoaPods/macosx"; "SWIFT_INCLUDE_PATHS[sdk=macosx10.11]" = "$(SRCROOT)/CocoaPods/macosx-10.11"; "SWIFT_INCLUDE_PATHS[sdk=macosx10.12]" = "$(SRCROOT)/CocoaPods/macosx-10.12"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -1303,7 +1303,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -1318,7 +1318,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/SQLite/Core/Blob.swift b/SQLite/Core/Blob.swift index 1b30ffa1..45d6604a 100644 --- a/SQLite/Core/Blob.swift +++ b/SQLite/Core/Blob.swift @@ -30,16 +30,16 @@ public struct Blob { self.bytes = bytes } - public init(bytes: UnsafePointer, length: Int) { - self.init(bytes: [UInt8](UnsafeBufferPointer( - start: UnsafePointer(bytes), count: length - ))) + public init(bytes: UnsafeRawPointer, length: Int) { + // TODO correct count + let i8bufptr = UnsafeBufferPointer(start: bytes.assumingMemoryBound(to: UInt8.self), count: length) + self.init(bytes: [UInt8](i8bufptr)) } public func toHex() -> String { return bytes.map { ($0 < 16 ? "0" : "") + String($0, radix: 16, uppercase: false) - }.joinWithSeparator("") + }.joined(separator: "") } } diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index 04fdd901..832910ba 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -39,24 +39,24 @@ public final class Connection { /// An in-memory database (equivalent to `.URI(":memory:")`). /// /// See: - case InMemory + case inMemory /// A temporary, file-backed database (equivalent to `.URI("")`). /// /// See: - case Temporary + case temporary /// A database located at the given URI filename (or path). /// /// See: /// /// - Parameter filename: A URI filename - case URI(String) + case uri(String) } - public var handle: COpaquePointer { return _handle } + public var handle: OpaquePointer { return _handle! } - private var _handle: COpaquePointer = nil + fileprivate var _handle: OpaquePointer? = nil /// Initializes a new SQLite connection. /// @@ -72,10 +72,10 @@ public final class Connection { /// Default: `false`. /// /// - Returns: A new database connection. - public init(_ location: Location = .InMemory, readonly: Bool = false) throws { + public init(_ location: Location = .inMemory, readonly: Bool = false) throws { let flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE - try check(sqlite3_open_v2(location.description, &_handle, flags | SQLITE_OPEN_FULLMUTEX, nil)) - dispatch_queue_set_specific(queue, Connection.queueKey, queueContext, nil) + _ = try check(sqlite3_open_v2(location.description, &_handle, flags | SQLITE_OPEN_FULLMUTEX, nil)) + queue.setSpecific(key: /*Migrator FIXME: Use a variable of type DispatchSpecificKey*/ Connection.queueKey, value: queueContext) } /// Initializes a new connection to a database. @@ -93,7 +93,7 @@ public final class Connection { /// /// - Returns: A new database connection. public convenience init(_ filename: String, readonly: Bool = false) throws { - try self.init(.URI(filename), readonly: readonly) + try self.init(.uri(filename), readonly: readonly) } deinit { @@ -131,8 +131,8 @@ public final class Connection { /// statements. /// /// - Throws: `Result.Error` if query execution fails. - public func execute(SQL: String) throws { - try sync { try self.check(sqlite3_exec(self.handle, SQL, nil, nil, nil)) } + public func execute(_ SQL: String) throws { + _ = try sync { try self.check(sqlite3_exec(self.handle, SQL, nil, nil, nil)) } } // MARK: - Prepare @@ -146,7 +146,7 @@ public final class Connection { /// - bindings: A list of parameters to bind to the statement. /// /// - Returns: A prepared statement. - @warn_unused_result public func prepare(statement: String, _ bindings: Binding?...) throws -> Statement { + public func prepare(_ statement: String, _ bindings: Binding?...) throws -> Statement { if !bindings.isEmpty { return try prepare(statement, bindings) } return try Statement(self, statement) } @@ -160,7 +160,7 @@ public final class Connection { /// - bindings: A list of parameters to bind to the statement. /// /// - Returns: A prepared statement. - @warn_unused_result public func prepare(statement: String, _ bindings: [Binding?]) throws -> Statement { + public func prepare(_ statement: String, _ bindings: [Binding?]) throws -> Statement { return try prepare(statement).bind(bindings) } @@ -173,7 +173,7 @@ public final class Connection { /// - bindings: A dictionary of named parameters to bind to the statement. /// /// - Returns: A prepared statement. - @warn_unused_result public func prepare(statement: String, _ bindings: [String: Binding?]) throws -> Statement { + public func prepare(_ statement: String, _ bindings: [String: Binding?]) throws -> Statement { return try prepare(statement).bind(bindings) } @@ -190,7 +190,7 @@ public final class Connection { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement. - public func run(statement: String, _ bindings: Binding?...) throws -> Statement { + public func run(_ statement: String, _ bindings: Binding?...) throws -> Statement { return try run(statement, bindings) } @@ -205,7 +205,7 @@ public final class Connection { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement. - public func run(statement: String, _ bindings: [Binding?]) throws -> Statement { + public func run(_ statement: String, _ bindings: [Binding?]) throws -> Statement { return try prepare(statement).run(bindings) } @@ -220,7 +220,7 @@ public final class Connection { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement. - public func run(statement: String, _ bindings: [String: Binding?]) throws -> Statement { + public func run(_ statement: String, _ bindings: [String: Binding?]) throws -> Statement { return try prepare(statement).run(bindings) } @@ -236,7 +236,7 @@ public final class Connection { /// - bindings: A list of parameters to bind to the statement. /// /// - Returns: The first value of the first row returned. - @warn_unused_result public func scalar(statement: String, _ bindings: Binding?...) throws -> Binding? { + public func scalar(_ statement: String, _ bindings: Binding?...) throws -> Binding? { return try scalar(statement, bindings) } @@ -250,7 +250,7 @@ public final class Connection { /// - bindings: A list of parameters to bind to the statement. /// /// - Returns: The first value of the first row returned. - @warn_unused_result public func scalar(statement: String, _ bindings: [Binding?]) throws -> Binding? { + public func scalar(_ statement: String, _ bindings: [Binding?]) throws -> Binding? { return try prepare(statement).scalar(bindings) } @@ -264,7 +264,7 @@ public final class Connection { /// - bindings: A dictionary of named parameters to bind to the statement. /// /// - Returns: The first value of the first row returned. - @warn_unused_result public func scalar(statement: String, _ bindings: [String: Binding?]) throws -> Binding? { + public func scalar(_ statement: String, _ bindings: [String: Binding?]) throws -> Binding? { return try prepare(statement).scalar(bindings) } @@ -301,7 +301,7 @@ public final class Connection { /// must throw to roll the transaction back. /// /// - Throws: `Result.Error`, and rethrows. - public func transaction(mode: TransactionMode = .Deferred, block: () throws -> Void) throws { + public func transaction(_ mode: TransactionMode = .Deferred, block: @escaping () throws -> Void) throws { try transaction("BEGIN \(mode.rawValue) TRANSACTION", block, "COMMIT TRANSACTION", or: "ROLLBACK TRANSACTION") } @@ -321,23 +321,23 @@ public final class Connection { /// The block must throw to roll the savepoint back. /// /// - Throws: `SQLite.Result.Error`, and rethrows. - public func savepoint(name: String = NSUUID().UUIDString, block: () throws -> Void) throws { + public func savepoint(_ name: String = UUID().uuidString, block: @escaping () throws -> Void) throws { let name = name.quote("'") let savepoint = "SAVEPOINT \(name)" try transaction(savepoint, block, "RELEASE \(savepoint)", or: "ROLLBACK TO \(savepoint)") } - private func transaction(begin: String, _ block: () throws -> Void, _ commit: String, or rollback: String) throws { + fileprivate func transaction(_ begin: String, _ block: @escaping () throws -> Void, _ commit: String, or rollback: String) throws { return try sync { - try self.run(begin) + _ = try self.run(begin) do { try block() } catch { - try self.run(rollback) + _ = try self.run(rollback) throw error } - try self.run(commit) + _ = try self.run(commit) } } @@ -362,21 +362,21 @@ public final class Connection { /// busy error would otherwise be returned. It’s passed the number of /// times it’s been called for this lock. If it returns `true`, it will /// try again. If it returns `false`, no further attempts will be made. - public func busyHandler(callback: ((tries: Int) -> Bool)?) { + public func busyHandler(_ callback: ((_ tries: Int) -> Bool)?) { guard let callback = callback else { sqlite3_busy_handler(handle, nil, nil) busyHandler = nil return } - let box: BusyHandler = { callback(tries: Int($0)) ? 1 : 0 } + let box: BusyHandler = { callback(Int($0)) ? 1 : 0 } sqlite3_busy_handler(handle, { callback, tries in - unsafeBitCast(callback, BusyHandler.self)(tries) - }, unsafeBitCast(box, UnsafeMutablePointer.self)) + unsafeBitCast(callback, to: BusyHandler.self)(tries) + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) busyHandler = box } - private typealias BusyHandler = @convention(block) Int32 -> Int32 - private var busyHandler: BusyHandler? + fileprivate typealias BusyHandler = @convention(block) (Int32) -> Int32 + fileprivate var busyHandler: BusyHandler? /// Sets a handler to call when a statement is executed with the compiled /// SQL. @@ -385,21 +385,21 @@ public final class Connection { /// with the compiled SQL as its argument. /// /// db.trace { SQL in print(SQL) } - public func trace(callback: (String -> Void)?) { + public func trace(_ callback: ((String) -> Void)?) { guard let callback = callback else { sqlite3_trace(handle, nil, nil) trace = nil return } - let box: Trace = { callback(String.fromCString($0)!) } + let box: Trace = { callback(String(cString: $0)) } sqlite3_trace(handle, { callback, SQL in - unsafeBitCast(callback, Trace.self)(SQL) - }, unsafeBitCast(box, UnsafeMutablePointer.self)) + unsafeBitCast(callback, to: Trace.self)(SQL!) + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) trace = box } - private typealias Trace = @convention(block) UnsafePointer -> Void - private var trace: Trace? + fileprivate typealias Trace = @convention(block) (UnsafePointer) -> Void + fileprivate var trace: Trace? /// Registers a callback to be invoked whenever a row is inserted, updated, /// or deleted in a rowid table. @@ -407,7 +407,7 @@ public final class Connection { /// - Parameter callback: A callback invoked with the `Operation` (one of /// `.Insert`, `.Update`, or `.Delete`), database name, table name, and /// rowid. - public func updateHook(callback: ((operation: Operation, db: String, table: String, rowid: Int64) -> Void)?) { + public func updateHook(_ callback: ((_ operation: Operation, _ db: String, _ table: String, _ rowid: Int64) -> Void)?) { guard let callback = callback else { sqlite3_update_hook(handle, nil, nil) updateHook = nil @@ -416,26 +416,26 @@ public final class Connection { let box: UpdateHook = { callback( - operation: Operation(rawValue: $0), - db: String.fromCString($1)!, - table: String.fromCString($2)!, - rowid: $3 + Operation(rawValue: $0), + String(cString: $1), + String(cString: $2), + $3 ) } sqlite3_update_hook(handle, { callback, operation, db, table, rowid in - unsafeBitCast(callback, UpdateHook.self)(operation, db, table, rowid) - }, unsafeBitCast(box, UnsafeMutablePointer.self)) + unsafeBitCast(callback, to: UpdateHook.self)(operation, db!, table!, rowid) + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) updateHook = box } - private typealias UpdateHook = @convention(block) (Int32, UnsafePointer, UnsafePointer, Int64) -> Void - private var updateHook: UpdateHook? + fileprivate typealias UpdateHook = @convention(block) (Int32, UnsafePointer, UnsafePointer, Int64) -> Void + fileprivate var updateHook: UpdateHook? /// Registers a callback to be invoked whenever a transaction is committed. /// /// - Parameter callback: A callback invoked whenever a transaction is /// committed. If this callback throws, the transaction will be rolled /// back. - public func commitHook(callback: (() throws -> Void)?) { + public func commitHook(_ callback: (() throws -> Void)?) { guard let callback = callback else { sqlite3_commit_hook(handle, nil, nil) commitHook = nil @@ -451,18 +451,18 @@ public final class Connection { return 0 } sqlite3_commit_hook(handle, { callback in - unsafeBitCast(callback, CommitHook.self)() - }, unsafeBitCast(box, UnsafeMutablePointer.self)) + unsafeBitCast(callback, to: CommitHook.self)() + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) commitHook = box } - private typealias CommitHook = @convention(block) () -> Int32 - private var commitHook: CommitHook? + fileprivate typealias CommitHook = @convention(block) () -> Int32 + fileprivate var commitHook: CommitHook? /// Registers a callback to be invoked whenever a transaction rolls back. /// /// - Parameter callback: A callback invoked when a transaction is rolled /// back. - public func rollbackHook(callback: (() -> Void)?) { + public func rollbackHook(_ callback: (() -> Void)?) { guard let callback = callback else { sqlite3_rollback_hook(handle, nil, nil) rollbackHook = nil @@ -471,12 +471,12 @@ public final class Connection { let box: RollbackHook = { callback() } sqlite3_rollback_hook(handle, { callback in - unsafeBitCast(callback, RollbackHook.self)() - }, unsafeBitCast(box, UnsafeMutablePointer.self)) + unsafeBitCast(callback, to: RollbackHook.self)() + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) rollbackHook = box } - private typealias RollbackHook = @convention(block) () -> Void - private var rollbackHook: RollbackHook? + fileprivate typealias RollbackHook = @convention(block) () -> Void + fileprivate var rollbackHook: RollbackHook? /// Creates or redefines a custom SQL function. /// @@ -497,11 +497,11 @@ public final class Connection { /// - block: A block of code to run when the function is called. The block /// is called with an array of raw SQL values mapped to the function’s /// parameters and should return a raw SQL value (or nil). - public func createFunction(function: String, argumentCount: UInt? = nil, deterministic: Bool = false, _ block: (args: [Binding?]) -> Binding?) { + public func createFunction(_ function: String, argumentCount: UInt? = nil, deterministic: Bool = false, _ block: @escaping (_ args: [Binding?]) -> Binding?) { let argc = argumentCount.map { Int($0) } ?? -1 let box: Function = { context, argc, argv in let arguments: [Binding?] = (0...self), { context, argc, value in - unsafeBitCast(sqlite3_user_data(context), Function.self)(context, argc, value) + sqlite3_create_function_v2(handle, function, Int32(argc), flags, unsafeBitCast(box, to: UnsafeMutableRawPointer.self), { context, argc, value in + let function = unsafeBitCast(sqlite3_user_data(context), to: Function.self) + function(context, argc, value) }, nil, nil, nil) if functions[function] == nil { self.functions[function] = [:] } functions[function]?[argc] = box } - private typealias Function = @convention(block) (COpaquePointer, Int32, UnsafeMutablePointer) -> Void - private var functions = [String: [Int: Function]]() + fileprivate typealias Function = @convention(block) (OpaquePointer?, Int32, UnsafeMutablePointer?) -> Void + fileprivate var functions = [String: [Int: Function]]() /// The return type of a collation comparison function. - public typealias ComparisonResult = NSComparisonResult + public typealias ComparisonResult = Foundation.ComparisonResult /// Defines a new collating sequence. /// @@ -556,23 +557,26 @@ public final class Connection { /// /// - block: A collation function that takes two strings and returns the /// comparison result. - public func createCollation(collation: String, _ block: (lhs: String, rhs: String) -> ComparisonResult) throws { + public func createCollation(_ collation: String, _ block: @escaping (_ lhs: String, _ rhs: String) -> ComparisonResult) throws { + // TODO correct capacity let box: Collation = { lhs, rhs in - Int32(block(lhs: String.fromCString(UnsafePointer(lhs))!, rhs: String.fromCString(UnsafePointer(rhs))!).rawValue) + let lstr = String(cString: lhs.bindMemory(to: UInt8.self, capacity: 0)) + let rstr = String(cString: rhs.bindMemory(to: UInt8.self, capacity: 0)) + return Int32(Int(block(lstr, rstr).rawValue)) } - try check(sqlite3_create_collation_v2(handle, collation, SQLITE_UTF8, unsafeBitCast(box, UnsafeMutablePointer.self), { callback, _, lhs, _, rhs in - unsafeBitCast(callback, Collation.self)(lhs, rhs) + _ = try check(sqlite3_create_collation_v2(handle, collation, SQLITE_UTF8, unsafeBitCast(box, to: UnsafeMutableRawPointer.self), { callback, _, lhs, _, rhs in + unsafeBitCast(callback, to: Collation.self)(lhs!, rhs!) }, nil)) collations[collation] = box } - private typealias Collation = @convention(block) (UnsafePointer, UnsafePointer) -> Int32 - private var collations = [String: Collation]() + fileprivate typealias Collation = @convention(block) (UnsafeRawPointer, UnsafeRawPointer) -> Int32 + fileprivate var collations = [String: Collation]() // MARK: - Error Handling - func sync(block: () throws -> T) rethrows -> T { + func sync(_ block: @escaping () throws -> T) rethrows -> T { var success: T? - var failure: ErrorType? + var failure: Error? let box: () -> Void = { do { @@ -582,10 +586,10 @@ public final class Connection { } } - if dispatch_get_specific(Connection.queueKey) == queueContext { + if DispatchQueue.getSpecific(key: Connection.queueKey) == queueContext { box() } else { - dispatch_sync(queue, box) // FIXME: rdar://problem/21389236 + queue.sync(execute: box) // FIXME: rdar://problem/21389236 } if let failure = failure { @@ -595,7 +599,7 @@ public final class Connection { return success! } - func check(resultCode: Int32, statement: Statement? = nil) throws -> Int32 { + func check(_ resultCode: Int32, statement: Statement? = nil) throws -> Int32 { guard let error = Result(errorCode: resultCode, connection: self, statement: statement) else { return resultCode } @@ -603,18 +607,18 @@ public final class Connection { throw error } - private var queue = dispatch_queue_create("SQLite.Database", DISPATCH_QUEUE_SERIAL) + fileprivate var queue = DispatchQueue(label: "SQLite.Database", attributes: []) - private static let queueKey = unsafeBitCast(Connection.self, UnsafePointer.self) + fileprivate static let queueKey = DispatchSpecificKey() - private lazy var queueContext: UnsafeMutablePointer = unsafeBitCast(self, UnsafeMutablePointer.self) + fileprivate lazy var queueContext: Int = unsafeBitCast(self, to: Int.self) } extension Connection : CustomStringConvertible { public var description: String { - return String.fromCString(sqlite3_db_filename(handle, nil))! + return String(cString: sqlite3_db_filename(handle, nil)) } } @@ -623,11 +627,11 @@ extension Connection.Location : CustomStringConvertible { public var description: String { switch self { - case .InMemory: + case .inMemory: return ":memory:" - case .Temporary: + case .temporary: return "" - case .URI(let URI): + case .uri(let URI): return URI } } @@ -638,22 +642,22 @@ extension Connection.Location : CustomStringConvertible { public enum Operation { /// An INSERT operation. - case Insert + case insert /// An UPDATE operation. - case Update + case update /// A DELETE operation. - case Delete + case delete - private init(rawValue: Int32) { + fileprivate init(rawValue: Int32) { switch rawValue { case SQLITE_INSERT: - self = .Insert + self = .insert case SQLITE_UPDATE: - self = .Update + self = .update case SQLITE_DELETE: - self = .Delete + self = .delete default: fatalError("unhandled operation code: \(rawValue)") } @@ -661,17 +665,17 @@ public enum Operation { } -public enum Result : ErrorType { +public enum Result : Error { - private static let successCodes: Set = [SQLITE_OK, SQLITE_ROW, SQLITE_DONE] + fileprivate static let successCodes: Set = [SQLITE_OK, SQLITE_ROW, SQLITE_DONE] - case Error(message: String, code: Int32, statement: Statement?) + case error(message: String, code: Int32, statement: Statement?) init?(errorCode: Int32, connection: Connection, statement: Statement? = nil) { guard !Result.successCodes.contains(errorCode) else { return nil } - let message = String.fromCString(sqlite3_errmsg(connection.handle))! - self = Error(message: message, code: errorCode, statement: statement) + let message = String(cString: sqlite3_errmsg(connection.handle)) + self = .error(message: message, code: errorCode, statement: statement) } } @@ -680,7 +684,7 @@ extension Result : CustomStringConvertible { public var description: String { switch self { - case let .Error(message, _, statement): + case let .error(message, _, statement): guard let statement = statement else { return message } return "\(message) (\(statement))" diff --git a/SQLite/Core/Statement.swift b/SQLite/Core/Statement.swift index 5e172b68..01720433 100644 --- a/SQLite/Core/Statement.swift +++ b/SQLite/Core/Statement.swift @@ -31,13 +31,13 @@ import CSQLite /// A single SQL statement. public final class Statement { - private var handle: COpaquePointer = nil + fileprivate var handle: OpaquePointer? = nil - private let connection: Connection + fileprivate let connection: Connection init(_ connection: Connection, _ SQL: String) throws { self.connection = connection - try connection.check(sqlite3_prepare_v2(connection.handle, SQL, -1, &handle, nil)) + _ = try connection.check(sqlite3_prepare_v2(connection.handle, SQL, -1, &handle, nil)) } deinit { @@ -47,7 +47,7 @@ public final class Statement { public lazy var columnCount: Int = Int(sqlite3_column_count(self.handle)) public lazy var columnNames: [String] = (0.. Statement { + public func bind(_ values: Binding?...) -> Statement { return bind(values) } @@ -67,7 +67,7 @@ public final class Statement { /// - Parameter values: A list of parameters to bind to the statement. /// /// - Returns: The statement object (useful for chaining). - public func bind(values: [Binding?]) -> Statement { + public func bind(_ values: [Binding?]) -> Statement { if values.isEmpty { return self } reset() guard values.count == Int(sqlite3_bind_parameter_count(handle)) else { @@ -83,7 +83,7 @@ public final class Statement { /// statement. /// /// - Returns: The statement object (useful for chaining). - public func bind(values: [String: Binding?]) -> Statement { + public func bind(_ values: [String: Binding?]) -> Statement { reset() for (name, value) in values { let idx = sqlite3_bind_parameter_index(handle, name) @@ -95,7 +95,7 @@ public final class Statement { return self } - private func bind(value: Binding?, atIndex idx: Int) { + fileprivate func bind(_ value: Binding?, atIndex idx: Int) { if value == nil { sqlite3_bind_null(handle, Int32(idx)) } else if let value = value as? Blob { @@ -120,7 +120,7 @@ public final class Statement { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement object (useful for chaining). - public func run(bindings: Binding?...) throws -> Statement { + public func run(_ bindings: Binding?...) throws -> Statement { guard bindings.isEmpty else { return try run(bindings) } @@ -135,7 +135,7 @@ public final class Statement { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement object (useful for chaining). - public func run(bindings: [Binding?]) throws -> Statement { + public func run(_ bindings: [Binding?]) throws -> Statement { return try bind(bindings).run() } @@ -145,27 +145,27 @@ public final class Statement { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement object (useful for chaining). - public func run(bindings: [String: Binding?]) throws -> Statement { + public func run(_ bindings: [String: Binding?]) throws -> Statement { return try bind(bindings).run() } /// - Parameter bindings: A list of parameters to bind to the statement. /// /// - Returns: The first value of the first row returned. - @warn_unused_result public func scalar(bindings: Binding?...) throws -> Binding? { + public func scalar(_ bindings: Binding?...) throws -> Binding? { guard bindings.isEmpty else { return try scalar(bindings) } reset(clearBindings: false) - try step() + _ = try step() return row[0] } /// - Parameter bindings: A list of parameters to bind to the statement. /// /// - Returns: The first value of the first row returned. - @warn_unused_result public func scalar(bindings: [Binding?]) throws -> Binding? { + public func scalar(_ bindings: [Binding?]) throws -> Binding? { return try bind(bindings).scalar() } @@ -174,7 +174,7 @@ public final class Statement { /// statement. /// /// - Returns: The first value of the first row returned. - @warn_unused_result public func scalar(bindings: [String: Binding?]) throws -> Binding? { + public func scalar(_ bindings: [String: Binding?]) throws -> Binding? { return try bind(bindings).scalar() } @@ -182,23 +182,23 @@ public final class Statement { return try connection.sync { try self.connection.check(sqlite3_step(self.handle)) == SQLITE_ROW } } - private func reset(clearBindings shouldClear: Bool = true) { + fileprivate func reset(clearBindings shouldClear: Bool = true) { sqlite3_reset(handle) if (shouldClear) { sqlite3_clear_bindings(handle) } } } -extension Statement : SequenceType { +extension Statement : Sequence { - public func generate() -> Statement { + public func makeIterator() -> Statement { reset(clearBindings: false) return self } } -extension Statement : GeneratorType { +extension Statement : IteratorProtocol { public func next() -> [Binding?]? { return try! step() ? Array(row) : nil @@ -209,19 +209,19 @@ extension Statement : GeneratorType { extension Statement : CustomStringConvertible { public var description: String { - return String.fromCString(sqlite3_sql(handle))! + return String(cString: sqlite3_sql(handle)) } } public struct Cursor { - private let handle: COpaquePointer + fileprivate let handle: OpaquePointer - private let columnCount: Int + fileprivate let columnCount: Int - private init(_ statement: Statement) { - handle = statement.handle + fileprivate init(_ statement: Statement) { + handle = statement.handle! columnCount = statement.columnCount } @@ -234,13 +234,13 @@ public struct Cursor { } public subscript(idx: Int) -> String { - return String.fromCString(UnsafePointer(sqlite3_column_text(handle, Int32(idx)))) ?? "" + return String(cString: UnsafePointer(sqlite3_column_text(handle, Int32(idx)))) } public subscript(idx: Int) -> Blob { let bytes = sqlite3_column_blob(handle, Int32(idx)) let length = Int(sqlite3_column_bytes(handle, Int32(idx))) - return Blob(bytes: bytes, length: length) + return Blob(bytes: bytes!, length: length) } // MARK: - @@ -256,7 +256,7 @@ public struct Cursor { } /// Cursors provide direct access to a statement’s current row. -extension Cursor : SequenceType { +extension Cursor : Sequence { public subscript(idx: Int) -> Binding? { switch sqlite3_column_type(handle, Int32(idx)) { @@ -275,11 +275,11 @@ extension Cursor : SequenceType { } } - public func generate() -> AnyGenerator { + public func makeIterator() -> AnyIterator { var idx = 0 - return AnyGenerator { + return AnyIterator { if idx >= self.columnCount { - return Optional.None + return Optional.none } else { idx += 1 return self[idx - 1] diff --git a/SQLite/Core/Value.swift b/SQLite/Core/Value.swift index 2cfb45ed..608f0ce6 100644 --- a/SQLite/Core/Value.swift +++ b/SQLite/Core/Value.swift @@ -39,7 +39,7 @@ public protocol Value : Expressible { // extensions cannot have inheritance clau static var declaredDatatype: String { get } - static func fromDatatypeValue(datatypeValue: Datatype) -> ValueType + static func fromDatatypeValue(_ datatypeValue: Datatype) -> ValueType var datatypeValue: Datatype { get } @@ -49,7 +49,7 @@ extension Double : Number, Value { public static let declaredDatatype = "REAL" - public static func fromDatatypeValue(datatypeValue: Double) -> Double { + public static func fromDatatypeValue(_ datatypeValue: Double) -> Double { return datatypeValue } @@ -63,7 +63,7 @@ extension Int64 : Number, Value { public static let declaredDatatype = "INTEGER" - public static func fromDatatypeValue(datatypeValue: Int64) -> Int64 { + public static func fromDatatypeValue(_ datatypeValue: Int64) -> Int64 { return datatypeValue } @@ -77,7 +77,7 @@ extension String : Binding, Value { public static let declaredDatatype = "TEXT" - public static func fromDatatypeValue(datatypeValue: String) -> String { + public static func fromDatatypeValue(_ datatypeValue: String) -> String { return datatypeValue } @@ -91,7 +91,7 @@ extension Blob : Binding, Value { public static let declaredDatatype = "BLOB" - public static func fromDatatypeValue(datatypeValue: Blob) -> Blob { + public static func fromDatatypeValue(_ datatypeValue: Blob) -> Blob { return datatypeValue } @@ -107,7 +107,7 @@ extension Bool : Binding, Value { public static var declaredDatatype = Int64.declaredDatatype - public static func fromDatatypeValue(datatypeValue: Int64) -> Bool { + public static func fromDatatypeValue(_ datatypeValue: Int64) -> Bool { return datatypeValue != 0 } @@ -121,7 +121,7 @@ extension Int : Number, Value { public static var declaredDatatype = Int64.declaredDatatype - public static func fromDatatypeValue(datatypeValue: Int64) -> Int { + public static func fromDatatypeValue(_ datatypeValue: Int64) -> Int { return Int(datatypeValue) } diff --git a/SQLite/Extensions/FTS4.swift b/SQLite/Extensions/FTS4.swift index 466c42c7..52de47bf 100644 --- a/SQLite/Extensions/FTS4.swift +++ b/SQLite/Extensions/FTS4.swift @@ -24,15 +24,15 @@ extension Module { - @warn_unused_result public static func FTS4(column: Expressible, _ more: Expressible...) -> Module { + public static func FTS4(_ column: Expressible, _ more: Expressible...) -> Module { return FTS4([column] + more) } - @warn_unused_result public static func FTS4(columns: [Expressible] = [], tokenize tokenizer: Tokenizer? = nil) -> Module { + public static func FTS4(_ columns: [Expressible] = [], tokenize tokenizer: Tokenizer? = nil) -> Module { return FTS4(FTS4Config().columns(columns).tokenizer(tokenizer)) } - @warn_unused_result public static func FTS4(config: FTS4Config) -> Module { + public static func FTS4(_ config: FTS4Config) -> Module { return Module(name: "fts4", arguments: config.arguments()) } } @@ -51,15 +51,15 @@ extension VirtualTable { /// /// - Returns: An expression appended with a `MATCH` query against the given /// pattern. - @warn_unused_result public func match(pattern: String) -> Expression { + public func match(_ pattern: String) -> Expression { return "MATCH".infix(tableName(), pattern) } - @warn_unused_result public func match(pattern: Expression) -> Expression { + public func match(_ pattern: Expression) -> Expression { return "MATCH".infix(tableName(), pattern) } - @warn_unused_result public func match(pattern: Expression) -> Expression { + public func match(_ pattern: Expression) -> Expression { return "MATCH".infix(tableName(), pattern) } @@ -73,15 +73,15 @@ extension VirtualTable { /// - Parameter pattern: A pattern to match. /// /// - Returns: A query with the given `WHERE … MATCH` clause applied. - @warn_unused_result public func match(pattern: String) -> QueryType { + public func match(_ pattern: String) -> QueryType { return filter(match(pattern)) } - @warn_unused_result public func match(pattern: Expression) -> QueryType { + public func match(_ pattern: Expression) -> QueryType { return filter(match(pattern)) } - @warn_unused_result public func match(pattern: Expression) -> QueryType { + public func match(_ pattern: Expression) -> QueryType { return filter(match(pattern)) } @@ -93,7 +93,7 @@ public struct Tokenizer { public static let Porter = Tokenizer("porter") - @warn_unused_result public static func Unicode61(removeDiacritics removeDiacritics: Bool? = nil, tokenchars: Set = [], separators: Set = []) -> Tokenizer { + public static func Unicode61(removeDiacritics: Bool? = nil, tokenchars: Set = [], separators: Set = []) -> Tokenizer { var arguments = [String]() if let removeDiacritics = removeDiacritics { @@ -101,19 +101,19 @@ public struct Tokenizer { } if !tokenchars.isEmpty { - let joined = tokenchars.map { String($0) }.joinWithSeparator("") + let joined = tokenchars.map { String($0) }.joined(separator: "") arguments.append("tokenchars=\(joined)".quote()) } if !separators.isEmpty { - let joined = separators.map { String($0) }.joinWithSeparator("") + let joined = separators.map { String($0) }.joined(separator: "") arguments.append("separators=\(joined)".quote()) } return Tokenizer("unicode61", arguments) } - @warn_unused_result public static func Custom(name: String) -> Tokenizer { + public static func Custom(_ name: String) -> Tokenizer { return Tokenizer(Tokenizer.moduleName.quote(), [name.quote()]) } @@ -121,34 +121,34 @@ public struct Tokenizer { public let arguments: [String] - private init(_ name: String, _ arguments: [String] = []) { + fileprivate init(_ name: String, _ arguments: [String] = []) { self.name = name self.arguments = arguments } - private static let moduleName = "SQLite.swift" + fileprivate static let moduleName = "SQLite.swift" } extension Tokenizer : CustomStringConvertible { public var description: String { - return ([name] + arguments).joinWithSeparator(" ") + return ([name] + arguments).joined(separator: " ") } } extension Connection { - public func registerTokenizer(submoduleName: String, next: String -> (String, Range)?) throws { - try check(_SQLiteRegisterTokenizer(handle, Tokenizer.moduleName, submoduleName) { input, offset, length in - let string = String.fromCString(input)! + public func registerTokenizer(_ submoduleName: String, next: @escaping (String) -> (String, Range)?) throws { + _ = try check(_SQLiteRegisterTokenizer(handle, Tokenizer.moduleName, submoduleName) { input, offset, length in + let string = String(cString: input) guard let (token, range) = next(string) else { return nil } let view = string.utf8 - offset.memory += string.substringToIndex(range.startIndex).utf8.count - length.memory = Int32(range.startIndex.samePositionIn(view).distanceTo(range.endIndex.samePositionIn(view))) + offset.pointee += string.substring(to: range.lowerBound).utf8.count + length.pointee = Int32(view.distance(from: range.lowerBound.samePosition(in: view), to: range.lowerBound.samePosition(in: view))) return token }) } @@ -157,7 +157,7 @@ extension Connection { /// Configuration options shared between the [FTS4](https://www.sqlite.org/fts3.html) and /// [FTS5](https://www.sqlite.org/fts5.html) extensions. -public class FTSConfig { +open class FTSConfig { public enum ColumnOption { /// [The notindexed= option](https://www.sqlite.org/fts3.html#section_6_5) case unindexed @@ -171,38 +171,38 @@ public class FTSConfig { var isContentless: Bool = false /// Adds a column definition - public func column(column: Expressible, _ options: [ColumnOption] = []) -> Self { + open func column(_ column: Expressible, _ options: [ColumnOption] = []) -> Self { self.columnDefinitions.append((column, options)) return self } - public func columns(columns: [Expressible]) -> Self { + open func columns(_ columns: [Expressible]) -> Self { for column in columns { - self.column(column) + _ = self.column(column) } return self } /// [Tokenizers](https://www.sqlite.org/fts3.html#tokenizer) - public func tokenizer(tokenizer: Tokenizer?) -> Self { + open func tokenizer(_ tokenizer: Tokenizer?) -> Self { self.tokenizer = tokenizer return self } /// [The prefix= option](https://www.sqlite.org/fts3.html#section_6_6) - public func prefix(prefix: [Int]) -> Self { + open func prefix(_ prefix: [Int]) -> Self { self.prefixes += prefix return self } /// [The content= option](https://www.sqlite.org/fts3.html#section_6_2) - public func externalContent(schema: SchemaType) -> Self { + open func externalContent(_ schema: SchemaType) -> Self { self.externalContentSchema = schema return self } /// [Contentless FTS4 Tables](https://www.sqlite.org/fts3.html#section_6_2_1) - public func contentless() -> Self { + open func contentless() -> Self { self.isContentless = true return self } @@ -217,15 +217,15 @@ public class FTSConfig { func options() -> Options { var options = Options() - options.append(formatColumnDefinitions()) + _ = options.append(formatColumnDefinitions()) if let tokenizer = tokenizer { - options.append("tokenize", value: Expression(literal: tokenizer.description)) + _ = options.append("tokenize", value: Expression(literal: tokenizer.description)) } - options.appendCommaSeparated("prefix", values:prefixes.sort().map { String($0) }) + _ = options.appendCommaSeparated("prefix", values:prefixes.sorted().map { String($0) }) if isContentless { - options.append("content", value: "") + _ = options.append("content", value: "") } else if let externalContentSchema = externalContentSchema { - options.append("content", value: externalContentSchema.tableName()) + _ = options.append("content", value: externalContentSchema.tableName()) } return options } @@ -233,28 +233,28 @@ public class FTSConfig { struct Options { var arguments = [Expressible]() - mutating func append(columns: [Expressible]) -> Options { - arguments.appendContentsOf(columns) + mutating func append(_ columns: [Expressible]) -> Options { + arguments.append(contentsOf: columns) return self } - mutating func appendCommaSeparated(key: String, values: [String]) -> Options { + mutating func appendCommaSeparated(_ key: String, values: [String]) -> Options { if values.isEmpty { return self } else { - return append(key, value: values.joinWithSeparator(",")) + return append(key, value: values.joined(separator: ",")) } } - mutating func append(key: String, value: CustomStringConvertible?) -> Options { + mutating func append(_ key: String, value: CustomStringConvertible?) -> Options { return append(key, value: value?.description) } - mutating func append(key: String, value: String?) -> Options { + mutating func append(_ key: String, value: String?) -> Options { return append(key, value: value.map { Expression($0) }) } - mutating func append(key: String, value: Expressible?) -> Options { + mutating func append(_ key: String, value: Expressible?) -> Options { if let value = value { arguments.append("=".join([Expression(literal: key), value])) } @@ -264,10 +264,10 @@ public class FTSConfig { } /// Configuration for the [FTS4](https://www.sqlite.org/fts3.html) extension. -public class FTS4Config : FTSConfig { +open class FTS4Config : FTSConfig { /// [The matchinfo= option](https://www.sqlite.org/fts3.html#section_6_4) public enum MatchInfo : CustomStringConvertible { - case FTS3 + case fts3 public var description: String { return "fts3" } @@ -276,14 +276,14 @@ public class FTS4Config : FTSConfig { /// [FTS4 options](https://www.sqlite.org/fts3.html#fts4_options) public enum Order : CustomStringConvertible { /// Data structures are optimized for returning results in ascending order by docid (default) - case Asc + case asc /// FTS4 stores its data in such a way as to optimize returning results in descending order by docid. - case Desc + case desc public var description: String { switch self { - case Asc: return "asc" - case Desc: return "desc" + case .asc: return "asc" + case .desc: return "desc" } } } @@ -298,31 +298,31 @@ public class FTS4Config : FTSConfig { } /// [The compress= and uncompress= options](https://www.sqlite.org/fts3.html#section_6_1) - public func compress(functionName: String) -> Self { + open func compress(_ functionName: String) -> Self { self.compressFunction = functionName return self } /// [The compress= and uncompress= options](https://www.sqlite.org/fts3.html#section_6_1) - public func uncompress(functionName: String) -> Self { + open func uncompress(_ functionName: String) -> Self { self.uncompressFunction = functionName return self } /// [The languageid= option](https://www.sqlite.org/fts3.html#section_6_3) - public func languageId(columnName: String) -> Self { + open func languageId(_ columnName: String) -> Self { self.languageId = columnName return self } /// [The matchinfo= option](https://www.sqlite.org/fts3.html#section_6_4) - public func matchInfo(matchInfo: MatchInfo) -> Self { + open func matchInfo(_ matchInfo: MatchInfo) -> Self { self.matchInfo = matchInfo return self } /// [FTS4 options](https://www.sqlite.org/fts3.html#fts4_options) - public func order(order: Order) -> Self { + open func order(_ order: Order) -> Self { self.order = order return self } @@ -332,11 +332,11 @@ public class FTS4Config : FTSConfig { for (column, _) in (columnDefinitions.filter { $0.options.contains(.unindexed) }) { options.append("notindexed", value: column) } - options.append("languageid", value: languageId) - options.append("compress", value: compressFunction) - options.append("uncompress", value: uncompressFunction) - options.append("matchinfo", value: matchInfo) - options.append("order", value: order) + _ = options.append("languageid", value: languageId) + _ = options.append("compress", value: compressFunction) + _ = options.append("uncompress", value: uncompressFunction) + _ = options.append("matchinfo", value: matchInfo) + _ = options.append("order", value: order) return options } } diff --git a/SQLite/Extensions/FTS5.swift b/SQLite/Extensions/FTS5.swift index 97056819..9204d5b2 100644 --- a/SQLite/Extensions/FTS5.swift +++ b/SQLite/Extensions/FTS5.swift @@ -23,7 +23,7 @@ // extension Module { - @warn_unused_result public static func FTS5(config: FTS5Config) -> Module { + public static func FTS5(_ config: FTS5Config) -> Module { return Module(name: "fts5", arguments: config.arguments()) } } @@ -32,20 +32,20 @@ extension Module { /// /// **Note:** this is currently only applicable when using SQLite.swift together with a FTS5-enabled version /// of SQLite. -public class FTS5Config : FTSConfig { +open class FTS5Config : FTSConfig { public enum Detail : CustomStringConvertible { /// store rowid, column number, term offset - case Full + case full /// store rowid, column number - case Column + case column /// store rowid - case None + case none public var description: String { switch self { - case Full: return "full" - case Column: return "column" - case None: return "none" + case .full: return "full" + case .column: return "column" + case .none: return "none" } } } @@ -58,30 +58,30 @@ public class FTS5Config : FTSConfig { } /// [External Content Tables](https://www.sqlite.org/fts5.html#section_4_4_2) - public func contentRowId(column: Expressible) -> Self { + open func contentRowId(_ column: Expressible) -> Self { self.contentRowId = column return self } /// [The Columnsize Option](https://www.sqlite.org/fts5.html#section_4_5) - public func columnSize(size: Int) -> Self { + open func columnSize(_ size: Int) -> Self { self.columnSize = size return self } /// [The Detail Option](https://www.sqlite.org/fts5.html#section_4_6) - public func detail(detail: Detail) -> Self { + open func detail(_ detail: Detail) -> Self { self.detail = detail return self } override func options() -> Options { var options = super.options() - options.append("content_rowid", value: contentRowId) + _ = options.append("content_rowid", value: contentRowId) if let columnSize = columnSize { - options.append("columnsize", value: Expression(value: columnSize)) + _ = options.append("columnsize", value: Expression(value: columnSize)) } - options.append("detail", value: detail) + _ = options.append("detail", value: detail) return options } diff --git a/SQLite/Extensions/RTree.swift b/SQLite/Extensions/RTree.swift index a5571ea6..4fc1a235 100644 --- a/SQLite/Extensions/RTree.swift +++ b/SQLite/Extensions/RTree.swift @@ -24,11 +24,11 @@ extension Module { - @warn_unused_result public static func RTree(primaryKey: Expression, _ pairs: (Expression, Expression)...) -> Module { + public static func RTree(_ primaryKey: Expression, _ pairs: (Expression, Expression)...) -> Module where T.Datatype == Int64, U.Datatype == Double { var arguments: [Expressible] = [primaryKey] for pair in pairs { - arguments.appendContentsOf([pair.0, pair.1] as [Expressible]) + arguments.append(contentsOf: [pair.0, pair.1] as [Expressible]) } return Module(name: "rtree", arguments: arguments) diff --git a/SQLite/Foundation.swift b/SQLite/Foundation.swift index 52b2ea02..5c266a05 100644 --- a/SQLite/Foundation.swift +++ b/SQLite/Foundation.swift @@ -24,34 +24,36 @@ import Foundation -extension NSData : Value { +extension Data : Value { - public class var declaredDatatype: String { + public static var declaredDatatype: String { return Blob.declaredDatatype } - public class func fromDatatypeValue(dataValue: Blob) -> NSData { - return NSData(bytes: dataValue.bytes, length: dataValue.bytes.count) + public static func fromDatatypeValue(_ dataValue: Blob) -> Data { + return Data(bytes: UnsafePointer(dataValue.bytes), count: dataValue.bytes.count) } public var datatypeValue: Blob { - return Blob(bytes: bytes, length: length) + return withUnsafeBytes { ptr -> Blob in + return Blob(bytes: ptr, length: count) + } } } -extension NSDate : Value { +extension Date : Value { - public class var declaredDatatype: String { + public static var declaredDatatype: String { return String.declaredDatatype } - public class func fromDatatypeValue(stringValue: String) -> NSDate { - return dateFormatter.dateFromString(stringValue)! + public static func fromDatatypeValue(_ stringValue: String) -> Date { + return dateFormatter.date(from: stringValue)! } public var datatypeValue: String { - return dateFormatter.stringFromDate(self) + return dateFormatter.string(from: self) } } @@ -59,11 +61,11 @@ extension NSDate : Value { /// A global date formatter used to serialize and deserialize `NSDate` objects. /// If multiple date formats are used in an application’s database(s), use a /// custom `Value` type per additional format. -public var dateFormatter: NSDateFormatter = { - let formatter = NSDateFormatter() +public var dateFormatter: DateFormatter = { + let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS" - formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") - formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.timeZone = TimeZone(secondsFromGMT: 0) return formatter }() @@ -71,17 +73,17 @@ public var dateFormatter: NSDateFormatter = { extension QueryType { - public subscript(column: Expression) -> Expression { + public subscript(column: Expression) -> Expression { return namespace(column) } - public subscript(column: Expression) -> Expression { + public subscript(column: Expression) -> Expression { return namespace(column) } - public subscript(column: Expression) -> Expression { + public subscript(column: Expression) -> Expression { return namespace(column) } - public subscript(column: Expression) -> Expression { + public subscript(column: Expression) -> Expression { return namespace(column) } @@ -89,17 +91,17 @@ extension QueryType { extension Row { - public subscript(column: Expression) -> NSData { + public subscript(column: Expression) -> Data { return get(column) } - public subscript(column: Expression) -> NSData? { + public subscript(column: Expression) -> Data? { return get(column) } - public subscript(column: Expression) -> NSDate { + public subscript(column: Expression) -> Date { return get(column) } - public subscript(column: Expression) -> NSDate? { + public subscript(column: Expression) -> Date? { return get(column) } diff --git a/SQLite/Helpers.swift b/SQLite/Helpers.swift index cc6da27c..e9a17ce6 100644 --- a/SQLite/Helpers.swift +++ b/SQLite/Helpers.swift @@ -47,28 +47,28 @@ extension Optional : _OptionalType { } // let SQLITE_STATIC = unsafeBitCast(0, sqlite3_destructor_type.self) -let SQLITE_TRANSIENT = unsafeBitCast(-1, sqlite3_destructor_type.self) +let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self) extension String { - @warn_unused_result func quote(mark: Character = "\"") -> String { + func quote(_ mark: Character = "\"") -> String { let escaped = characters.reduce("") { string, character in string + (character == mark ? "\(mark)\(mark)" : "\(character)") } return "\(mark)\(escaped)\(mark)" } - @warn_unused_result func join(expressions: [Expressible]) -> Expressible { + func join(_ expressions: [Expressible]) -> Expressible { var (template, bindings) = ([String](), [Binding?]()) for expressible in expressions { let expression = expressible.expression template.append(expression.template) - bindings.appendContentsOf(expression.bindings) + bindings.append(contentsOf: expression.bindings) } - return Expression(template.joinWithSeparator(self), bindings) + return Expression(template.joined(separator: self), bindings) } - @warn_unused_result func infix(lhs: Expressible, _ rhs: Expressible, wrap: Bool = true) -> Expression { + func infix(_ lhs: Expressible, _ rhs: Expressible, wrap: Bool = true) -> Expression { let expression = Expression(" \(self) ".join([lhs, rhs]).expression) guard wrap else { return expression @@ -76,37 +76,37 @@ extension String { return "".wrap(expression) } - @warn_unused_result func prefix(expressions: Expressible) -> Expressible { + func prefix(_ expressions: Expressible) -> Expressible { return "\(self) ".wrap(expressions) as Expression } - @warn_unused_result func prefix(expressions: [Expressible]) -> Expressible { + func prefix(_ expressions: [Expressible]) -> Expressible { return "\(self) ".wrap(expressions) as Expression } - @warn_unused_result func wrap(expression: Expressible) -> Expression { + func wrap(_ expression: Expressible) -> Expression { return Expression("\(self)(\(expression.expression.template))", expression.expression.bindings) } - @warn_unused_result func wrap(expressions: [Expressible]) -> Expression { + func wrap(_ expressions: [Expressible]) -> Expression { return wrap(", ".join(expressions)) } } -@warn_unused_result func infix(lhs: Expressible, _ rhs: Expressible, wrap: Bool = true, function: String = #function) -> Expression { +func infix(_ lhs: Expressible, _ rhs: Expressible, wrap: Bool = true, function: String = #function) -> Expression { return function.infix(lhs, rhs, wrap: wrap) } -@warn_unused_result func wrap(expression: Expressible, function: String = #function) -> Expression { +func wrap(_ expression: Expressible, function: String = #function) -> Expression { return function.wrap(expression) } -@warn_unused_result func wrap(expressions: [Expressible], function: String = #function) -> Expression { +func wrap(_ expressions: [Expressible], function: String = #function) -> Expression { return function.wrap(", ".join(expressions)) } -@warn_unused_result func transcode(literal: Binding?) -> String { +func transcode(_ literal: Binding?) -> String { guard let literal = literal else { return "NULL" } switch literal { @@ -119,10 +119,10 @@ extension String { } } -@warn_unused_result func value(v: Binding) -> A { +func value(_ v: Binding) -> A { return A.fromDatatypeValue(v as! A.Datatype) as! A } -@warn_unused_result func value(v: Binding?) -> A { +func value(_ v: Binding?) -> A { return value(v!) } diff --git a/SQLite/Typed/AggregateFunctions.swift b/SQLite/Typed/AggregateFunctions.swift index 5775e0fe..249bbe60 100644 --- a/SQLite/Typed/AggregateFunctions.swift +++ b/SQLite/Typed/AggregateFunctions.swift @@ -232,7 +232,7 @@ extension ExpressionType where UnderlyingType : _OptionalType, UnderlyingType.Wr extension ExpressionType where UnderlyingType == Int { - @warn_unused_result static func count(star: Star) -> Expression { + static func count(_ star: Star) -> Expression { return wrap(star(nil, nil)) } @@ -246,6 +246,6 @@ extension ExpressionType where UnderlyingType == Int { /// /// - Returns: An expression returning `count(*)` (when called with the `*` /// function literal). -@warn_unused_result public func count(star: Star) -> Expression { +public func count(_ star: Star) -> Expression { return Expression.count(star) } diff --git a/SQLite/Typed/Collation.swift b/SQLite/Typed/Collation.swift index 5a632055..e2ff9d10 100644 --- a/SQLite/Typed/Collation.swift +++ b/SQLite/Typed/Collation.swift @@ -28,18 +28,18 @@ public enum Collation { /// Compares string by raw data. - case Binary + case binary /// Like binary, but folds uppercase ASCII letters into their lowercase /// equivalents. - case Nocase + case nocase /// Like binary, but strips trailing space. - case Rtrim + case rtrim /// A custom collating sequence identified by the given string, registered /// using `Database.create(collation:…)` - case Custom(String) + case custom(String) } @@ -55,13 +55,13 @@ extension Collation : CustomStringConvertible { public var description : String { switch self { - case Binary: + case .binary: return "BINARY" - case Nocase: + case .nocase: return "NOCASE" - case Rtrim: + case .rtrim: return "RTRIM" - case Custom(let collation): + case .custom(let collation): return collation.quote() } } diff --git a/SQLite/Typed/CoreFunctions.swift b/SQLite/Typed/CoreFunctions.swift index b597f3ba..9d17a326 100644 --- a/SQLite/Typed/CoreFunctions.swift +++ b/SQLite/Typed/CoreFunctions.swift @@ -66,7 +66,7 @@ extension ExpressionType where UnderlyingType == Double { /// // round("salary", 2) /// /// - Returns: A copy of the expression wrapped with the `round` function. - @warn_unused_result public func round(precision: Int? = nil) -> Expression { + public func round(_ precision: Int? = nil) -> Expression { guard let precision = precision else { return wrap([self]) } @@ -86,7 +86,7 @@ extension ExpressionType where UnderlyingType == Double? { /// // round("salary", 2) /// /// - Returns: A copy of the expression wrapped with the `round` function. - @warn_unused_result public func round(precision: Int? = nil) -> Expression { + public func round(_ precision: Int? = nil) -> Expression { guard let precision = precision else { return wrap(self) } @@ -103,13 +103,13 @@ extension ExpressionType where UnderlyingType : Value, UnderlyingType.Datatype = /// // random() /// /// - Returns: An expression calling the `random` function. - @warn_unused_result public static func random() -> Expression { + public static func random() -> Expression { return "random".wrap([]) } } -extension ExpressionType where UnderlyingType == NSData { +extension ExpressionType where UnderlyingType == Data { /// Builds an expression representing the `randomblob` function. /// @@ -119,7 +119,7 @@ extension ExpressionType where UnderlyingType == NSData { /// - Parameter length: Length in bytes. /// /// - Returns: An expression calling the `randomblob` function. - @warn_unused_result public static func random(length: Int) -> Expression { + public static func random(_ length: Int) -> Expression { return "randomblob".wrap([]) } @@ -131,7 +131,7 @@ extension ExpressionType where UnderlyingType == NSData { /// - Parameter length: Length in bytes. /// /// - Returns: An expression calling the `zeroblob` function. - @warn_unused_result public static func allZeros(length: Int) -> Expression { + public static func allZeros(_ length: Int) -> Expression { return "zeroblob".wrap([]) } @@ -148,7 +148,7 @@ extension ExpressionType where UnderlyingType == NSData { } -extension ExpressionType where UnderlyingType == NSData? { +extension ExpressionType where UnderlyingType == Data? { /// Builds a copy of the expression wrapped with the `length` function. /// @@ -216,7 +216,7 @@ extension ExpressionType where UnderlyingType == String { /// /// - Returns: A copy of the expression appended with a `LIKE` query against /// the given pattern. - @warn_unused_result public func like(pattern: String, escape character: Character? = nil) -> Expression { + public func like(_ pattern: String, escape character: Character? = nil) -> Expression { guard let character = character else { return "LIKE".infix(self, pattern) } @@ -234,7 +234,7 @@ extension ExpressionType where UnderlyingType == String { /// /// - Returns: A copy of the expression appended with a `GLOB` query against /// the given pattern. - @warn_unused_result public func glob(pattern: String) -> Expression { + public func glob(_ pattern: String) -> Expression { return "GLOB".infix(self, pattern) } @@ -249,7 +249,7 @@ extension ExpressionType where UnderlyingType == String { /// /// - Returns: A copy of the expression appended with a `MATCH` query /// against the given pattern. - @warn_unused_result public func match(pattern: String) -> Expression { + public func match(_ pattern: String) -> Expression { return "MATCH".infix(self, pattern) } @@ -260,7 +260,7 @@ extension ExpressionType where UnderlyingType == String { /// /// - Returns: A copy of the expression appended with a `REGEXP` query /// against the given pattern. - @warn_unused_result public func regexp(pattern: String) -> Expression { + public func regexp(_ pattern: String) -> Expression { return "REGEXP".infix(self, pattern) } @@ -275,7 +275,7 @@ extension ExpressionType where UnderlyingType == String { /// /// - Returns: A copy of the expression appended with a `COLLATE` clause /// with the given sequence. - @warn_unused_result public func collate(collation: Collation) -> Expression { + public func collate(_ collation: Collation) -> Expression { return "COLLATE".infix(self, collation) } @@ -290,7 +290,7 @@ extension ExpressionType where UnderlyingType == String { /// - Parameter characters: A set of characters to trim. /// /// - Returns: A copy of the expression wrapped with the `ltrim` function. - @warn_unused_result public func ltrim(characters: Set? = nil) -> Expression { + public func ltrim(_ characters: Set? = nil) -> Expression { guard let characters = characters else { return wrap(self) } @@ -308,7 +308,7 @@ extension ExpressionType where UnderlyingType == String { /// - Parameter characters: A set of characters to trim. /// /// - Returns: A copy of the expression wrapped with the `rtrim` function. - @warn_unused_result public func rtrim(characters: Set? = nil) -> Expression { + public func rtrim(_ characters: Set? = nil) -> Expression { guard let characters = characters else { return wrap(self) } @@ -326,7 +326,7 @@ extension ExpressionType where UnderlyingType == String { /// - Parameter characters: A set of characters to trim. /// /// - Returns: A copy of the expression wrapped with the `trim` function. - @warn_unused_result public func trim(characters: Set? = nil) -> Expression { + public func trim(_ characters: Set? = nil) -> Expression { guard let characters = characters else { return wrap([self]) } @@ -346,11 +346,11 @@ extension ExpressionType where UnderlyingType == String { /// - replacement: The replacement string. /// /// - Returns: A copy of the expression wrapped with the `replace` function. - @warn_unused_result public func replace(pattern: String, with replacement: String) -> Expression { + public func replace(_ pattern: String, with replacement: String) -> Expression { return "replace".wrap([self, pattern, replacement]) } - @warn_unused_result public func substring(location: Int, length: Int? = nil) -> Expression { + public func substring(_ location: Int, length: Int? = nil) -> Expression { guard let length = length else { return "substr".wrap([self, location]) } @@ -358,7 +358,7 @@ extension ExpressionType where UnderlyingType == String { } public subscript(range: Range) -> Expression { - return substring(range.startIndex, length: range.endIndex - range.startIndex) + return substring(range.lowerBound, length: range.upperBound - range.lowerBound) } } @@ -416,7 +416,7 @@ extension ExpressionType where UnderlyingType == String? { /// /// - Returns: A copy of the expression appended with a `LIKE` query against /// the given pattern. - @warn_unused_result public func like(pattern: String, escape character: Character? = nil) -> Expression { + public func like(_ pattern: String, escape character: Character? = nil) -> Expression { guard let character = character else { return "LIKE".infix(self, pattern) } @@ -434,7 +434,7 @@ extension ExpressionType where UnderlyingType == String? { /// /// - Returns: A copy of the expression appended with a `GLOB` query against /// the given pattern. - @warn_unused_result public func glob(pattern: String) -> Expression { + public func glob(_ pattern: String) -> Expression { return "GLOB".infix(self, pattern) } @@ -449,7 +449,7 @@ extension ExpressionType where UnderlyingType == String? { /// /// - Returns: A copy of the expression appended with a `MATCH` query /// against the given pattern. - @warn_unused_result public func match(pattern: String) -> Expression { + public func match(_ pattern: String) -> Expression { return "MATCH".infix(self, pattern) } @@ -460,7 +460,7 @@ extension ExpressionType where UnderlyingType == String? { /// /// - Returns: A copy of the expression appended with a `REGEXP` query /// against the given pattern. - @warn_unused_result public func regexp(pattern: String) -> Expression { + public func regexp(_ pattern: String) -> Expression { return "REGEXP".infix(self, pattern) } @@ -475,7 +475,7 @@ extension ExpressionType where UnderlyingType == String? { /// /// - Returns: A copy of the expression appended with a `COLLATE` clause /// with the given sequence. - @warn_unused_result public func collate(collation: Collation) -> Expression { + public func collate(_ collation: Collation) -> Expression { return "COLLATE".infix(self, collation) } @@ -490,7 +490,7 @@ extension ExpressionType where UnderlyingType == String? { /// - Parameter characters: A set of characters to trim. /// /// - Returns: A copy of the expression wrapped with the `ltrim` function. - @warn_unused_result public func ltrim(characters: Set? = nil) -> Expression { + public func ltrim(_ characters: Set? = nil) -> Expression { guard let characters = characters else { return wrap(self) } @@ -508,7 +508,7 @@ extension ExpressionType where UnderlyingType == String? { /// - Parameter characters: A set of characters to trim. /// /// - Returns: A copy of the expression wrapped with the `rtrim` function. - @warn_unused_result public func rtrim(characters: Set? = nil) -> Expression { + public func rtrim(_ characters: Set? = nil) -> Expression { guard let characters = characters else { return wrap(self) } @@ -526,7 +526,7 @@ extension ExpressionType where UnderlyingType == String? { /// - Parameter characters: A set of characters to trim. /// /// - Returns: A copy of the expression wrapped with the `trim` function. - @warn_unused_result public func trim(characters: Set? = nil) -> Expression { + public func trim(_ characters: Set? = nil) -> Expression { guard let characters = characters else { return wrap(self) } @@ -546,7 +546,7 @@ extension ExpressionType where UnderlyingType == String? { /// - replacement: The replacement string. /// /// - Returns: A copy of the expression wrapped with the `replace` function. - @warn_unused_result public func replace(pattern: String, with replacement: String) -> Expression { + public func replace(_ pattern: String, with replacement: String) -> Expression { return "replace".wrap([self, pattern, replacement]) } @@ -565,7 +565,7 @@ extension ExpressionType where UnderlyingType == String? { /// - length: An optional substring length. /// /// - Returns: A copy of the expression wrapped with the `substr` function. - @warn_unused_result public func substring(location: Int, length: Int? = nil) -> Expression { + public func substring(_ location: Int, length: Int? = nil) -> Expression { guard let length = length else { return "substr".wrap([self, location]) } @@ -582,12 +582,12 @@ extension ExpressionType where UnderlyingType == String? { /// /// - Returns: A copy of the expression wrapped with the `substr` function. public subscript(range: Range) -> Expression { - return substring(range.startIndex, length: range.endIndex - range.startIndex) + return substring(range.lowerBound, length: range.upperBound - range.lowerBound) } } -extension CollectionType where Generator.Element : Value, Index.Distance == Int { +extension Collection where Iterator.Element : Value, IndexDistance == Int { /// Builds a copy of the expression prepended with an `IN` check against the /// collection. @@ -600,8 +600,8 @@ extension CollectionType where Generator.Element : Value, Index.Distance == Int /// /// - Returns: A copy of the expression prepended with an `IN` check against /// the collection. - @warn_unused_result public func contains(expression: Expression) -> Expression { - let templates = [String](count: count, repeatedValue: "?").joinWithSeparator(", ") + public func contains(_ expression: Expression) -> Expression { + let templates = [String](repeating: "?", count: count).joined(separator: ", ") return "IN".infix(expression, Expression("(\(templates))", map { $0.datatypeValue })) } @@ -616,8 +616,8 @@ extension CollectionType where Generator.Element : Value, Index.Distance == Int /// /// - Returns: A copy of the expression prepended with an `IN` check against /// the collection. - @warn_unused_result public func contains(expression: Expression) -> Expression { - let templates = [String](count: count, repeatedValue: "?").joinWithSeparator(", ") + public func contains(_ expression: Expression) -> Expression { + let templates = [String](repeating: "?", count: count).joined(separator: ", ") return "IN".infix(expression, Expression("(\(templates))", map { $0.datatypeValue })) } diff --git a/SQLite/Typed/CustomFunctions.swift b/SQLite/Typed/CustomFunctions.swift index 068d0340..64b54edb 100644 --- a/SQLite/Typed/CustomFunctions.swift +++ b/SQLite/Typed/CustomFunctions.swift @@ -39,83 +39,83 @@ public extension Connection { /// The assigned types must be explicit. /// /// - Returns: A closure returning an SQL expression to call the function. - public func createFunction(function: String, deterministic: Bool = false, _ block: () -> Z) throws -> (() -> Expression) { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping () -> Z) throws -> (() -> Expression) { let fn = try createFunction(function, 0, deterministic) { _ in block() } return { fn([]) } } - public func createFunction(function: String, deterministic: Bool = false, _ block: () -> Z?) throws -> (() -> Expression) { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping () -> Z?) throws -> (() -> Expression) { let fn = try createFunction(function, 0, deterministic) { _ in block() } return { fn([]) } } // MARK: - - public func createFunction(function: String, deterministic: Bool = false, _ block: A -> Z) throws -> (Expression -> Expression) { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A) -> Z) throws -> ((Expression) -> Expression) { let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0])) } return { arg in fn([arg]) } } - public func createFunction(function function: String, deterministic: Bool = false, _ block: A? -> Z) throws -> (Expression -> Expression) { + public func createFunction(function: String, deterministic: Bool = false, _ block: @escaping (A?) -> Z) throws -> ((Expression) -> Expression) { let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value)) } return { arg in fn([arg]) } } - public func createFunction(function function: String, deterministic: Bool = false, _ block: A -> Z?) throws -> (Expression -> Expression) { + public func createFunction(function: String, deterministic: Bool = false, _ block: @escaping (A) -> Z?) throws -> ((Expression) -> Expression) { let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0])) } return { arg in fn([arg]) } } - public func createFunction(function function: String, deterministic: Bool = false, _ block: A? -> Z?) throws -> (Expression -> Expression) { + public func createFunction(function: String, deterministic: Bool = false, _ block: @escaping (A?) -> Z?) throws -> ((Expression) -> Expression) { let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value)) } return { arg in fn([arg]) } } // MARK: - - public func createFunction(function: String, deterministic: Bool = false, _ block: (A, B) -> Z) throws -> (Expression, Expression) -> Expression { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A, B) -> Z) throws -> (Expression, Expression) -> Expression { let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0]), value(args[1])) } return { a, b in fn([a, b]) } } - public func createFunction(function: String, deterministic: Bool = false, _ block: (A?, B) -> Z) throws -> (Expression, Expression) -> Expression { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A?, B) -> Z) throws -> (Expression, Expression) -> Expression { let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value), value(args[1])) } return { a, b in fn([a, b]) } } - public func createFunction(function: String, deterministic: Bool = false, _ block: (A, B?) -> Z) throws -> (Expression, Expression) -> Expression { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A, B?) -> Z) throws -> (Expression, Expression) -> Expression { let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0]), args[1].map(value)) } return { a, b in fn([a, b]) } } - public func createFunction(function: String, deterministic: Bool = false, _ block: (A, B) -> Z?) throws -> (Expression, Expression) -> Expression { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A, B) -> Z?) throws -> (Expression, Expression) -> Expression { let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0]), value(args[1])) } return { a, b in fn([a, b]) } } - public func createFunction(function: String, deterministic: Bool = false, _ block: (A?, B?) -> Z) throws -> (Expression, Expression) -> Expression { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A?, B?) -> Z) throws -> (Expression, Expression) -> Expression { let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value), args[1].map(value)) } return { a, b in fn([a, b]) } } - public func createFunction(function: String, deterministic: Bool = false, _ block: (A?, B) -> Z?) throws -> (Expression, Expression) -> Expression { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A?, B) -> Z?) throws -> (Expression, Expression) -> Expression { let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value), value(args[1])) } return { a, b in fn([a, b]) } } - public func createFunction(function: String, deterministic: Bool = false, _ block: (A, B?) -> Z?) throws -> (Expression, Expression) -> Expression { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A, B?) -> Z?) throws -> (Expression, Expression) -> Expression { let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0]), args[1].map(value)) } return { a, b in fn([a, b]) } } - public func createFunction(function: String, deterministic: Bool = false, _ block: (A?, B?) -> Z?) throws -> (Expression, Expression) -> Expression { + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A?, B?) -> Z?) throws -> (Expression, Expression) -> Expression { let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value), args[1].map(value)) } return { a, b in fn([a, b]) } } // MARK: - - private func createFunction(function: String, _ argumentCount: UInt, _ deterministic: Bool, _ block: [Binding?] -> Z) throws -> ([Expressible] -> Expression) { + fileprivate func createFunction(_ function: String, _ argumentCount: UInt, _ deterministic: Bool, _ block: @escaping ([Binding?]) -> Z) throws -> (([Expressible]) -> Expression) { createFunction(function, argumentCount: argumentCount, deterministic: deterministic) { arguments in block(arguments).datatypeValue } @@ -124,7 +124,7 @@ public extension Connection { } } - private func createFunction(function: String, _ argumentCount: UInt, _ deterministic: Bool, _ block: [Binding?] -> Z?) throws -> ([Expressible] -> Expression) { + fileprivate func createFunction(_ function: String, _ argumentCount: UInt, _ deterministic: Bool, _ block: @escaping ([Binding?]) -> Z?) throws -> (([Expressible]) -> Expression) { createFunction(function, argumentCount: argumentCount, deterministic: deterministic) { arguments in block(arguments)?.datatypeValue } diff --git a/SQLite/Typed/Expression.swift b/SQLite/Typed/Expression.swift index 2e71b970..3198901c 100644 --- a/SQLite/Typed/Expression.swift +++ b/SQLite/Typed/Expression.swift @@ -138,10 +138,10 @@ extension Value { public let rowid = Expression("ROWID") -public func cast(expression: Expression) -> Expression { +public func cast(_ expression: Expression) -> Expression { return Expression("CAST (\(expression.template) AS \(U.declaredDatatype))", expression.bindings) } -public func cast(expression: Expression) -> Expression { +public func cast(_ expression: Expression) -> Expression { return Expression("CAST (\(expression.template) AS \(U.declaredDatatype))", expression.bindings) } diff --git a/SQLite/Typed/Operators.swift b/SQLite/Typed/Operators.swift index 816560a5..616015dc 100644 --- a/SQLite/Typed/Operators.swift +++ b/SQLite/Typed/Operators.swift @@ -52,433 +52,433 @@ public func +(lhs: String, rhs: Expression) -> Expression { // MARK: - -public func +(lhs: Expression, rhs: Expression) -> Expression { +public func +(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func +(lhs: Expression, rhs: Expression) -> Expression { +public func +(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func +(lhs: Expression, rhs: Expression) -> Expression { +public func +(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func +(lhs: Expression, rhs: Expression) -> Expression { +public func +(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func +(lhs: Expression, rhs: V) -> Expression { +public func +(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func +(lhs: Expression, rhs: V) -> Expression { +public func +(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func +(lhs: V, rhs: Expression) -> Expression { +public func +(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func +(lhs: V, rhs: Expression) -> Expression { +public func +(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func -(lhs: Expression, rhs: Expression) -> Expression { +public func -(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func -(lhs: Expression, rhs: Expression) -> Expression { +public func -(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func -(lhs: Expression, rhs: Expression) -> Expression { +public func -(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func -(lhs: Expression, rhs: Expression) -> Expression { +public func -(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func -(lhs: Expression, rhs: V) -> Expression { +public func -(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func -(lhs: Expression, rhs: V) -> Expression { +public func -(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func -(lhs: V, rhs: Expression) -> Expression { +public func -(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func -(lhs: V, rhs: Expression) -> Expression { +public func -(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func *(lhs: Expression, rhs: Expression) -> Expression { +public func *(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func *(lhs: Expression, rhs: Expression) -> Expression { +public func *(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func *(lhs: Expression, rhs: Expression) -> Expression { +public func *(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func *(lhs: Expression, rhs: Expression) -> Expression { +public func *(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func *(lhs: Expression, rhs: V) -> Expression { +public func *(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func *(lhs: Expression, rhs: V) -> Expression { +public func *(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func *(lhs: V, rhs: Expression) -> Expression { +public func *(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func *(lhs: V, rhs: Expression) -> Expression { +public func *(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func /(lhs: Expression, rhs: Expression) -> Expression { +public func /(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func /(lhs: Expression, rhs: Expression) -> Expression { +public func /(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func /(lhs: Expression, rhs: Expression) -> Expression { +public func /(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func /(lhs: Expression, rhs: Expression) -> Expression { +public func /(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func /(lhs: Expression, rhs: V) -> Expression { +public func /(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func /(lhs: Expression, rhs: V) -> Expression { +public func /(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func /(lhs: V, rhs: Expression) -> Expression { +public func /(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public func /(lhs: V, rhs: Expression) -> Expression { +public func /(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { return infix(lhs, rhs) } -public prefix func -(rhs: Expression) -> Expression { +public prefix func -(rhs: Expression) -> Expression where V.Datatype : Number { return wrap(rhs) } -public prefix func -(rhs: Expression) -> Expression { +public prefix func -(rhs: Expression) -> Expression where V.Datatype : Number { return wrap(rhs) } // MARK: - -public func %(lhs: Expression, rhs: Expression) -> Expression { +public func %(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func %(lhs: Expression, rhs: Expression) -> Expression { +public func %(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func %(lhs: Expression, rhs: Expression) -> Expression { +public func %(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func %(lhs: Expression, rhs: Expression) -> Expression { +public func %(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func %(lhs: Expression, rhs: V) -> Expression { +public func %(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func %(lhs: Expression, rhs: V) -> Expression { +public func %(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func %(lhs: V, rhs: Expression) -> Expression { +public func %(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func %(lhs: V, rhs: Expression) -> Expression { +public func %(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func <<(lhs: Expression, rhs: Expression) -> Expression { +public func <<(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func <<(lhs: Expression, rhs: Expression) -> Expression { +public func <<(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func <<(lhs: Expression, rhs: Expression) -> Expression { +public func <<(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func <<(lhs: Expression, rhs: Expression) -> Expression { +public func <<(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func <<(lhs: Expression, rhs: V) -> Expression { +public func <<(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func <<(lhs: Expression, rhs: V) -> Expression { +public func <<(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func <<(lhs: V, rhs: Expression) -> Expression { +public func <<(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func <<(lhs: V, rhs: Expression) -> Expression { +public func <<(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func >>(lhs: Expression, rhs: Expression) -> Expression { +public func >>(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func >>(lhs: Expression, rhs: Expression) -> Expression { +public func >>(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func >>(lhs: Expression, rhs: Expression) -> Expression { +public func >>(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func >>(lhs: Expression, rhs: Expression) -> Expression { +public func >>(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func >>(lhs: Expression, rhs: V) -> Expression { +public func >>(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func >>(lhs: Expression, rhs: V) -> Expression { +public func >>(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func >>(lhs: V, rhs: Expression) -> Expression { +public func >>(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func >>(lhs: V, rhs: Expression) -> Expression { +public func >>(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func &(lhs: Expression, rhs: Expression) -> Expression { +public func &(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func &(lhs: Expression, rhs: Expression) -> Expression { +public func &(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func &(lhs: Expression, rhs: Expression) -> Expression { +public func &(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func &(lhs: Expression, rhs: Expression) -> Expression { +public func &(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func &(lhs: Expression, rhs: V) -> Expression { +public func &(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func &(lhs: Expression, rhs: V) -> Expression { +public func &(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func &(lhs: V, rhs: Expression) -> Expression { +public func &(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func &(lhs: V, rhs: Expression) -> Expression { +public func &(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func |(lhs: Expression, rhs: Expression) -> Expression { +public func |(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func |(lhs: Expression, rhs: Expression) -> Expression { +public func |(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func |(lhs: Expression, rhs: Expression) -> Expression { +public func |(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func |(lhs: Expression, rhs: Expression) -> Expression { +public func |(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func |(lhs: Expression, rhs: V) -> Expression { +public func |(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func |(lhs: Expression, rhs: V) -> Expression { +public func |(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func |(lhs: V, rhs: Expression) -> Expression { +public func |(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func |(lhs: V, rhs: Expression) -> Expression { +public func |(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return infix(lhs, rhs) } -public func ^(lhs: Expression, rhs: Expression) -> Expression { +public func ^(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return (~(lhs & rhs)) & (lhs | rhs) } -public func ^(lhs: Expression, rhs: Expression) -> Expression { +public func ^(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return (~(lhs & rhs)) & (lhs | rhs) } -public func ^(lhs: Expression, rhs: Expression) -> Expression { +public func ^(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return (~(lhs & rhs)) & (lhs | rhs) } -public func ^(lhs: Expression, rhs: Expression) -> Expression { +public func ^(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { return (~(lhs & rhs)) & (lhs | rhs) } -public func ^(lhs: Expression, rhs: V) -> Expression { +public func ^(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return (~(lhs & rhs)) & (lhs | rhs) } -public func ^(lhs: Expression, rhs: V) -> Expression { +public func ^(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { return (~(lhs & rhs)) & (lhs | rhs) } -public func ^(lhs: V, rhs: Expression) -> Expression { +public func ^(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return (~(lhs & rhs)) & (lhs | rhs) } -public func ^(lhs: V, rhs: Expression) -> Expression { +public func ^(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { return (~(lhs & rhs)) & (lhs | rhs) } -public prefix func ~(rhs: Expression) -> Expression { +public prefix func ~(rhs: Expression) -> Expression where V.Datatype == Int64 { return wrap(rhs) } -public prefix func ~(rhs: Expression) -> Expression { +public prefix func ~(rhs: Expression) -> Expression where V.Datatype == Int64 { return wrap(rhs) } // MARK: - -public func ==(lhs: Expression, rhs: Expression) -> Expression { +public func ==(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { return "=".infix(lhs, rhs) } -public func ==(lhs: Expression, rhs: Expression) -> Expression { +public func ==(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { return "=".infix(lhs, rhs) } -public func ==(lhs: Expression, rhs: Expression) -> Expression { +public func ==(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { return "=".infix(lhs, rhs) } -public func ==(lhs: Expression, rhs: Expression) -> Expression { +public func ==(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { return "=".infix(lhs, rhs) } -public func ==(lhs: Expression, rhs: V) -> Expression { +public func ==(lhs: Expression, rhs: V) -> Expression where V.Datatype : Equatable { return "=".infix(lhs, rhs) } -public func ==(lhs: Expression, rhs: V?) -> Expression { +public func ==(lhs: Expression, rhs: V?) -> Expression where V.Datatype : Equatable { guard let rhs = rhs else { return "IS".infix(lhs, Expression(value: nil)) } return "=".infix(lhs, rhs) } -public func ==(lhs: V, rhs: Expression) -> Expression { +public func ==(lhs: V, rhs: Expression) -> Expression where V.Datatype : Equatable { return "=".infix(lhs, rhs) } -public func ==(lhs: V?, rhs: Expression) -> Expression { +public func ==(lhs: V?, rhs: Expression) -> Expression where V.Datatype : Equatable { guard let lhs = lhs else { return "IS".infix(Expression(value: nil), rhs) } return "=".infix(lhs, rhs) } -public func !=(lhs: Expression, rhs: Expression) -> Expression { +public func !=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { return infix(lhs, rhs) } -public func !=(lhs: Expression, rhs: Expression) -> Expression { +public func !=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { return infix(lhs, rhs) } -public func !=(lhs: Expression, rhs: Expression) -> Expression { +public func !=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { return infix(lhs, rhs) } -public func !=(lhs: Expression, rhs: Expression) -> Expression { +public func !=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { return infix(lhs, rhs) } -public func !=(lhs: Expression, rhs: V) -> Expression { +public func !=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Equatable { return infix(lhs, rhs) } -public func !=(lhs: Expression, rhs: V?) -> Expression { +public func !=(lhs: Expression, rhs: V?) -> Expression where V.Datatype : Equatable { guard let rhs = rhs else { return "IS NOT".infix(lhs, Expression(value: nil)) } return infix(lhs, rhs) } -public func !=(lhs: V, rhs: Expression) -> Expression { +public func !=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Equatable { return infix(lhs, rhs) } -public func !=(lhs: V?, rhs: Expression) -> Expression { +public func !=(lhs: V?, rhs: Expression) -> Expression where V.Datatype : Equatable { guard let lhs = lhs else { return "IS NOT".infix(Expression(value: nil), rhs) } return infix(lhs, rhs) } -public func >(lhs: Expression, rhs: Expression) -> Expression { +public func >(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >(lhs: Expression, rhs: Expression) -> Expression { +public func >(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >(lhs: Expression, rhs: Expression) -> Expression { +public func >(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >(lhs: Expression, rhs: Expression) -> Expression { +public func >(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >(lhs: Expression, rhs: V) -> Expression { +public func >(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >(lhs: Expression, rhs: V) -> Expression { +public func >(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >(lhs: V, rhs: Expression) -> Expression { +public func >(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >(lhs: V, rhs: Expression) -> Expression { +public func >(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >=(lhs: Expression, rhs: Expression) -> Expression { +public func >=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >=(lhs: Expression, rhs: Expression) -> Expression { +public func >=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >=(lhs: Expression, rhs: Expression) -> Expression { +public func >=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >=(lhs: Expression, rhs: Expression) -> Expression { +public func >=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >=(lhs: Expression, rhs: V) -> Expression { +public func >=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >=(lhs: Expression, rhs: V) -> Expression { +public func >=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >=(lhs: V, rhs: Expression) -> Expression { +public func >=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func >=(lhs: V, rhs: Expression) -> Expression { +public func >=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <(lhs: Expression, rhs: Expression) -> Expression { +public func <(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <(lhs: Expression, rhs: Expression) -> Expression { +public func <(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <(lhs: Expression, rhs: Expression) -> Expression { +public func <(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <(lhs: Expression, rhs: Expression) -> Expression { +public func <(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <(lhs: Expression, rhs: V) -> Expression { +public func <(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <(lhs: Expression, rhs: V) -> Expression { +public func <(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <(lhs: V, rhs: Expression) -> Expression { +public func <(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <(lhs: V, rhs: Expression) -> Expression { +public func <(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <=(lhs: Expression, rhs: Expression) -> Expression { +public func <=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <=(lhs: Expression, rhs: Expression) -> Expression { +public func <=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <=(lhs: Expression, rhs: Expression) -> Expression { +public func <=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <=(lhs: Expression, rhs: Expression) -> Expression { +public func <=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <=(lhs: Expression, rhs: V) -> Expression { +public func <=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <=(lhs: Expression, rhs: V) -> Expression { +public func <=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <=(lhs: V, rhs: Expression) -> Expression { +public func <=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func <=(lhs: V, rhs: Expression) -> Expression { +public func <=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { return infix(lhs, rhs) } -public func ~=, V.Datatype == I.Bound>(lhs: I, rhs: Expression) -> Expression { - return Expression("\(rhs.template) BETWEEN ? AND ?", rhs.bindings + [lhs.start, lhs.end]) +public func ~=(lhs: CountableClosedRange, rhs: Expression) -> Expression where V.Datatype : Binding & Comparable { + return Expression("\(rhs.template) BETWEEN ? AND ?", rhs.bindings + [lhs.lowerBound as? Binding, lhs.upperBound as? Binding]) } -public func ~=, V.Datatype == I.Bound>(lhs: I, rhs: Expression) -> Expression { - return Expression("\(rhs.template) BETWEEN ? AND ?", rhs.bindings + [lhs.start, lhs.end]) +public func ~=(lhs: CountableClosedRange, rhs: Expression) -> Expression where V.Datatype : Binding & Comparable { + return Expression("\(rhs.template) BETWEEN ? AND ?", rhs.bindings + [lhs.lowerBound as? Binding, lhs.upperBound as? Binding]) } // MARK: - diff --git a/SQLite/Typed/Query.swift b/SQLite/Typed/Query.swift index 36b3b2e1..d0e4572d 100644 --- a/SQLite/Typed/Query.swift +++ b/SQLite/Typed/Query.swift @@ -50,7 +50,7 @@ extension SchemaType { /// - Parameter all: A list of expressions to select. /// /// - Returns: A query with the given `SELECT` clause applied. - public func select(column1: Expressible, _ more: Expressible...) -> Self { + public func select(_ column1: Expressible, _ more: Expressible...) -> Self { return select(false, [column1] + more) } @@ -81,7 +81,7 @@ extension SchemaType { /// - Parameter all: A list of expressions to select. /// /// - Returns: A query with the given `SELECT` clause applied. - public func select(all: [Expressible]) -> Self { + public func select(_ all: [Expressible]) -> Self { return select(false, all) } @@ -110,7 +110,7 @@ extension SchemaType { /// - Parameter star: A star literal. /// /// - Returns: A query with the given `SELECT *` clause applied. - public func select(star: Star) -> Self { + public func select(_ star: Star) -> Self { return select([star(nil, nil)]) } @@ -139,10 +139,10 @@ extension SchemaType { /// - Parameter all: A list of expressions to select. /// /// - Returns: A query with the given `SELECT` clause applied. - public func select(column: Expression) -> ScalarQuery { + public func select(_ column: Expression) -> ScalarQuery { return select(false, [column]) } - public func select(column: Expression) -> ScalarQuery { + public func select(_ column: Expression) -> ScalarQuery { return select(false, [column]) } @@ -173,7 +173,7 @@ extension SchemaType { extension QueryType { - private func select(distinct: Bool, _ columns: [Expressible]) -> Q { + fileprivate func select(_ distinct: Bool, _ columns: [Expressible]) -> Q { var query = Q.init(clauses.from.name, database: clauses.from.database) query.clauses = clauses query.clauses.select = (distinct, columns) @@ -199,7 +199,7 @@ extension QueryType { /// - condition: A boolean expression describing the join condition. /// /// - Returns: A query with the given `JOIN` clause applied. - public func join(table: QueryType, on condition: Expression) -> Self { + public func join(_ table: QueryType, on condition: Expression) -> Self { return join(table, on: Expression(condition)) } @@ -220,7 +220,7 @@ extension QueryType { /// - condition: A boolean expression describing the join condition. /// /// - Returns: A query with the given `JOIN` clause applied. - public func join(table: QueryType, on condition: Expression) -> Self { + public func join(_ table: QueryType, on condition: Expression) -> Self { return join(.Inner, table, on: condition) } @@ -243,7 +243,7 @@ extension QueryType { /// - condition: A boolean expression describing the join condition. /// /// - Returns: A query with the given `JOIN` clause applied. - public func join(type: JoinType, _ table: QueryType, on condition: Expression) -> Self { + public func join(_ type: JoinType, _ table: QueryType, on condition: Expression) -> Self { return join(type, table, on: Expression(condition)) } @@ -266,7 +266,7 @@ extension QueryType { /// - condition: A boolean expression describing the join condition. /// /// - Returns: A query with the given `JOIN` clause applied. - public func join(type: JoinType, _ table: QueryType, on condition: Expression) -> Self { + public func join(_ type: JoinType, _ table: QueryType, on condition: Expression) -> Self { var query = self query.clauses.join.append((type: type, query: table, condition: table.clauses.filters.map { condition && $0 } ?? condition as Expressible)) return query @@ -285,7 +285,7 @@ extension QueryType { /// - Parameter condition: A boolean expression to filter on. /// /// - Returns: A query with the given `WHERE` clause applied. - public func filter(predicate: Expression) -> Self { + public func filter(_ predicate: Expression) -> Self { return filter(Expression(predicate)) } @@ -300,7 +300,7 @@ extension QueryType { /// - Parameter condition: A boolean expression to filter on. /// /// - Returns: A query with the given `WHERE` clause applied. - public func filter(predicate: Expression) -> Self { + public func filter(_ predicate: Expression) -> Self { var query = self query.clauses.filters = query.clauses.filters.map { $0 && predicate } ?? predicate return query @@ -313,7 +313,7 @@ extension QueryType { /// - Parameter by: A list of columns to group by. /// /// - Returns: A query with the given `GROUP BY` clause applied. - public func group(by: Expressible...) -> Self { + public func group(_ by: Expressible...) -> Self { return group(by) } @@ -322,7 +322,7 @@ extension QueryType { /// - Parameter by: A list of columns to group by. /// /// - Returns: A query with the given `GROUP BY` clause applied. - public func group(by: [Expressible]) -> Self { + public func group(_ by: [Expressible]) -> Self { return group(by, nil) } @@ -335,7 +335,7 @@ extension QueryType { /// - having: A condition determining which groups are returned. /// /// - Returns: A query with the given `GROUP BY`–`HAVING` clause applied. - public func group(by: Expressible, having: Expression) -> Self { + public func group(_ by: Expressible, having: Expression) -> Self { return group([by], having: having) } @@ -348,7 +348,7 @@ extension QueryType { /// - having: A condition determining which groups are returned. /// /// - Returns: A query with the given `GROUP BY`–`HAVING` clause applied. - public func group(by: Expressible, having: Expression) -> Self { + public func group(_ by: Expressible, having: Expression) -> Self { return group([by], having: having) } @@ -361,7 +361,7 @@ extension QueryType { /// - having: A condition determining which groups are returned. /// /// - Returns: A query with the given `GROUP BY`–`HAVING` clause applied. - public func group(by: [Expressible], having: Expression) -> Self { + public func group(_ by: [Expressible], having: Expression) -> Self { return group(by, Expression(having)) } @@ -374,11 +374,11 @@ extension QueryType { /// - having: A condition determining which groups are returned. /// /// - Returns: A query with the given `GROUP BY`–`HAVING` clause applied. - public func group(by: [Expressible], having: Expression) -> Self { + public func group(_ by: [Expressible], having: Expression) -> Self { return group(by, having) } - private func group(by: [Expressible], _ having: Expression?) -> Self { + fileprivate func group(_ by: [Expressible], _ having: Expression?) -> Self { var query = self query.clauses.group = (by, having) return query @@ -398,7 +398,7 @@ extension QueryType { /// - Parameter by: An ordered list of columns and directions to sort by. /// /// - Returns: A query with the given `ORDER BY` clause applied. - public func order(by: Expressible...) -> Self { + public func order(_ by: Expressible...) -> Self { return order(by) } @@ -414,7 +414,7 @@ extension QueryType { /// - Parameter by: An ordered list of columns and directions to sort by. /// /// - Returns: A query with the given `ORDER BY` clause applied. - public func order(by: [Expressible]) -> Self { + public func order(_ by: [Expressible]) -> Self { var query = self query.clauses.order = by return query @@ -433,7 +433,7 @@ extension QueryType { /// return unlimited rows). /// /// - Returns: A query with the given LIMIT clause applied. - public func limit(length: Int?) -> Self { + public func limit(_ length: Int?) -> Self { return limit(length, nil) } @@ -451,12 +451,12 @@ extension QueryType { /// - offset: The number of rows to skip. /// /// - Returns: A query with the given LIMIT and OFFSET clauses applied. - public func limit(length: Int, offset: Int) -> Self { + public func limit(_ length: Int, offset: Int) -> Self { return limit(length, offset) } // prevents limit(nil, offset: 5) - private func limit(length: Int?, _ offset: Int?) -> Self { + fileprivate func limit(_ length: Int?, _ offset: Int?) -> Self { var query = self query.clauses.limit = length.map { ($0, offset) } return query @@ -468,7 +468,7 @@ extension QueryType { // MARK: - - private var selectClause: Expressible { + fileprivate var selectClause: Expressible { return " ".join([ Expression(literal: clauses.select.distinct ? "SELECT DISTINCT" : "SELECT"), ", ".join(clauses.select.columns), @@ -477,7 +477,7 @@ extension QueryType { ]) } - private var joinClause: Expressible? { + fileprivate var joinClause: Expressible? { guard !clauses.join.isEmpty else { return nil } @@ -492,7 +492,7 @@ extension QueryType { }) } - private var whereClause: Expressible? { + fileprivate var whereClause: Expressible? { guard let filters = clauses.filters else { return nil } @@ -503,7 +503,7 @@ extension QueryType { ]) } - private var groupByClause: Expressible? { + fileprivate var groupByClause: Expressible? { guard let group = clauses.group else { return nil } @@ -526,7 +526,7 @@ extension QueryType { ]) } - private var orderClause: Expressible? { + fileprivate var orderClause: Expressible? { guard !clauses.order.isEmpty else { return nil } @@ -537,7 +537,7 @@ extension QueryType { ]) } - private var limitOffsetClause: Expressible? { + fileprivate var limitOffsetClause: Expressible? { guard let limit = clauses.limit else { return nil } @@ -556,7 +556,7 @@ extension QueryType { // MARK: - - public func alias(aliasName: String) -> Self { + public func alias(_ aliasName: String) -> Self { var query = self query.clauses.from = (clauses.from.name, aliasName, clauses.from.database) return query @@ -566,11 +566,11 @@ extension QueryType { // // MARK: INSERT - public func insert(value: Setter, _ more: Setter...) -> Insert { + public func insert(_ value: Setter, _ more: Setter...) -> Insert { return insert([value] + more) } - public func insert(values: [Setter]) -> Insert { + public func insert(_ values: [Setter]) -> Insert { return insert(nil, values) } @@ -582,7 +582,7 @@ extension QueryType { return insert(onConflict, values) } - private func insert(or: OnConflict?, _ values: [Setter]) -> Insert { + fileprivate func insert(_ or: OnConflict?, _ values: [Setter]) -> Insert { let insert = values.reduce((columns: [Expressible](), values: [Expressible]())) { insert, setter in (insert.columns + [setter.column], insert.values + [setter.value]) } @@ -616,7 +616,7 @@ extension QueryType { /// - Parameter query: A query to `SELECT` results from. /// /// - Returns: The number of updated rows and statement. - public func insert(query: QueryType) -> Update { + public func insert(_ query: QueryType) -> Update { return Update(" ".join([ Expression(literal: "INSERT INTO"), tableName(), @@ -626,11 +626,11 @@ extension QueryType { // MARK: UPDATE - public func update(values: Setter...) -> Update { + public func update(_ values: Setter...) -> Update { return update(values) } - public func update(values: [Setter]) -> Update { + public func update(_ values: [Setter]) -> Update { let clauses: [Expressible?] = [ Expression(literal: "UPDATE"), tableName(), @@ -671,7 +671,7 @@ extension QueryType { /// /// - Returns: A column expression namespaced with the query’s table name or /// alias. - public func namespace(column: Expression) -> Expression { + public func namespace(_ column: Expression) -> Expression { return Expression(".".join([tableName(), column]).expression) } @@ -733,7 +733,7 @@ extension QueryType { // TODO: alias support func tableName(alias aliased: Bool = false) -> Expressible { - guard let alias = clauses.from.alias where aliased else { + guard let alias = clauses.from.alias , aliased else { return database(namespace: clauses.from.alias ?? clauses.from.name) } @@ -744,7 +744,7 @@ extension QueryType { ]) } - func tableName(qualified qualified: Bool) -> Expressible { + func tableName(qualified: Bool) -> Expressible { if qualified { return tableName() } @@ -880,7 +880,7 @@ public struct Delete : ExpressionType { extension Connection { - public func prepare(query: QueryType) throws -> AnySequence { + public func prepare(_ query: QueryType) throws -> AnySequence { let expression = query.expression let statement = try prepare(expression.template, expression.bindings) @@ -889,11 +889,11 @@ extension Connection { column: for each in query.clauses.select.columns ?? [Expression(literal: "*")] { var names = each.expression.template.characters.split { $0 == "." }.map(String.init) let column = names.removeLast() - let namespace = names.joinWithSeparator(".") + let namespace = names.joined(separator: ".") - func expandGlob(namespace: Bool) -> (QueryType throws -> Void) { + func expandGlob(_ namespace: Bool) -> ((QueryType) throws -> Void) { return { (query: QueryType) throws -> (Void) in - var q = query.dynamicType.init(query.clauses.from.name, database: query.clauses.from.database) + var q = type(of: query).init(query.clauses.from.name, database: query.clauses.from.database) q.clauses.select = query.clauses.select let e = q.expression var names = try self.prepare(e.template, e.bindings).columnNames.map { $0.quote() } @@ -928,34 +928,34 @@ extension Connection { }() return AnySequence { - AnyGenerator { statement.next().map { Row(columnNames, $0) } } + AnyIterator { statement.next().map { Row(columnNames, $0) } } } } - public func scalar(query: ScalarQuery) throws -> V { + public func scalar(_ query: ScalarQuery) throws -> V { let expression = query.expression return value(try scalar(expression.template, expression.bindings)) } - public func scalar(query: ScalarQuery) throws -> V.ValueType? { + public func scalar(_ query: ScalarQuery) throws -> V.ValueType? { let expression = query.expression guard let value = try scalar(expression.template, expression.bindings) as? V.Datatype else { return nil } return V.fromDatatypeValue(value) } - public func scalar(query: Select) throws -> V { + public func scalar(_ query: Select) throws -> V { let expression = query.expression return value(try scalar(expression.template, expression.bindings)) } - public func scalar(query: Select) throws -> V.ValueType? { + public func scalar(_ query: Select) throws -> V.ValueType? { let expression = query.expression guard let value = try scalar(expression.template, expression.bindings) as? V.Datatype else { return nil } return V.fromDatatypeValue(value) } - public func pluck(query: QueryType) throws -> Row? { - return try prepare(query.limit(1, query.clauses.limit?.offset)).generate().next() + public func pluck(_ query: QueryType) throws -> Row? { + return try prepare(query.limit(1, query.clauses.limit?.offset)).makeIterator().next() } /// Runs an `Insert` query. @@ -968,10 +968,10 @@ extension Connection { /// - Parameter query: An insert query. /// /// - Returns: The insert’s rowid. - public func run(query: Insert) throws -> Int64 { + public func run(_ query: Insert) throws -> Int64 { let expression = query.expression return try sync { - try self.run(expression.template, expression.bindings) + _ = try self.run(expression.template, expression.bindings) return self.lastInsertRowid! } } @@ -984,10 +984,10 @@ extension Connection { /// - Parameter query: An update query. /// /// - Returns: The number of updated rows. - public func run(query: Update) throws -> Int { + public func run(_ query: Update) throws -> Int { let expression = query.expression return try sync { - try self.run(expression.template, expression.bindings) + _ = try self.run(expression.template, expression.bindings) return self.changes } } @@ -999,10 +999,10 @@ extension Connection { /// - Parameter query: A delete query. /// /// - Returns: The number of deleted rows. - public func run(query: Delete) throws -> Int { + public func run(_ query: Delete) throws -> Int { let expression = query.expression return try sync { - try self.run(expression.template, expression.bindings) + _ = try self.run(expression.template, expression.bindings) return self.changes } } @@ -1011,11 +1011,11 @@ extension Connection { public struct Row { - private let columnNames: [String: Int] + fileprivate let columnNames: [String: Int] - private let values: [Binding?] + fileprivate let values: [Binding?] - private init(_ columnNames: [String: Int], _ values: [Binding?]) { + fileprivate init(_ columnNames: [String: Int], _ values: [Binding?]) { self.columnNames = columnNames self.values = values } @@ -1025,11 +1025,11 @@ public struct Row { /// - Parameter column: An expression representing a column selected in a Query. /// /// - Returns: The value for the given column. - public func get(column: Expression) -> V { + public func get(_ column: Expression) -> V { return get(Expression(column))! } - public func get(column: Expression) -> V? { - func valueAtIndex(idx: Int) -> V? { + public func get(_ column: Expression) -> V? { + func valueAtIndex(_ idx: Int) -> V? { guard let value = values[idx] as? V.Datatype else { return nil } return (V.fromDatatypeValue(value) as? V)! } @@ -1039,7 +1039,7 @@ public struct Row { switch similar.count { case 0: - fatalError("no such column '\(column.template)' in columns: \(columnNames.keys.sort())") + fatalError("no such column '\(column.template)' in columns: \(columnNames.keys.sorted())") case 1: return valueAtIndex(columnNames[similar[0]]!) default: @@ -1143,7 +1143,7 @@ public struct QueryClauses { var limit: (length: Int, offset: Int?)? - private init(_ name: String, alias: String?, database: String?) { + fileprivate init(_ name: String, alias: String?, database: String?) { self.from = (name, alias, database) } diff --git a/SQLite/Typed/Schema.swift b/SQLite/Typed/Schema.swift index 16e11c16..4c6862c0 100644 --- a/SQLite/Typed/Schema.swift +++ b/SQLite/Typed/Schema.swift @@ -26,7 +26,7 @@ extension SchemaType { // MARK: - DROP TABLE / VIEW / VIRTUAL TABLE - public func drop(ifExists ifExists: Bool = false) -> String { + public func drop(ifExists: Bool = false) -> String { return drop("TABLE", tableName(), ifExists) } @@ -36,7 +36,7 @@ extension Table { // MARK: - CREATE TABLE - public func create(temporary temporary: Bool = false, ifNotExists: Bool = false, @noescape block: TableBuilder -> Void) -> String { + public func create(temporary: Bool = false, ifNotExists: Bool = false, block: (TableBuilder) -> Void) -> String { let builder = TableBuilder() block(builder) @@ -49,7 +49,7 @@ extension Table { return " ".join(clauses.flatMap { $0 }).asSQL() } - public func create(query: QueryType, temporary: Bool = false, ifNotExists: Bool = false) -> String { + public func create(_ query: QueryType, temporary: Bool = false, ifNotExists: Bool = false) -> String { let clauses: [Expressible?] = [ create(Table.identifier, tableName(), temporary ? .Temporary : nil, ifNotExists), Expression(literal: "AS"), @@ -61,55 +61,55 @@ extension Table { // MARK: - ALTER TABLE … ADD COLUMN - public func addColumn(name: Expression, check: Expression? = nil, defaultValue: V) -> String { + public func addColumn(_ name: Expression, check: Expression? = nil, defaultValue: V) -> String { return addColumn(definition(name, V.declaredDatatype, nil, false, false, check, defaultValue, nil, nil)) } - public func addColumn(name: Expression, check: Expression, defaultValue: V) -> String { + public func addColumn(_ name: Expression, check: Expression, defaultValue: V) -> String { return addColumn(definition(name, V.declaredDatatype, nil, false, false, check, defaultValue, nil, nil)) } - public func addColumn(name: Expression, check: Expression? = nil, defaultValue: V? = nil) -> String { + public func addColumn(_ name: Expression, check: Expression? = nil, defaultValue: V? = nil) -> String { return addColumn(definition(name, V.declaredDatatype, nil, true, false, check, defaultValue, nil, nil)) } - public func addColumn(name: Expression, check: Expression, defaultValue: V? = nil) -> String { + public func addColumn(_ name: Expression, check: Expression, defaultValue: V? = nil) -> String { return addColumn(definition(name, V.declaredDatatype, nil, true, false, check, defaultValue, nil, nil)) } - public func addColumn(name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) -> String { + public func addColumn(_ name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) -> String where V.Datatype == Int64 { return addColumn(definition(name, V.declaredDatatype, nil, false, unique, check, nil, (table, other), nil)) } - public func addColumn(name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) -> String { + public func addColumn(_ name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) -> String where V.Datatype == Int64 { return addColumn(definition(name, V.declaredDatatype, nil, false, unique, check, nil, (table, other), nil)) } - public func addColumn(name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) -> String { + public func addColumn(_ name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) -> String where V.Datatype == Int64 { return addColumn(definition(name, V.declaredDatatype, nil, true, unique, check, nil, (table, other), nil)) } - public func addColumn(name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) -> String { + public func addColumn(_ name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) -> String where V.Datatype == Int64 { return addColumn(definition(name, V.declaredDatatype, nil, true, unique, check, nil, (table, other), nil)) } - public func addColumn(name: Expression, check: Expression? = nil, defaultValue: V, collate: Collation) -> String { + public func addColumn(_ name: Expression, check: Expression? = nil, defaultValue: V, collate: Collation) -> String where V.Datatype == String { return addColumn(definition(name, V.declaredDatatype, nil, false, false, check, defaultValue, nil, collate)) } - public func addColumn(name: Expression, check: Expression, defaultValue: V, collate: Collation) -> String { + public func addColumn(_ name: Expression, check: Expression, defaultValue: V, collate: Collation) -> String where V.Datatype == String { return addColumn(definition(name, V.declaredDatatype, nil, false, false, check, defaultValue, nil, collate)) } - public func addColumn(name: Expression, check: Expression? = nil, defaultValue: V? = nil, collate: Collation) -> String { + public func addColumn(_ name: Expression, check: Expression? = nil, defaultValue: V? = nil, collate: Collation) -> String where V.Datatype == String { return addColumn(definition(name, V.declaredDatatype, nil, true, false, check, defaultValue, nil, collate)) } - public func addColumn(name: Expression, check: Expression, defaultValue: V? = nil, collate: Collation) -> String { + public func addColumn(_ name: Expression, check: Expression, defaultValue: V? = nil, collate: Collation) -> String where V.Datatype == String { return addColumn(definition(name, V.declaredDatatype, nil, true, false, check, defaultValue, nil, collate)) } - private func addColumn(expression: Expressible) -> String { + fileprivate func addColumn(_ expression: Expressible) -> String { return " ".join([ Expression(literal: "ALTER TABLE"), tableName(), @@ -120,17 +120,17 @@ extension Table { // MARK: - ALTER TABLE … RENAME TO - public func rename(to: Table) -> String { + public func rename(_ to: Table) -> String { return rename(to: to) } // MARK: - CREATE INDEX - public func createIndex(columns: Expressible...) -> String { + public func createIndex(_ columns: Expressible...) -> String { return createIndex(columns) } - public func createIndex(columns: [Expressible], unique: Bool = false, ifNotExists: Bool = false) -> String { + public func createIndex(_ columns: [Expressible], unique: Bool = false, ifNotExists: Bool = false) -> String { let clauses: [Expressible?] = [ create("INDEX", indexName(columns), unique ? .Unique : nil, ifNotExists), Expression(literal: "ON"), @@ -143,16 +143,16 @@ extension Table { // MARK: - DROP INDEX - public func dropIndex(columns: Expressible...) -> String { + public func dropIndex(_ columns: Expressible...) -> String { return dropIndex(columns) } - public func dropIndex(columns: [Expressible], ifExists: Bool = false) -> String { + public func dropIndex(_ columns: [Expressible], ifExists: Bool = false) -> String { return drop("INDEX", indexName(columns), ifExists) } - private func indexName(columns: [Expressible]) -> Expressible { - let string = (["index", clauses.from.name, "on"] + columns.map { $0.expression.template }).joinWithSeparator(" ").lowercaseString + fileprivate func indexName(_ columns: [Expressible]) -> Expressible { + let string = (["index", clauses.from.name, "on"] + columns.map { $0.expression.template }).joined(separator: " ").lowercased() let index = string.characters.reduce("") { underscored, character in guard character != "\"" else { @@ -173,7 +173,7 @@ extension View { // MARK: - CREATE VIEW - public func create(query: QueryType, temporary: Bool = false, ifNotExists: Bool = false) -> String { + public func create(_ query: QueryType, temporary: Bool = false, ifNotExists: Bool = false) -> String { let clauses: [Expressible?] = [ create(View.identifier, tableName(), temporary ? .Temporary : nil, ifNotExists), Expression(literal: "AS"), @@ -185,7 +185,7 @@ extension View { // MARK: - DROP VIEW - public func drop(ifExists ifExists: Bool = false) -> String { + public func drop(ifExists: Bool = false) -> String { return drop("VIEW", tableName(), ifExists) } @@ -195,7 +195,7 @@ extension VirtualTable { // MARK: - CREATE VIRTUAL TABLE - public func create(using: Module, ifNotExists: Bool = false) -> String { + public func create(_ using: Module, ifNotExists: Bool = false) -> String { let clauses: [Expressible?] = [ create(VirtualTable.identifier, tableName(), nil, ifNotExists), Expression(literal: "USING"), @@ -207,7 +207,7 @@ extension VirtualTable { // MARK: - ALTER TABLE … RENAME TO - public func rename(to: VirtualTable) -> String { + public func rename(_ to: VirtualTable) -> String { return rename(to: to) } @@ -215,155 +215,155 @@ extension VirtualTable { public final class TableBuilder { - private var definitions = [Expressible]() + fileprivate var definitions = [Expressible]() - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil) { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V) { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil) { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: V) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: V) { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil) { column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression) { column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V) { column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil) { column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression) { column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: V) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: V) { column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) } - public func column(name: Expression, primaryKey: Bool, check: Expression? = nil, defaultValue: Expression? = nil) { - column(name, V.declaredDatatype, primaryKey ? .Default : nil, false, false, check, defaultValue, nil, nil) + public func column(_ name: Expression, primaryKey: Bool, check: Expression? = nil, defaultValue: Expression? = nil) { + column(name, V.declaredDatatype, primaryKey ? .default : nil, false, false, check, defaultValue, nil, nil) } - public func column(name: Expression, primaryKey: Bool, check: Expression, defaultValue: Expression? = nil) { - column(name, V.declaredDatatype, primaryKey ? .Default : nil, false, false, check, defaultValue, nil, nil) + public func column(_ name: Expression, primaryKey: Bool, check: Expression, defaultValue: Expression? = nil) { + column(name, V.declaredDatatype, primaryKey ? .default : nil, false, false, check, defaultValue, nil, nil) } - public func column(name: Expression, primaryKey: PrimaryKey, check: Expression? = nil) { + public func column(_ name: Expression, primaryKey: PrimaryKey, check: Expression? = nil) where V.Datatype == Int64 { column(name, V.declaredDatatype, primaryKey, false, false, check, nil, nil, nil) } - public func column(name: Expression, primaryKey: PrimaryKey, check: Expression) { + public func column(_ name: Expression, primaryKey: PrimaryKey, check: Expression) where V.Datatype == Int64 { column(name, V.declaredDatatype, primaryKey, false, false, check, nil, nil, nil) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) where V.Datatype == Int64 { column(name, V.declaredDatatype, nil, false, unique, check, nil, (table, other), nil) } - public func column(name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) where V.Datatype == Int64 { column(name, V.declaredDatatype, nil, false, unique, check, nil, (table, other), nil) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) where V.Datatype == Int64 { column(name, V.declaredDatatype, nil, true, unique, check, nil, (table, other), nil) } - public func column(name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) where V.Datatype == Int64 { column(name, V.declaredDatatype, nil, true, unique, check, nil, (table, other), nil) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: V, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: V, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - public func column(name: Expression, unique: Bool = false, check: Expression, defaultValue: V, collate: Collation) { + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: V, collate: Collation) where V.Datatype == String { column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) } - private func column(name: Expressible, _ datatype: String, _ primaryKey: PrimaryKey?, _ null: Bool, _ unique: Bool, _ check: Expressible?, _ defaultValue: Expressible?, _ references: (QueryType, Expressible)?, _ collate: Collation?) { + fileprivate func column(_ name: Expressible, _ datatype: String, _ primaryKey: PrimaryKey?, _ null: Bool, _ unique: Bool, _ check: Expressible?, _ defaultValue: Expressible?, _ references: (QueryType, Expressible)?, _ collate: Collation?) { definitions.append(definition(name, datatype, primaryKey, null, unique, check, defaultValue, references, collate)) } // MARK: - - public func primaryKey(column: Expression) { + public func primaryKey(_ column: Expression) { primaryKey([column]) } - public func primaryKey(compositeA: Expression, _ b: Expression) { + public func primaryKey(_ compositeA: Expression, _ b: Expression) { primaryKey([compositeA, b]) } - public func primaryKey(compositeA: Expression, _ b: Expression, _ c: Expression) { + public func primaryKey(_ compositeA: Expression, _ b: Expression, _ c: Expression) { primaryKey([compositeA, b, c]) } - private func primaryKey(composite: [Expressible]) { + fileprivate func primaryKey(_ composite: [Expressible]) { definitions.append("PRIMARY KEY".prefix(composite)) } - public func unique(columns: Expressible...) { + public func unique(_ columns: Expressible...) { unique(columns) } - public func unique(columns: [Expressible]) { + public func unique(_ columns: [Expressible]) { definitions.append("UNIQUE".prefix(columns)) } - public func check(condition: Expression) { + public func check(_ condition: Expression) { check(Expression(condition)) } - public func check(condition: Expression) { + public func check(_ condition: Expression) { definitions.append("CHECK".prefix(condition)) } @@ -381,29 +381,29 @@ public final class TableBuilder { } - public func foreignKey(column: Expression, references table: QueryType, _ other: Expression, update: Dependency? = nil, delete: Dependency? = nil) { + public func foreignKey(_ column: Expression, references table: QueryType, _ other: Expression, update: Dependency? = nil, delete: Dependency? = nil) { foreignKey(column, (table, other), update, delete) } - public func foreignKey(column: Expression, references table: QueryType, _ other: Expression, update: Dependency? = nil, delete: Dependency? = nil) { + public func foreignKey(_ column: Expression, references table: QueryType, _ other: Expression, update: Dependency? = nil, delete: Dependency? = nil) { foreignKey(column, (table, other), update, delete) } - public func foreignKey(composite: (Expression, Expression), references table: QueryType, _ other: (Expression, Expression), update: Dependency? = nil, delete: Dependency? = nil) { + public func foreignKey(_ composite: (Expression, Expression), references table: QueryType, _ other: (Expression, Expression), update: Dependency? = nil, delete: Dependency? = nil) { let composite = ", ".join([composite.0, composite.1]) let references = (table, ", ".join([other.0, other.1])) foreignKey(composite, references, update, delete) } - public func foreignKey(composite: (Expression, Expression, Expression), references table: QueryType, _ other: (Expression, Expression, Expression), update: Dependency? = nil, delete: Dependency? = nil) { + public func foreignKey(_ composite: (Expression, Expression, Expression), references table: QueryType, _ other: (Expression, Expression, Expression), update: Dependency? = nil, delete: Dependency? = nil) { let composite = ", ".join([composite.0, composite.1, composite.2]) let references = (table, ", ".join([other.0, other.1, other.2])) foreignKey(composite, references, update, delete) } - private func foreignKey(column: Expressible, _ references: (QueryType, Expressible), _ update: Dependency?, _ delete: Dependency?) { + fileprivate func foreignKey(_ column: Expressible, _ references: (QueryType, Expressible), _ update: Dependency?, _ delete: Dependency?) { let clauses: [Expressible?] = [ "FOREIGN KEY".prefix(column), reference(references), @@ -418,17 +418,17 @@ public final class TableBuilder { public enum PrimaryKey { - case Default + case `default` - case Autoincrement + case autoincrement } public struct Module { - private let name: String + fileprivate let name: String - private let arguments: [Expressible] + fileprivate let arguments: [Expressible] public init(_ name: String, _ arguments: [Expressible]) { self.init(name: name.quote(), arguments: arguments) @@ -453,7 +453,7 @@ extension Module : Expressible { private extension QueryType { - func create(identifier: String, _ name: Expressible, _ modifier: Modifier?, _ ifNotExists: Bool) -> Expressible { + func create(_ identifier: String, _ name: Expressible, _ modifier: Modifier?, _ ifNotExists: Bool) -> Expressible { let clauses: [Expressible?] = [ Expression(literal: "CREATE"), modifier.map { Expression(literal: $0.rawValue) }, @@ -465,7 +465,7 @@ private extension QueryType { return " ".join(clauses.flatMap { $0 }) } - func rename(to to: Self) -> String { + func rename(to: Self) -> String { return " ".join([ Expression(literal: "ALTER TABLE"), tableName(), @@ -474,7 +474,7 @@ private extension QueryType { ]).asSQL() } - func drop(identifier: String, _ name: Expressible, _ ifExists: Bool) -> String { + func drop(_ identifier: String, _ name: Expressible, _ ifExists: Bool) -> String { let clauses: [Expressible?] = [ Expression(literal: "DROP \(identifier)"), ifExists ? Expression(literal: "IF EXISTS") : nil, @@ -486,11 +486,11 @@ private extension QueryType { } -private func definition(column: Expressible, _ datatype: String, _ primaryKey: PrimaryKey?, _ null: Bool, _ unique: Bool, _ check: Expressible?, _ defaultValue: Expressible?, _ references: (QueryType, Expressible)?, _ collate: Collation?) -> Expressible { +private func definition(_ column: Expressible, _ datatype: String, _ primaryKey: PrimaryKey?, _ null: Bool, _ unique: Bool, _ check: Expressible?, _ defaultValue: Expressible?, _ references: (QueryType, Expressible)?, _ collate: Collation?) -> Expressible { let clauses: [Expressible?] = [ column, Expression(literal: datatype), - primaryKey.map { Expression(literal: $0 == .Autoincrement ? "PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY") }, + primaryKey.map { Expression(literal: $0 == .autoincrement ? "PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY") }, null ? nil : Expression(literal: "NOT NULL"), unique ? Expression(literal: "UNIQUE") : nil, check.map { " ".join([Expression(literal: "CHECK"), $0]) }, @@ -502,7 +502,7 @@ private func definition(column: Expressible, _ datatype: String, _ primaryKey: P return " ".join(clauses.flatMap { $0 }) } -private func reference(primary: (QueryType, Expressible)) -> Expressible { +private func reference(_ primary: (QueryType, Expressible)) -> Expressible { return " ".join([ Expression(literal: "REFERENCES"), primary.0.tableName(qualified: false), diff --git a/SQLite/Typed/Setter.swift b/SQLite/Typed/Setter.swift index d8bf775a..86f16fca 100644 --- a/SQLite/Typed/Setter.swift +++ b/SQLite/Typed/Setter.swift @@ -22,38 +22,40 @@ // THE SOFTWARE. // -infix operator <- { - associativity left - precedence 135 - assignment +precedencegroup ColumnAssignment { + associativity: left + assignment: true + lowerThan: AssignmentPrecedence } +infix operator <- : ColumnAssignment + public struct Setter { let column: Expressible let value: Expressible - private init(column: Expression, value: Expression) { + fileprivate init(column: Expression, value: Expression) { self.column = column self.value = value } - private init(column: Expression, value: V) { + fileprivate init(column: Expression, value: V) { self.column = column self.value = value } - private init(column: Expression, value: Expression) { + fileprivate init(column: Expression, value: Expression) { self.column = column self.value = value } - private init(column: Expression, value: Expression) { + fileprivate init(column: Expression, value: Expression) { self.column = column self.value = value } - private init(column: Expression, value: V?) { + fileprivate init(column: Expression, value: V?) { self.column = column self.value = Expression(value: value) } @@ -100,176 +102,176 @@ public func +=(column: Expression, value: String) -> Setter { return column <- column + value } -public func +=(column: Expression, value: Expression) -> Setter { +public func +=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column + value } -public func +=(column: Expression, value: V) -> Setter { +public func +=(column: Expression, value: V) -> Setter where V.Datatype : Number { return column <- column + value } -public func +=(column: Expression, value: Expression) -> Setter { +public func +=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column + value } -public func +=(column: Expression, value: Expression) -> Setter { +public func +=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column + value } -public func +=(column: Expression, value: V) -> Setter { +public func +=(column: Expression, value: V) -> Setter where V.Datatype : Number { return column <- column + value } -public func -=(column: Expression, value: Expression) -> Setter { +public func -=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column - value } -public func -=(column: Expression, value: V) -> Setter { +public func -=(column: Expression, value: V) -> Setter where V.Datatype : Number { return column <- column - value } -public func -=(column: Expression, value: Expression) -> Setter { +public func -=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column - value } -public func -=(column: Expression, value: Expression) -> Setter { +public func -=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column - value } -public func -=(column: Expression, value: V) -> Setter { +public func -=(column: Expression, value: V) -> Setter where V.Datatype : Number { return column <- column - value } -public func *=(column: Expression, value: Expression) -> Setter { +public func *=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column * value } -public func *=(column: Expression, value: V) -> Setter { +public func *=(column: Expression, value: V) -> Setter where V.Datatype : Number { return column <- column * value } -public func *=(column: Expression, value: Expression) -> Setter { +public func *=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column * value } -public func *=(column: Expression, value: Expression) -> Setter { +public func *=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column * value } -public func *=(column: Expression, value: V) -> Setter { +public func *=(column: Expression, value: V) -> Setter where V.Datatype : Number { return column <- column * value } -public func /=(column: Expression, value: Expression) -> Setter { +public func /=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column / value } -public func /=(column: Expression, value: V) -> Setter { +public func /=(column: Expression, value: V) -> Setter where V.Datatype : Number { return column <- column / value } -public func /=(column: Expression, value: Expression) -> Setter { +public func /=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column / value } -public func /=(column: Expression, value: Expression) -> Setter { +public func /=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { return column <- column / value } -public func /=(column: Expression, value: V) -> Setter { +public func /=(column: Expression, value: V) -> Setter where V.Datatype : Number { return column <- column / value } -public func %=(column: Expression, value: Expression) -> Setter { +public func %=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column % value } -public func %=(column: Expression, value: V) -> Setter { +public func %=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column % value } -public func %=(column: Expression, value: Expression) -> Setter { +public func %=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column % value } -public func %=(column: Expression, value: Expression) -> Setter { +public func %=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column % value } -public func %=(column: Expression, value: V) -> Setter { +public func %=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column % value } -public func <<=(column: Expression, value: Expression) -> Setter { +public func <<=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column << value } -public func <<=(column: Expression, value: V) -> Setter { +public func <<=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column << value } -public func <<=(column: Expression, value: Expression) -> Setter { +public func <<=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column << value } -public func <<=(column: Expression, value: Expression) -> Setter { +public func <<=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column << value } -public func <<=(column: Expression, value: V) -> Setter { +public func <<=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column << value } -public func >>=(column: Expression, value: Expression) -> Setter { +public func >>=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column >> value } -public func >>=(column: Expression, value: V) -> Setter { +public func >>=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column >> value } -public func >>=(column: Expression, value: Expression) -> Setter { +public func >>=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column >> value } -public func >>=(column: Expression, value: Expression) -> Setter { +public func >>=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column >> value } -public func >>=(column: Expression, value: V) -> Setter { +public func >>=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column >> value } -public func &=(column: Expression, value: Expression) -> Setter { +public func &=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column & value } -public func &=(column: Expression, value: V) -> Setter { +public func &=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column & value } -public func &=(column: Expression, value: Expression) -> Setter { +public func &=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column & value } -public func &=(column: Expression, value: Expression) -> Setter { +public func &=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column & value } -public func &=(column: Expression, value: V) -> Setter { +public func &=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column & value } -public func |=(column: Expression, value: Expression) -> Setter { +public func |=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column | value } -public func |=(column: Expression, value: V) -> Setter { +public func |=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column | value } -public func |=(column: Expression, value: Expression) -> Setter { +public func |=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column | value } -public func |=(column: Expression, value: Expression) -> Setter { +public func |=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column | value } -public func |=(column: Expression, value: V) -> Setter { +public func |=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column | value } -public func ^=(column: Expression, value: Expression) -> Setter { +public func ^=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column ^ value } -public func ^=(column: Expression, value: V) -> Setter { +public func ^=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column ^ value } -public func ^=(column: Expression, value: Expression) -> Setter { +public func ^=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column ^ value } -public func ^=(column: Expression, value: Expression) -> Setter { +public func ^=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { return column <- column ^ value } -public func ^=(column: Expression, value: V) -> Setter { +public func ^=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { return column <- column ^ value } -public postfix func ++(column: Expression) -> Setter { +public postfix func ++(column: Expression) -> Setter where V.Datatype == Int64 { return Expression(column) += 1 } -public postfix func ++(column: Expression) -> Setter { +public postfix func ++(column: Expression) -> Setter where V.Datatype == Int64 { return Expression(column) += 1 } -public postfix func --(column: Expression) -> Setter { +public postfix func --(column: Expression) -> Setter where V.Datatype == Int64 { return Expression(column) -= 1 } -public postfix func --(column: Expression) -> Setter { +public postfix func --(column: Expression) -> Setter where V.Datatype == Int64 { return Expression(column) -= 1 } diff --git a/SQLiteTests/ConnectionTests.swift b/SQLiteTests/ConnectionTests.swift index 3d7dd3eb..0e8ebea6 100644 --- a/SQLiteTests/ConnectionTests.swift +++ b/SQLiteTests/ConnectionTests.swift @@ -10,7 +10,7 @@ class ConnectionTests : SQLiteTestCase { } func test_init_withInMemory_returnsInMemoryConnection() { - let db = try! Connection(.InMemory) + let db = try! Connection(.inMemory) XCTAssertEqual("", db.description) } @@ -20,12 +20,12 @@ class ConnectionTests : SQLiteTestCase { } func test_init_withTemporary_returnsTemporaryConnection() { - let db = try! Connection(.Temporary) + let db = try! Connection(.temporary) XCTAssertEqual("", db.description) } func test_init_withURI_returnsURIConnection() { - let db = try! Connection(.URI("\(NSTemporaryDirectory())/SQLite.swift Tests.sqlite3")) + let db = try! Connection(.uri("\(NSTemporaryDirectory())/SQLite.swift Tests.sqlite3")) XCTAssertEqual("\(NSTemporaryDirectory())/SQLite.swift Tests.sqlite3", db.description) } @@ -48,7 +48,7 @@ class ConnectionTests : SQLiteTestCase { } func test_lastInsertRowid_returnsLastIdAfterInserts() { - try! InsertUser("alice") + _ = try! InsertUser("alice") XCTAssertEqual(1, db.lastInsertRowid!) } @@ -57,17 +57,17 @@ class ConnectionTests : SQLiteTestCase { } func test_changes_returnsNumberOfChanges() { - try! InsertUser("alice") + _ = try! InsertUser("alice") XCTAssertEqual(1, db.changes) - try! InsertUser("betsy") + _ = try! InsertUser("betsy") XCTAssertEqual(1, db.changes) } func test_totalChanges_returnsTotalNumberOfChanges() { XCTAssertEqual(0, db.totalChanges) - try! InsertUser("alice") + _ = try! InsertUser("alice") XCTAssertEqual(1, db.totalChanges) - try! InsertUser("betsy") + _ = try! InsertUser("betsy") XCTAssertEqual(2, db.totalChanges) } @@ -79,10 +79,10 @@ class ConnectionTests : SQLiteTestCase { } func test_run_preparesRunsAndReturnsStatements() { - try! db.run("SELECT * FROM users WHERE admin = 0") - try! db.run("SELECT * FROM users WHERE admin = ?", 0) - try! db.run("SELECT * FROM users WHERE admin = ?", [0]) - try! db.run("SELECT * FROM users WHERE admin = $admin", ["$admin": 0]) + _ = try! db.run("SELECT * FROM users WHERE admin = 0") + _ = try! db.run("SELECT * FROM users WHERE admin = ?", 0) + _ = try! db.run("SELECT * FROM users WHERE admin = ?", [0]) + _ = try! db.run("SELECT * FROM users WHERE admin = $admin", ["$admin": 0]) AssertSQL("SELECT * FROM users WHERE admin = 0", 4) } @@ -116,7 +116,7 @@ class ConnectionTests : SQLiteTestCase { let stmt = try! db.prepare("INSERT INTO users (email) VALUES (?)", "alice@example.com") try! db.transaction { - try stmt.run() + _ = try stmt.run() } AssertSQL("BEGIN DEFERRED TRANSACTION") @@ -130,8 +130,8 @@ class ConnectionTests : SQLiteTestCase { do { try db.transaction { - try stmt.run() - try stmt.run() + _ = try stmt.run() + _ = try stmt.run() } } catch { } @@ -147,7 +147,7 @@ class ConnectionTests : SQLiteTestCase { try! db.savepoint("1") { try db.savepoint("2") { - try db.run("INSERT INTO users (email) VALUES (?)", "alice@example.com") + _ = try db.run("INSERT INTO users (email) VALUES (?)", "alice@example.com") } } @@ -167,14 +167,14 @@ class ConnectionTests : SQLiteTestCase { do { try db.savepoint("1") { try db.savepoint("2") { - try stmt.run() - try stmt.run() - try stmt.run() + _ = try stmt.run() + _ = try stmt.run() + _ = try stmt.run() } try db.savepoint("2") { - try stmt.run() - try stmt.run() - try stmt.run() + _ = try stmt.run() + _ = try stmt.run() + _ = try stmt.run() } } } catch { @@ -192,41 +192,41 @@ class ConnectionTests : SQLiteTestCase { func test_updateHook_setsUpdateHook_withInsert() { async { done in db.updateHook { operation, db, table, rowid in - XCTAssertEqual(Operation.Insert, operation) + XCTAssertEqual(Operation.insert, operation) XCTAssertEqual("main", db) XCTAssertEqual("users", table) XCTAssertEqual(1, rowid) done() } - try! InsertUser("alice") + _ = try! InsertUser("alice") } } func test_updateHook_setsUpdateHook_withUpdate() { - try! InsertUser("alice") + _ = try! InsertUser("alice") async { done in db.updateHook { operation, db, table, rowid in - XCTAssertEqual(Operation.Update, operation) + XCTAssertEqual(Operation.update, operation) XCTAssertEqual("main", db) XCTAssertEqual("users", table) XCTAssertEqual(1, rowid) done() } - try! db.run("UPDATE users SET email = 'alice@example.com'") + _ = try! db.run("UPDATE users SET email = 'alice@example.com'") } } func test_updateHook_setsUpdateHook_withDelete() { - try! InsertUser("alice") + _ = try! InsertUser("alice") async { done in db.updateHook { operation, db, table, rowid in - XCTAssertEqual(Operation.Delete, operation) + XCTAssertEqual(Operation.delete, operation) XCTAssertEqual("main", db) XCTAssertEqual("users", table) XCTAssertEqual(1, rowid) done() } - try! db.run("DELETE FROM users WHERE id = 1") + _ = try! db.run("DELETE FROM users WHERE id = 1") } } @@ -236,7 +236,7 @@ class ConnectionTests : SQLiteTestCase { done() } try! db.transaction { - try self.InsertUser("alice") + _ = try self.InsertUser("alice") } XCTAssertEqual(1, try! db.scalar("SELECT count(*) FROM users") as? Int64) } @@ -247,8 +247,8 @@ class ConnectionTests : SQLiteTestCase { db.rollbackHook(done) do { try db.transaction { - try self.InsertUser("alice") - try self.InsertUser("alice") // throw + _ = try self.InsertUser("alice") + _ = try self.InsertUser("alice") // throw } } catch { } @@ -264,7 +264,7 @@ class ConnectionTests : SQLiteTestCase { db.rollbackHook(done) do { try db.transaction { - try self.InsertUser("alice") + _ = try self.InsertUser("alice") } } catch { } @@ -288,14 +288,14 @@ class ConnectionTests : SQLiteTestCase { func test_createCollation_createsCollation() { try! db.createCollation("NODIACRITIC") { lhs, rhs in - return lhs.compare(rhs, options: .DiacriticInsensitiveSearch) + return lhs.compare(rhs, options: .diacriticInsensitive) } XCTAssertEqual(1, try! db.scalar("SELECT ? = ? COLLATE NODIACRITIC", "cafe", "café") as? Int64) } func test_createCollation_createsQuotableCollation() { try! db.createCollation("NO DIACRITIC") { lhs, rhs in - return lhs.compare(rhs, options: .DiacriticInsensitiveSearch) + return lhs.compare(rhs, options: .diacriticInsensitive) } XCTAssertEqual(1, try! db.scalar("SELECT ? = ? COLLATE \"NO DIACRITIC\"", "cafe", "café") as? Int64) } @@ -308,9 +308,9 @@ class ConnectionTests : SQLiteTestCase { } let stmt = try! db.prepare("SELECT *, sleep(?) FROM users", 0.1) - try! stmt.run() + _ = try! stmt.run() - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(10 * NSEC_PER_MSEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), db.interrupt) + _ = DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.background).asyncAfter(deadline: DispatchTime.now() + Double(Int64(10 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC), execute: db.interrupt) AssertThrows(try stmt.run()) } diff --git a/SQLiteTests/CoreFunctionsTests.swift b/SQLiteTests/CoreFunctionsTests.swift index 8f7460d5..db37ff7f 100644 --- a/SQLiteTests/CoreFunctionsTests.swift +++ b/SQLiteTests/CoreFunctionsTests.swift @@ -55,15 +55,15 @@ class CoreFunctionsTests : XCTestCase { } func test_collate_buildsExpressionWithCollateOperator() { - AssertSQL("(\"string\" COLLATE BINARY)", string.collate(.Binary)) - AssertSQL("(\"string\" COLLATE NOCASE)", string.collate(.Nocase)) - AssertSQL("(\"string\" COLLATE RTRIM)", string.collate(.Rtrim)) - AssertSQL("(\"string\" COLLATE \"CUSTOM\")", string.collate(.Custom("CUSTOM"))) - - AssertSQL("(\"stringOptional\" COLLATE BINARY)", stringOptional.collate(.Binary)) - AssertSQL("(\"stringOptional\" COLLATE NOCASE)", stringOptional.collate(.Nocase)) - AssertSQL("(\"stringOptional\" COLLATE RTRIM)", stringOptional.collate(.Rtrim)) - AssertSQL("(\"stringOptional\" COLLATE \"CUSTOM\")", stringOptional.collate(.Custom("CUSTOM"))) + AssertSQL("(\"string\" COLLATE BINARY)", string.collate(.binary)) + AssertSQL("(\"string\" COLLATE NOCASE)", string.collate(.nocase)) + AssertSQL("(\"string\" COLLATE RTRIM)", string.collate(.rtrim)) + AssertSQL("(\"string\" COLLATE \"CUSTOM\")", string.collate(.custom("CUSTOM"))) + + AssertSQL("(\"stringOptional\" COLLATE BINARY)", stringOptional.collate(.binary)) + AssertSQL("(\"stringOptional\" COLLATE NOCASE)", stringOptional.collate(.nocase)) + AssertSQL("(\"stringOptional\" COLLATE RTRIM)", stringOptional.collate(.rtrim)) + AssertSQL("(\"stringOptional\" COLLATE \"CUSTOM\")", stringOptional.collate(.custom("CUSTOM"))) } func test_ltrim_wrapsStringWithLtrimFunction() { diff --git a/SQLiteTests/FTS4Tests.swift b/SQLiteTests/FTS4Tests.swift index 8b4e4f96..37a773a6 100644 --- a/SQLiteTests/FTS4Tests.swift +++ b/SQLiteTests/FTS4Tests.swift @@ -121,19 +121,19 @@ class FTS4ConfigTests : XCTestCase { func test_config_matchinfo() { XCTAssertEqual( "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(matchinfo=\"fts3\")", - sql(config.matchInfo(.FTS3))) + sql(config.matchInfo(.fts3))) } func test_config_order_asc() { XCTAssertEqual( "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(order=\"asc\")", - sql(config.order(.Asc))) + sql(config.order(.asc))) } func test_config_order_desc() { XCTAssertEqual( "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(order=\"desc\")", - sql(config.order(.Desc))) + sql(config.order(.desc))) } func test_config_compress() { @@ -163,14 +163,14 @@ class FTS4ConfigTests : XCTestCase { .column(string, [.unindexed]) .column(date, [.unindexed]) .externalContent(table) - .matchInfo(.FTS3) + .matchInfo(.fts3) .languageId("lid") - .order(.Desc) + .order(.desc) .prefix([2, 4])) ) } - func sql(config: FTS4Config) -> String { + func sql(_ config: FTS4Config) -> String { return virtualTable.create(.FTS4(config)) } } @@ -184,24 +184,24 @@ class FTS4IntegrationTests : SQLiteTestCase { let locale = CFLocaleCopyCurrent() let tokenizerName = "tokenizer" - let tokenizer = CFStringTokenizerCreate(nil, "", CFRangeMake(0, 0), UInt(kCFStringTokenizerUnitWord), locale) + let tokenizer = CFStringTokenizerCreate(nil, "" as CFString!, CFRangeMake(0, 0), UInt(kCFStringTokenizerUnitWord), locale) try! db.registerTokenizer(tokenizerName) { string in - CFStringTokenizerSetString(tokenizer, string, CFRangeMake(0, CFStringGetLength(string))) - if CFStringTokenizerAdvanceToNextToken(tokenizer) == .None { + CFStringTokenizerSetString(tokenizer, string as CFString, CFRangeMake(0, CFStringGetLength(string as CFString))) + if CFStringTokenizerAdvanceToNextToken(tokenizer) == .none { return nil } let range = CFStringTokenizerGetCurrentTokenRange(tokenizer) - let input = CFStringCreateWithSubstring(kCFAllocatorDefault, string, range) + let input = CFStringCreateWithSubstring(kCFAllocatorDefault, string as CFString, range) let token = CFStringCreateMutableCopy(nil, range.length, input) CFStringLowercase(token, locale) CFStringTransform(token, nil, kCFStringTransformStripDiacritics, false) - return (token as String, string.rangeOfString(input as String)!) + return ((token as String?)!, string.range(of: (input as String?)!)!) } - try! db.run(emails.create(.FTS4([subject, body], tokenize: .Custom(tokenizerName)))) + _ = try! db.run(emails.create(.FTS4([subject, body], tokenize: .Custom(tokenizerName)))) AssertSQL("CREATE VIRTUAL TABLE \"emails\" USING fts4(\"subject\", \"body\", tokenize=\"SQLite.swift\" \"tokenizer\")") - try! db.run(emails.insert(subject <- "Aún más cáfe!")) + _ = try! db.run(emails.insert(subject <- "Aún más cáfe!")) XCTAssertEqual(1, try! db.scalar(emails.filter(emails.match("aun")).count)) } #endif diff --git a/SQLiteTests/FTS5Tests.swift b/SQLiteTests/FTS5Tests.swift index aa3965bd..63d8dc40 100644 --- a/SQLiteTests/FTS5Tests.swift +++ b/SQLiteTests/FTS5Tests.swift @@ -90,19 +90,19 @@ class FTS5Tests: XCTestCase { func test_detail_full() { XCTAssertEqual( "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(detail=\"full\")", - sql(config.detail(.Full))) + sql(config.detail(.full))) } func test_detail_column() { XCTAssertEqual( "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(detail=\"column\")", - sql(config.detail(.Column))) + sql(config.detail(.column))) } func test_detail_none() { XCTAssertEqual( "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(detail=\"none\")", - sql(config.detail(.None))) + sql(config.detail(.none))) } func test_fts5_config_all() { @@ -118,7 +118,7 @@ class FTS5Tests: XCTestCase { ) } - func sql(config: FTS5Config) -> String { + func sql(_ config: FTS5Config) -> String { return virtualTable.create(.FTS5(config)) } } diff --git a/SQLiteTests/OperatorsTests.swift b/SQLiteTests/OperatorsTests.swift index 86aa34ed..819cf292 100644 --- a/SQLiteTests/OperatorsTests.swift +++ b/SQLiteTests/OperatorsTests.swift @@ -283,4 +283,4 @@ class OperatorsTests : XCTestCase { AssertSQL("((1 = 1) AND ((1 = 1) OR (1 = 1)))", n == n && (n == n || n == n)) } -} \ No newline at end of file +} diff --git a/SQLiteTests/QueryTests.swift b/SQLiteTests/QueryTests.swift index f584bfcf..df2ff073 100644 --- a/SQLiteTests/QueryTests.swift +++ b/SQLiteTests/QueryTests.swift @@ -298,10 +298,10 @@ class QueryIntegrationTests : SQLiteTestCase { let managers = users.alias("managers") let alice = try! db.run(users.insert(email <- "alice@example.com")) - try! db.run(users.insert(email <- "betsy@example.com", managerId <- alice)) + _ = try! db.run(users.insert(email <- "betsy@example.com", managerId <- alice)) for user in try! db.prepare(users.join(managers, on: managers[id] == users[managerId])) { - user[users[managerId]] + _ = user[users[managerId]] } } diff --git a/SQLiteTests/SchemaTests.swift b/SQLiteTests/SchemaTests.swift index 416b3646..01bedda0 100644 --- a/SQLiteTests/SchemaTests.swift +++ b/SQLiteTests/SchemaTests.swift @@ -283,15 +283,15 @@ class SchemaTests : XCTestCase { func test_column_withIntegerExpression_compilesPrimaryKeyAutoincrementColumnDefinitionExpression() { XCTAssertEqual( "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - table.create { t in t.column(int64, primaryKey: .Autoincrement) } + table.create { t in t.column(int64, primaryKey: .autoincrement) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK (\"int64\" > 0))", - table.create { t in t.column(int64, primaryKey: .Autoincrement, check: int64 > 0) } + table.create { t in t.column(int64, primaryKey: .autoincrement, check: int64 > 0) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK (\"int64Optional\" > 0))", - table.create { t in t.column(int64, primaryKey: .Autoincrement, check: int64Optional > 0) } + table.create { t in t.column(int64, primaryKey: .autoincrement, check: int64Optional > 0) } ) } @@ -354,172 +354,172 @@ class SchemaTests : XCTestCase { func test_column_withStringExpression_compilesCollatedColumnDefinitionExpression() { XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL COLLATE RTRIM)", - table.create { t in t.column(string, collate: .Rtrim) } + table.create { t in t.column(string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, collate: .Rtrim) } + table.create { t in t.column(string, unique: true, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"string\" != '') COLLATE RTRIM)", - table.create { t in t.column(string, check: string != "", collate: .Rtrim) } + table.create { t in t.column(string, check: string != "", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"stringOptional\" != '') COLLATE RTRIM)", - table.create { t in t.column(string, check: stringOptional != "", collate: .Rtrim) } + table.create { t in t.column(string, check: stringOptional != "", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(string, defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(string, defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(string, defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(string, defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, check: string != "", collate: .Rtrim) } + table.create { t in t.column(string, unique: true, check: string != "", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, check: stringOptional != "", collate: .Rtrim) } + table.create { t in t.column(string, unique: true, check: stringOptional != "", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(string, unique: true, defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(string, unique: true, defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, check: string != "", defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(string, unique: true, check: string != "", defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, check: stringOptional != "", defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(string, unique: true, check: stringOptional != "", defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, check: string != "", defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(string, unique: true, check: string != "", defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(string, unique: true, check: stringOptional != "", defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(string, unique: true, check: stringOptional != "", defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(string, check: string != "", defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(string, check: string != "", defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(string, check: stringOptional != "", defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(string, check: stringOptional != "", defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(string, check: string != "", defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(string, check: string != "", defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(string, check: stringOptional != "", defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(string, check: stringOptional != "", defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL COLLATE RTRIM)", - table.create { t in t.column(stringOptional, collate: .Rtrim) } + table.create { t in t.column(stringOptional, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"string\" != '') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, check: string != "", collate: .Rtrim) } + table.create { t in t.column(stringOptional, check: string != "", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"stringOptional\" != '') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, check: stringOptional != "", collate: .Rtrim) } + table.create { t in t.column(stringOptional, check: stringOptional != "", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(stringOptional, defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL DEFAULT (\"stringOptional\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, defaultValue: stringOptional, collate: .Rtrim) } + table.create { t in t.column(stringOptional, defaultValue: stringOptional, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(stringOptional, defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, check: string != "", collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, check: string != "", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE DEFAULT (\"stringOptional\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, defaultValue: stringOptional, collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, defaultValue: stringOptional, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT (\"stringOptional\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: stringOptional, collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: stringOptional, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT (\"stringOptional\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: stringOptional, collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: stringOptional, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, check: string != "", defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(stringOptional, check: string != "", defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT (\"string\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: string, collate: .Rtrim) } + table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: string, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT (\"stringOptional\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, check: string != "", defaultValue: stringOptional, collate: .Rtrim) } + table.create { t in t.column(stringOptional, check: string != "", defaultValue: stringOptional, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT (\"stringOptional\") COLLATE RTRIM)", - table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: stringOptional, collate: .Rtrim) } + table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: stringOptional, collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, check: string != "", defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(stringOptional, check: string != "", defaultValue: "string", collate: .rtrim) } ) XCTAssertEqual( "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM)", - table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: "string", collate: .Rtrim) } + table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: "string", collate: .rtrim) } ) } @@ -676,36 +676,36 @@ class SchemaTests : XCTestCase { func test_addColumn_withStringExpression_compilesCollatedAlterTableExpression() { XCTAssertEqual( "ALTER TABLE \"table\" ADD COLUMN \"string\" TEXT NOT NULL DEFAULT ('string') COLLATE RTRIM", - table.addColumn(string, defaultValue: "string", collate: .Rtrim) + table.addColumn(string, defaultValue: "string", collate: .rtrim) ) XCTAssertEqual( "ALTER TABLE \"table\" ADD COLUMN \"string\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM", - table.addColumn(string, check: string != "", defaultValue: "string", collate: .Rtrim) + table.addColumn(string, check: string != "", defaultValue: "string", collate: .rtrim) ) XCTAssertEqual( "ALTER TABLE \"table\" ADD COLUMN \"string\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM", - table.addColumn(string, check: stringOptional != "", defaultValue: "string", collate: .Rtrim) + table.addColumn(string, check: stringOptional != "", defaultValue: "string", collate: .rtrim) ) XCTAssertEqual( "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT COLLATE RTRIM", - table.addColumn(stringOptional, collate: .Rtrim) + table.addColumn(stringOptional, collate: .rtrim) ) XCTAssertEqual( "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT CHECK (\"string\" != '') COLLATE RTRIM", - table.addColumn(stringOptional, check: string != "", collate: .Rtrim) + table.addColumn(stringOptional, check: string != "", collate: .rtrim) ) XCTAssertEqual( "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT CHECK (\"stringOptional\" != '') COLLATE RTRIM", - table.addColumn(stringOptional, check: stringOptional != "", collate: .Rtrim) + table.addColumn(stringOptional, check: stringOptional != "", collate: .rtrim) ) XCTAssertEqual( "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM", - table.addColumn(stringOptional, check: string != "", defaultValue: "string", collate: .Rtrim) + table.addColumn(stringOptional, check: string != "", defaultValue: "string", collate: .rtrim) ) XCTAssertEqual( "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM", - table.addColumn(stringOptional, check: stringOptional != "", defaultValue: "string", collate: .Rtrim) + table.addColumn(stringOptional, check: stringOptional != "", defaultValue: "string", collate: .rtrim) ) } diff --git a/SQLiteTests/TestHelpers.swift b/SQLiteTests/TestHelpers.swift index 464b9c27..7b7715b1 100644 --- a/SQLiteTests/TestHelpers.swift +++ b/SQLiteTests/TestHelpers.swift @@ -32,22 +32,22 @@ class SQLiteTestCase : XCTestCase { ) } - func InsertUsers(names: String...) throws { + func InsertUsers(_ names: String...) throws { try InsertUsers(names) } - func InsertUsers(names: [String]) throws { - for name in names { try InsertUser(name) } + func InsertUsers(_ names: [String]) throws { + for name in names { _ = try InsertUser(name) } } - func InsertUser(name: String, age: Int? = nil, admin: Bool = false) throws -> Statement { + func InsertUser(_ name: String, age: Int? = nil, admin: Bool = false) throws -> Statement { return try db.run( "INSERT INTO \"users\" (email, age, admin) values (?, ?, ?)", "\(name)@example.com", age?.datatypeValue, admin.datatypeValue ) } - func AssertSQL(SQL: String, _ executions: Int = 1, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) { + func AssertSQL(_ SQL: String, _ executions: Int = 1, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) { XCTAssertEqual( executions, trace[SQL] ?? 0, message ?? SQL, @@ -55,8 +55,8 @@ class SQLiteTestCase : XCTestCase { ) } - func AssertSQL(SQL: String, _ statement: Statement, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) { - try! statement.run() + func AssertSQL(_ SQL: String, _ statement: Statement, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) { + _ = try! statement.run() AssertSQL(SQL, 1, message, file: file, line: line) if let count = trace[SQL] { trace[SQL] = count - 1 } } @@ -67,10 +67,10 @@ class SQLiteTestCase : XCTestCase { // if let count = trace[SQL] { trace[SQL] = count - 1 } // } - func async(expect description: String = "async", timeout: Double = 5, @noescape block: (() -> Void) -> Void) { - let expectation = expectationWithDescription(description) + func async(expect description: String = "async", timeout: Double = 5, block: (@escaping () -> Void) -> Void) { + let expectation = self.expectation(description: description) block(expectation.fulfill) - waitForExpectationsWithTimeout(timeout, handler: nil) + waitForExpectations(timeout: timeout, handler: nil) } } @@ -81,8 +81,8 @@ let boolOptional = Expression("boolOptional") let data = Expression("blob") let dataOptional = Expression("blobOptional") -let date = Expression("date") -let dateOptional = Expression("dateOptional") +let date = Expression("date") +let dateOptional = Expression("dateOptional") let double = Expression("double") let doubleOptional = Expression("doubleOptional") @@ -96,13 +96,13 @@ let int64Optional = Expression("int64Optional") let string = Expression("string") let stringOptional = Expression("stringOptional") -func AssertSQL(@autoclosure expression1: () -> String, @autoclosure _ expression2: () -> Expressible, file: StaticString = #file, line: UInt = #line) { +func AssertSQL(_ expression1: @autoclosure () -> String, _ expression2: @autoclosure () -> Expressible, file: StaticString = #file, line: UInt = #line) { XCTAssertEqual(expression1(), expression2().asSQL(), file: file, line: line) } -func AssertThrows(@autoclosure expression: () throws -> T, file: StaticString = #file, line: UInt = #line) { +func AssertThrows(_ expression: @autoclosure () throws -> T, file: StaticString = #file, line: UInt = #line) { do { - try expression() + _ = try expression() XCTFail("expression expected to throw", file: file, line: line) } catch { XCTAssert(true, file: file, line: line) From 78c7f6ae01fc06d86b24f9a595c03eb85d0bde8f Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Fri, 16 Sep 2016 18:47:54 +0800 Subject: [PATCH 14/36] all tests passed --- SQLite.xcodeproj/project.pbxproj | 4 ++++ SQLite/Extensions/FTS4.swift | 2 +- SQLiteTests/FTS4Tests.swift | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index 2f13a35f..aa951fd8 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -1007,6 +1007,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; + SWIFT_VERSION = 3.0; TVOS_DEPLOYMENT_TARGET = 9.1; }; name = Debug; @@ -1019,6 +1020,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; + SWIFT_VERSION = 3.0; TVOS_DEPLOYMENT_TARGET = 9.1; }; name = Release; @@ -1040,6 +1042,7 @@ PRODUCT_NAME = SQLite; SDKROOT = watchos; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.2; }; @@ -1062,6 +1065,7 @@ PRODUCT_NAME = SQLite; SDKROOT = watchos; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.2; }; diff --git a/SQLite/Extensions/FTS4.swift b/SQLite/Extensions/FTS4.swift index 52de47bf..bd8c7b2d 100644 --- a/SQLite/Extensions/FTS4.swift +++ b/SQLite/Extensions/FTS4.swift @@ -148,7 +148,7 @@ extension Connection { let view = string.utf8 offset.pointee += string.substring(to: range.lowerBound).utf8.count - length.pointee = Int32(view.distance(from: range.lowerBound.samePosition(in: view), to: range.lowerBound.samePosition(in: view))) + length.pointee = Int32(view.distance(from: range.lowerBound.samePosition(in: view), to: range.upperBound.samePosition(in: view))) return token }) } diff --git a/SQLiteTests/FTS4Tests.swift b/SQLiteTests/FTS4Tests.swift index 37a773a6..92f197a2 100644 --- a/SQLiteTests/FTS4Tests.swift +++ b/SQLiteTests/FTS4Tests.swift @@ -187,15 +187,15 @@ class FTS4IntegrationTests : SQLiteTestCase { let tokenizer = CFStringTokenizerCreate(nil, "" as CFString!, CFRangeMake(0, 0), UInt(kCFStringTokenizerUnitWord), locale) try! db.registerTokenizer(tokenizerName) { string in CFStringTokenizerSetString(tokenizer, string as CFString, CFRangeMake(0, CFStringGetLength(string as CFString))) - if CFStringTokenizerAdvanceToNextToken(tokenizer) == .none { + if CFStringTokenizerAdvanceToNextToken(tokenizer).isEmpty { return nil } let range = CFStringTokenizerGetCurrentTokenRange(tokenizer) - let input = CFStringCreateWithSubstring(kCFAllocatorDefault, string as CFString, range) - let token = CFStringCreateMutableCopy(nil, range.length, input) + let input = CFStringCreateWithSubstring(kCFAllocatorDefault, string as CFString, range)! + let token = CFStringCreateMutableCopy(nil, range.length, input)! CFStringLowercase(token, locale) CFStringTransform(token, nil, kCFStringTransformStripDiacritics, false) - return ((token as String?)!, string.range(of: (input as String?)!)!) + return (token as String, string.range(of: input as String)!) } _ = try! db.run(emails.create(.FTS4([subject, body], tokenize: .Custom(tokenizerName)))) From aaa07c70e1952ce6aadccc0b79e7e0a1ce05d2ba Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Sat, 17 Sep 2016 09:37:27 +0800 Subject: [PATCH 15/36] added .swift-version for pods --- .swift-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.swift-version b/.swift-version index bb576dbd..9f55b2cc 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -2.3 +3.0 From e9abf032f461bf2a6d84751d13e37998a94a2dfa Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 17 Sep 2016 17:32:30 +0100 Subject: [PATCH 16/36] Remove Xcode 7.3 tests --- .travis.yml | 31 ++++--------------------------- Makefile | 2 +- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/.travis.yml b/.travis.yml index d855fb3c..ada13822 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,34 +3,11 @@ rvm: 2.2 osx_image: xcode8 matrix: include: - - env: - - BUILD_SCHEME="SQLite iOS" - - IOS_SIMULATOR="iPhone SE" + - env: BUILD_SCHEME="SQLite iOS" - env: BUILD_SCHEME="SQLite Mac" - - env: - - VALIDATOR_SUBSPEC="none" - - IOS_SIMULATOR="iPhone SE" - - env: - - VALIDATOR_SUBSPEC="standard" - - IOS_SIMULATOR="iPhone SE" - - env: - - VALIDATOR_SUBSPEC="standalone" - - IOS_SIMULATOR="iPhone SE" - - os: osx - osx_image: xcode7.3 - env: BUILD_SCHEME="SQLite iOS" - - os: osx - osx_image: xcode7.3 - env: BUILD_SCHEME="SQLite Mac" - - os: osx - osx_image: xcode7.3 - env: VALIDATOR_SUBSPEC="none" - - os: osx - osx_image: xcode7.3 - env: VALIDATOR_SUBSPEC="standard" - - os: osx - osx_image: xcode7.3 - env: VALIDATOR_SUBSPEC="standalone" + - env: VALIDATOR_SUBSPEC="none" + - env: VALIDATOR_SUBSPEC="standard" + - env: VALIDATOR_SUBSPEC="standalone" before_install: - gem install xcpretty --no-document script: diff --git a/Makefile b/Makefile index 35edf493..2f085b6c 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ BUILD_TOOL = xcodebuild BUILD_SCHEME = SQLite Mac -IOS_SIMULATOR = iPhone 6 +IOS_SIMULATOR = iPhone SE ifeq ($(BUILD_SCHEME),SQLite iOS) BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" -destination "platform=iOS Simulator,name=$(IOS_SIMULATOR)" else From f8209be2fad7c88e41210e742a57a80338ff8a17 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 17 Sep 2016 17:37:07 +0100 Subject: [PATCH 17/36] Set swift version in podspec --- SQLite.swift.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 89cffff1..b7a09bc1 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -26,7 +26,7 @@ Pod::Spec.new do |s| s.watchos.deployment_target = "2.0" s.default_subspec = 'standard' s.pod_target_xcconfig = { - 'SWIFT_VERSION' => '2.3', + 'SWIFT_VERSION' => '3.0', } s.subspec 'standard' do |ss| From 33f712dc30571fd631175675a8aecf604f612eaa Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 17 Sep 2016 17:57:51 +0100 Subject: [PATCH 18/36] Set iOS simulator --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index ada13822..d280766b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: objective-c rvm: 2.2 osx_image: xcode8 +env: + global: + - IOS_SIMULATOR="iPhone SE" matrix: include: - env: BUILD_SCHEME="SQLite iOS" From 183726692204ba437541ea378ad90c99644472db Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 Sep 2016 10:48:58 +0100 Subject: [PATCH 19/36] Swift3 enum casing --- Documentation/Index.md | 34 +++++++++++++++---------------- SQLite/Core/Connection.swift | 8 ++++---- SQLite/Typed/Query.swift | 20 +++++++++--------- SQLite/Typed/Schema.swift | 12 +++++------ SQLiteTests/ConnectionTests.swift | 6 +++--- SQLiteTests/QueryTests.swift | 10 ++++----- SQLiteTests/SchemaTests.swift | 2 +- 7 files changed, 46 insertions(+), 46 deletions(-) diff --git a/Documentation/Index.md b/Documentation/Index.md index 0579e6f3..3063d095 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -192,7 +192,7 @@ On iOS, you can create a writable database in your app’s **Documents** directo ``` swift let path = NSSearchPathForDirectoriesInDomains( - .DocumentDirectory, .UserDomainMask, true + .documentDirectory, .userDomainMask, true ).first! let db = try Connection("\(path)/db.sqlite3") @@ -202,7 +202,7 @@ On OS X, you can use your app’s **Application Support** directory: ``` swift var path = NSSearchPathForDirectoriesInDomains( - .ApplicationSupportDirectory, .UserDomainMask, true + .applicationSupportDirectory, .userDomainMask, true ).first! + NSBundle.mainBundle().bundleIdentifier! // create parent directory iff it doesn’t exist @@ -225,7 +225,7 @@ let db = try Connection(path, readonly: true) ``` > _Note:_ Signed applications cannot modify their bundle resources. If you bundle a database file with your app for the purpose of bootstrapping, copy it to a writable location _before_ establishing a connection (see [Read-Write Databases](#read-write-databases), above, for typical, writable locations). -> +> > See these two Stack Overflow questions for more information about iOS apps with SQLite databases: [1](https://stackoverflow.com/questions/34609746/what-different-between-store-database-in-different-locations-in-ios), [2](https://stackoverflow.com/questions/34614968/ios-how-to-copy-pre-seeded-database-at-the-first-running-app-with-sqlite-swift). We welcome sample code to show how to successfully copy and use a bundled "seed" database for writing in an app. #### In-Memory Databases @@ -233,13 +233,13 @@ let db = try Connection(path, readonly: true) If you omit the path, SQLite.swift will provision an [in-memory database](https://www.sqlite.org/inmemorydb.html). ``` swift -let db = try Connection() // equivalent to `Connection(.InMemory)` +let db = try Connection() // equivalent to `Connection(.inMemory)` ``` To create a temporary, disk-backed database, pass an empty file name. ``` swift -let db = try Connection(.Temporary) +let db = try Connection(.temporary) ``` In-memory databases are automatically deleted when the database connection is closed. @@ -367,7 +367,7 @@ The `column` function is used for a single column definition. It takes an [expre t.column(id, primaryKey: true) // "id" INTEGER PRIMARY KEY NOT NULL - t.column(id, primaryKey: .Autoincrement) + t.column(id, primaryKey: .autoincrement) // "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ``` @@ -375,7 +375,7 @@ The `column` function is used for a single column definition. It takes an [expre > > Primary keys cannot be optional (_e.g._, `Expression`). > - > Only an `INTEGER PRIMARY KEY` can take `.Autoincrement`. + > Only an `INTEGER PRIMARY KEY` can take `.autoincrement`. - `unique` adds a `UNIQUE` constraint to the column. (See the `unique` function under [Table Constraints](#table-constraints) for uniqueness over multiple columns). @@ -403,10 +403,10 @@ The `column` function is used for a single column definition. It takes an [expre - `collate` adds a `COLLATE` clause to `Expression` (and `Expression`) column definitions with [a collating sequence](https://www.sqlite.org/datatype3.html#collation) defined in the `Collation` enumeration. ``` swift - t.column(email, collate: .Nocase) + t.column(email, collate: .nocase) // "email" TEXT NOT NULL COLLATE "NOCASE" - t.column(name, collate: .Rtrim) + t.column(name, collate: .rtrim) // "name" TEXT COLLATE "RTRIM" ``` @@ -454,7 +454,7 @@ Additional constraints may be provided outside the scope of a single column usin - `foreignKey` adds a `FOREIGN KEY` constraint to the table. Unlike [the `references` constraint, above](#column-constraints), it supports all SQLite types, both [`ON UPDATE` and `ON DELETE` actions](https://www.sqlite.org/foreignkeys.html#fk_actions), and composite (multiple column) keys. ``` swift - t.foreignKey(user_id, references: users, id, delete: .SetNull) + t.foreignKey(user_id, references: users, id, delete: .setNull) // FOREIGN KEY("user_id") REFERENCES "users"("id") ON DELETE SET NULL ``` @@ -471,7 +471,7 @@ We can insert rows into a table by calling a [query’s](#queries) `insert` func try db.run(users.insert(email <- "alice@mac.com", name <- "Alice")) // INSERT INTO "users" ("email", "name") VALUES ('alice@mac.com', 'Alice') -try db.run(users.insert(or: .Replace, email <- "alice@mac.com", name <- "Alice B.")) +try db.run(users.insert(or: .replace, email <- "alice@mac.com", name <- "Alice B.")) // INSERT OR REPLACE INTO "users" ("email", "name") VALUES ('alice@mac.com', 'Alice B.') ``` @@ -637,7 +637,7 @@ users.join(posts, on: user_id == users[id]) // SELECT * FROM "users" INNER JOIN "posts" ON ("user_id" = "users"."id") ``` -The `join` function takes a [query](#queries) object (for the table being joined on), a join condition (`on`), and is prefixed with an optional join type (default: `.Inner`). Join conditions can be built using [filter operators and functions](#filter-operators-and-functions), generally require [namespacing](#column-namespacing), and sometimes require [aliasing](#table-aliasing). +The `join` function takes a [query](#queries) object (for the table being joined on), a join condition (`on`), and is prefixed with an optional join type (default: `.inner`). Join conditions can be built using [filter operators and functions](#filter-operators-and-functions), generally require [namespacing](#column-namespacing), and sometimes require [aliasing](#table-aliasing). ##### Column Namespacing @@ -996,10 +996,10 @@ The `addColumn` function shares several of the same [`column` function parameter - `collate` adds a `COLLATE` clause to `Expression` (and `Expression`) column definitions with [a collating sequence](https://www.sqlite.org/datatype3.html#collation) defined in the `Collation` enumeration. ``` swift - try db.run(users.addColumn(email, collate: .Nocase)) + try db.run(users.addColumn(email, collate: .nocase)) // ALTER TABLE "users" ADD COLUMN "email" TEXT NOT NULL COLLATE "NOCASE" - try db.run(users.addColumn(name, collate: .Rtrim)) + try db.run(users.addColumn(name, collate: .rtrim)) // ALTER TABLE "users" ADD COLUMN "name" TEXT COLLATE "RTRIM" ``` @@ -1367,14 +1367,14 @@ We can create custom collating sequences by calling `createCollation` on a datab ``` swift try db.createCollation("NODIACRITIC") { lhs, rhs in - return lhs.compare(rhs, options: .DiacriticInsensitiveSearch) + return lhs.compare(rhs, options: .diacriticInsensitiveSearch) } ``` We can reference a custom collation using the `Custom` member of the `Collation` enumeration. ``` swift -restaurants.order(collate(.Custom("NODIACRITIC"), name)) +restaurants.order(collate(.custom("NODIACRITIC"), name)) // SELECT * FROM "restaurants" ORDER BY "name" COLLATE "NODIACRITIC" ``` @@ -1409,7 +1409,7 @@ let config = FTS4Config() .column(subject) .column(body, [.unindexed]) .languageId("lid") - .order(.Desc) + .order(.desc) try db.run(emails.create(.FTS4(config)) // CREATE VIRTUAL TABLE "emails" USING fts4("subject", "body", notindexed="body", languageid="lid", order="desc") diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index 832910ba..5acc44d2 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -274,13 +274,13 @@ public final class Connection { public enum TransactionMode : String { /// Defers locking the database till the first read/write executes. - case Deferred = "DEFERRED" + case deferred = "DEFERRED" /// Immediately acquires a reserved lock on the database. - case Immediate = "IMMEDIATE" + case immediate = "IMMEDIATE" /// Immediately acquires an exclusive lock on all databases. - case Exclusive = "EXCLUSIVE" + case exclusive = "EXCLUSIVE" } @@ -301,7 +301,7 @@ public final class Connection { /// must throw to roll the transaction back. /// /// - Throws: `Result.Error`, and rethrows. - public func transaction(_ mode: TransactionMode = .Deferred, block: @escaping () throws -> Void) throws { + public func transaction(_ mode: TransactionMode = .deferred, block: @escaping () throws -> Void) throws { try transaction("BEGIN \(mode.rawValue) TRANSACTION", block, "COMMIT TRANSACTION", or: "ROLLBACK TRANSACTION") } diff --git a/SQLite/Typed/Query.swift b/SQLite/Typed/Query.swift index d0e4572d..0e54392b 100644 --- a/SQLite/Typed/Query.swift +++ b/SQLite/Typed/Query.swift @@ -221,7 +221,7 @@ extension QueryType { /// /// - Returns: A query with the given `JOIN` clause applied. public func join(_ table: QueryType, on condition: Expression) -> Self { - return join(.Inner, table, on: condition) + return join(.inner, table, on: condition) } /// Adds a `JOIN` clause to the query. @@ -401,7 +401,7 @@ extension QueryType { public func order(_ by: Expressible...) -> Self { return order(by) } - + /// Sets an `ORDER BY` clause on the query. /// /// let users = Table("users") @@ -1100,28 +1100,28 @@ public struct Row { public enum JoinType : String { /// A `CROSS` join. - case Cross = "CROSS" + case cross = "CROSS" /// An `INNER` join. - case Inner = "INNER" + case inner = "INNER" /// A `LEFT OUTER` join. - case LeftOuter = "LEFT OUTER" + case leftOuter = "LEFT OUTER" } /// ON CONFLICT resolutions. public enum OnConflict: String { - case Replace = "REPLACE" + case replace = "REPLACE" - case Rollback = "ROLLBACK" + case rollback = "ROLLBACK" - case Abort = "ABORT" + case abort = "ABORT" - case Fail = "FAIL" + case fail = "FAIL" - case Ignore = "IGNORE" + case ignore = "IGNORE" } diff --git a/SQLite/Typed/Schema.swift b/SQLite/Typed/Schema.swift index 4c6862c0..1388170e 100644 --- a/SQLite/Typed/Schema.swift +++ b/SQLite/Typed/Schema.swift @@ -369,16 +369,16 @@ public final class TableBuilder { public enum Dependency: String { - case NoAction = "NO ACTION" + case noAction = "NO ACTION" - case Restrict = "RESTRICT" + case restrict = "RESTRICT" - case SetNull = "SET NULL" + case setNull = "SET NULL" - case SetDefault = "SET DEFAULT" + case setDefault = "SET DEFAULT" + + case cascade = "CASCADE" - case Cascade = "CASCADE" - } public func foreignKey(_ column: Expression, references table: QueryType, _ other: Expression, update: Dependency? = nil, delete: Dependency? = nil) { diff --git a/SQLiteTests/ConnectionTests.swift b/SQLiteTests/ConnectionTests.swift index 0e8ebea6..c217eac7 100644 --- a/SQLiteTests/ConnectionTests.swift +++ b/SQLiteTests/ConnectionTests.swift @@ -95,19 +95,19 @@ class ConnectionTests : SQLiteTestCase { } func test_transaction_executesBeginDeferred() { - try! db.transaction(.Deferred) {} + try! db.transaction(.deferred) {} AssertSQL("BEGIN DEFERRED TRANSACTION") } func test_transaction_executesBeginImmediate() { - try! db.transaction(.Immediate) {} + try! db.transaction(.immediate) {} AssertSQL("BEGIN IMMEDIATE TRANSACTION") } func test_transaction_executesBeginExclusive() { - try! db.transaction(.Exclusive) {} + try! db.transaction(.exclusive) {} AssertSQL("BEGIN EXCLUSIVE TRANSACTION") } diff --git a/SQLiteTests/QueryTests.swift b/SQLiteTests/QueryTests.swift index df2ff073..ed34921e 100644 --- a/SQLiteTests/QueryTests.swift +++ b/SQLiteTests/QueryTests.swift @@ -20,11 +20,11 @@ class QueryTests : XCTestCase { func test_select_withExpression_compilesSelectClause() { AssertSQL("SELECT \"email\" FROM \"users\"", users.select(email)) } - + func test_select_withStarExpression_compilesSelectClause() { AssertSQL("SELECT * FROM \"users\"", users.select(*)) } - + func test_select_withNamespacedStarExpression_compilesSelectClause() { AssertSQL("SELECT \"users\".* FROM \"users\"", users.select(users[*])) } @@ -59,12 +59,12 @@ class QueryTests : XCTestCase { func test_join_withExplicitType_compilesJoinClauseWithType() { AssertSQL( "SELECT * FROM \"users\" LEFT OUTER JOIN \"posts\" ON (\"posts\".\"user_id\" = \"users\".\"id\")", - users.join(.LeftOuter, posts, on: posts[userId] == users[id]) + users.join(.leftOuter, posts, on: posts[userId] == users[id]) ) AssertSQL( "SELECT * FROM \"users\" CROSS JOIN \"posts\" ON (\"posts\".\"user_id\" = \"users\".\"id\")", - users.join(.Cross, posts, on: posts[userId] == users[id]) + users.join(.cross, posts, on: posts[userId] == users[id]) ) } @@ -192,7 +192,7 @@ class QueryTests : XCTestCase { func test_insert_withOnConflict_compilesInsertOrOnConflictExpression() { AssertSQL( "INSERT OR REPLACE INTO \"users\" (\"email\", \"age\") VALUES ('alice@example.com', 30)", - users.insert(or: .Replace, email <- "alice@example.com", age <- 30) + users.insert(or: .replace, email <- "alice@example.com", age <- 30) ) } diff --git a/SQLiteTests/SchemaTests.swift b/SQLiteTests/SchemaTests.swift index 01bedda0..371459c7 100644 --- a/SQLiteTests/SchemaTests.swift +++ b/SQLiteTests/SchemaTests.swift @@ -568,7 +568,7 @@ class SchemaTests : XCTestCase { XCTAssertEqual( "CREATE TABLE \"table\" (FOREIGN KEY (\"string\") REFERENCES \"table\" (\"string\") ON UPDATE CASCADE ON DELETE SET NULL)", - table.create { t in t.foreignKey(string, references: table, string, update: .Cascade, delete: .SetNull) } + table.create { t in t.foreignKey(string, references: table, string, update: .cascade, delete: .setNull) } ) XCTAssertEqual( From 4ed14adaefa1ed308ff949ae5e2cff0dc2b8d4b2 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 Sep 2016 11:59:50 +0100 Subject: [PATCH 20/36] Nest Operation inside Connection --- SQLite/Core/Connection.swift | 53 +++++++++++++++---------------- SQLiteTests/ConnectionTests.swift | 6 ++-- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index 5acc44d2..2a7ba3b0 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -54,6 +54,32 @@ public final class Connection { case uri(String) } + /// An SQL operation passed to update callbacks. + public enum Operation { + + /// An INSERT operation. + case insert + + /// An UPDATE operation. + case update + + /// A DELETE operation. + case delete + + fileprivate init(rawValue:Int32) { + switch rawValue { + case SQLITE_INSERT: + self = .insert + case SQLITE_UPDATE: + self = .update + case SQLITE_DELETE: + self = .delete + default: + fatalError("unhandled operation code: \(rawValue)") + } + } + } + public var handle: OpaquePointer { return _handle! } fileprivate var _handle: OpaquePointer? = nil @@ -638,33 +664,6 @@ extension Connection.Location : CustomStringConvertible { } -/// An SQL operation passed to update callbacks. -public enum Operation { - - /// An INSERT operation. - case insert - - /// An UPDATE operation. - case update - - /// A DELETE operation. - case delete - - fileprivate init(rawValue: Int32) { - switch rawValue { - case SQLITE_INSERT: - self = .insert - case SQLITE_UPDATE: - self = .update - case SQLITE_DELETE: - self = .delete - default: - fatalError("unhandled operation code: \(rawValue)") - } - } - -} - public enum Result : Error { fileprivate static let successCodes: Set = [SQLITE_OK, SQLITE_ROW, SQLITE_DONE] diff --git a/SQLiteTests/ConnectionTests.swift b/SQLiteTests/ConnectionTests.swift index c217eac7..4db671ad 100644 --- a/SQLiteTests/ConnectionTests.swift +++ b/SQLiteTests/ConnectionTests.swift @@ -192,7 +192,7 @@ class ConnectionTests : SQLiteTestCase { func test_updateHook_setsUpdateHook_withInsert() { async { done in db.updateHook { operation, db, table, rowid in - XCTAssertEqual(Operation.insert, operation) + XCTAssertEqual(Connection.Operation.insert, operation) XCTAssertEqual("main", db) XCTAssertEqual("users", table) XCTAssertEqual(1, rowid) @@ -206,7 +206,7 @@ class ConnectionTests : SQLiteTestCase { _ = try! InsertUser("alice") async { done in db.updateHook { operation, db, table, rowid in - XCTAssertEqual(Operation.update, operation) + XCTAssertEqual(Connection.Operation.update, operation) XCTAssertEqual("main", db) XCTAssertEqual("users", table) XCTAssertEqual(1, rowid) @@ -220,7 +220,7 @@ class ConnectionTests : SQLiteTestCase { _ = try! InsertUser("alice") async { done in db.updateHook { operation, db, table, rowid in - XCTAssertEqual(Operation.delete, operation) + XCTAssertEqual(Connection.Operation.delete, operation) XCTAssertEqual("main", db) XCTAssertEqual("users", table) XCTAssertEqual(1, rowid) From 2c9fd0c1417bec5878226c045ae7ac86b7644bc0 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 6 Oct 2016 22:22:29 +0200 Subject: [PATCH 21/36] Flag methods executed for side-effects to silence warnings --- SQLite/Core/Connection.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index 2a7ba3b0..04b515c3 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -216,7 +216,7 @@ public final class Connection { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement. - public func run(_ statement: String, _ bindings: Binding?...) throws -> Statement { + @discardableResult public func run(_ statement: String, _ bindings: Binding?...) throws -> Statement { return try run(statement, bindings) } @@ -231,7 +231,7 @@ public final class Connection { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement. - public func run(_ statement: String, _ bindings: [Binding?]) throws -> Statement { + @discardableResult public func run(_ statement: String, _ bindings: [Binding?]) throws -> Statement { return try prepare(statement).run(bindings) } @@ -246,7 +246,7 @@ public final class Connection { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement. - public func run(_ statement: String, _ bindings: [String: Binding?]) throws -> Statement { + @discardableResult public func run(_ statement: String, _ bindings: [String: Binding?]) throws -> Statement { return try prepare(statement).run(bindings) } From 8f8eec7b4c81b7547ee90bb2e51a235c9b02e222 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 7 Oct 2016 12:48:29 +0200 Subject: [PATCH 22/36] Add tests for Blob initializer --- SQLiteTests/BlobTests.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/SQLiteTests/BlobTests.swift b/SQLiteTests/BlobTests.swift index ba0a7c54..fbcca9bc 100644 --- a/SQLiteTests/BlobTests.swift +++ b/SQLiteTests/BlobTests.swift @@ -9,4 +9,15 @@ class BlobTests : XCTestCase { XCTAssertEqual(blob.toHex(), "000a141e28323c46505a6496faff") } + func test_init_array() { + let blob = Blob(bytes: [42, 42, 42]) + XCTAssertEqual(blob.bytes, [42, 42, 42]) + } + + func test_init_unsafeRawPointer() { + let pointer = UnsafeMutablePointer.allocate(capacity: 3) + pointer.initialize(to: 42, count: 3) + let blob = Blob(bytes: pointer, length: 3) + XCTAssertEqual(blob.bytes, [42, 42, 42]) + } } From b6941cda744c6cb163180eb5c8dead1fa76d6c77 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 7 Oct 2016 15:03:53 +0200 Subject: [PATCH 23/36] Add more tests for blob handling --- SQLite.xcodeproj/project.pbxproj | 8 ++++++++ SQLite/Core/Blob.swift | 1 - SQLite/Core/Statement.swift | 9 ++++++--- SQLite/Foundation.swift | 6 +++--- SQLiteTests/FoundationTests.swift | 16 ++++++++++++++++ SQLiteTests/StatementTests.swift | 14 +++++++++++++- 6 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 SQLiteTests/FoundationTests.swift diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index aa951fd8..4dddeaaf 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -51,7 +51,10 @@ 19A17254FBA7894891F7297B /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; }; 19A174D78559CD30679BCCCB /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; }; 19A1750CEE9B05267995CF3D /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; }; + 19A178072B371489E6A1E839 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; }; + 19A17E04C4C0956715C5676A /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; }; 19A17EC0D68BA8C03288ADF7 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; }; + 19A17FB80B94E882050AA908 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; }; EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; }; EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; @@ -162,6 +165,7 @@ 03A65E961C6BB3210062603F /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; }; 19A1721B8984686B9963B45D /* FTS5Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5Tests.swift; sourceTree = ""; }; 19A1730E4390C775C25677D1 /* FTS5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5.swift; sourceTree = ""; }; + 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationTests.swift; sourceTree = ""; }; 39548A631CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; 39548A651CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; 39548A671CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; @@ -415,6 +419,7 @@ EE247B161C3F127200AE3E12 /* TestHelpers.swift */, EE247AE41C3F04ED00AE3E12 /* Info.plist */, 19A1721B8984686B9963B45D /* FTS5Tests.swift */, + 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */, ); path = SQLiteTests; sourceTree = ""; @@ -824,6 +829,7 @@ 03A65E8E1C6BB3030062603F /* OperatorsTests.swift in Sources */, 03A65E951C6BB3030062603F /* TestHelpers.swift in Sources */, 19A17254FBA7894891F7297B /* FTS5Tests.swift in Sources */, + 19A17E04C4C0956715C5676A /* FoundationTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -880,6 +886,7 @@ EE247B2E1C3F141E00AE3E12 /* OperatorsTests.swift in Sources */, EE247B251C3F137700AE3E12 /* ConnectionTests.swift in Sources */, 19A171E6FA242F72A308C594 /* FTS5Tests.swift in Sources */, + 19A17FB80B94E882050AA908 /* FoundationTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -929,6 +936,7 @@ EE247B5E1C3F3FC700AE3E12 /* SetterTests.swift in Sources */, EE247B5B1C3F3FC700AE3E12 /* QueryTests.swift in Sources */, 19A174D78559CD30679BCCCB /* FTS5Tests.swift in Sources */, + 19A178072B371489E6A1E839 /* FoundationTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SQLite/Core/Blob.swift b/SQLite/Core/Blob.swift index 45d6604a..2f5d2a14 100644 --- a/SQLite/Core/Blob.swift +++ b/SQLite/Core/Blob.swift @@ -31,7 +31,6 @@ public struct Blob { } public init(bytes: UnsafeRawPointer, length: Int) { - // TODO correct count let i8bufptr = UnsafeBufferPointer(start: bytes.assumingMemoryBound(to: UInt8.self), count: length) self.init(bytes: [UInt8](i8bufptr)) } diff --git a/SQLite/Core/Statement.swift b/SQLite/Core/Statement.swift index 01720433..f0c05bb8 100644 --- a/SQLite/Core/Statement.swift +++ b/SQLite/Core/Statement.swift @@ -238,9 +238,12 @@ public struct Cursor { } public subscript(idx: Int) -> Blob { - let bytes = sqlite3_column_blob(handle, Int32(idx)) - let length = Int(sqlite3_column_bytes(handle, Int32(idx))) - return Blob(bytes: bytes!, length: length) + if let pointer = sqlite3_column_blob(handle, Int32(idx)) { + let length = Int(sqlite3_column_bytes(handle, Int32(idx))) + return Blob(bytes: pointer, length: length) + } else { + fatalError("sqlite3_column_blob returned NULL") + } } // MARK: - diff --git a/SQLite/Foundation.swift b/SQLite/Foundation.swift index 5c266a05..5e102297 100644 --- a/SQLite/Foundation.swift +++ b/SQLite/Foundation.swift @@ -31,12 +31,12 @@ extension Data : Value { } public static func fromDatatypeValue(_ dataValue: Blob) -> Data { - return Data(bytes: UnsafePointer(dataValue.bytes), count: dataValue.bytes.count) + return Data(bytes: dataValue.bytes) } public var datatypeValue: Blob { - return withUnsafeBytes { ptr -> Blob in - return Blob(bytes: ptr, length: count) + return withUnsafeBytes { (pointer: UnsafePointer) -> Blob in + return Blob(bytes: pointer, length: count) } } diff --git a/SQLiteTests/FoundationTests.swift b/SQLiteTests/FoundationTests.swift new file mode 100644 index 00000000..0df746d9 --- /dev/null +++ b/SQLiteTests/FoundationTests.swift @@ -0,0 +1,16 @@ +import XCTest +import SQLite + +class FoundationTests : XCTestCase { + func testDataFromBlob() { + let data = Data(bytes: [1, 2, 3]) + let blob = data.datatypeValue + XCTAssertEqual([1, 2, 3], blob.bytes) + } + + func testBlobToData() { + let blob = Blob(bytes: [1, 2, 3]) + let data = Data.fromDatatypeValue(blob) + XCTAssertEqual(Data(bytes: [1, 2, 3]), data) + } +} diff --git a/SQLiteTests/StatementTests.swift b/SQLiteTests/StatementTests.swift index 5965929c..fce3585c 100644 --- a/SQLiteTests/StatementTests.swift +++ b/SQLiteTests/StatementTests.swift @@ -1,5 +1,17 @@ import XCTest import SQLite -class StatementTests : XCTestCase { +class StatementTests : SQLiteTestCase { + override func setUp() { + super.setUp() + CreateUsersTable() + } + + func test_cursor_to_blob() { + try! InsertUsers("alice") + let statement = try! db.prepare("SELECT email FROM users") + XCTAssert(try! statement.step()) + let blob = statement.row[0] as Blob + XCTAssertEqual("alice@example.com", String(bytes: blob.bytes, encoding: .utf8)!) + } } From f7d017d858a6e0dc5b5bbc81974d3caca04b619c Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 8 Oct 2016 13:44:47 +0200 Subject: [PATCH 24/36] use @discardableResult --- SQLite/Core/Connection.swift | 12 +++---- SQLite/Core/Statement.swift | 8 ++--- SQLite/Extensions/FTS4.swift | 28 +++++++-------- SQLite/Extensions/FTS5.swift | 6 ++-- SQLite/Typed/Query.swift | 6 ++-- SQLiteTests/ConnectionTests.swift | 58 +++++++++++++++---------------- SQLiteTests/FTS4Tests.swift | 4 +-- SQLiteTests/TestHelpers.swift | 6 ++-- 8 files changed, 64 insertions(+), 64 deletions(-) diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index 04b515c3..bd4cafb3 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -100,7 +100,7 @@ public final class Connection { /// - Returns: A new database connection. public init(_ location: Location = .inMemory, readonly: Bool = false) throws { let flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE - _ = try check(sqlite3_open_v2(location.description, &_handle, flags | SQLITE_OPEN_FULLMUTEX, nil)) + try check(sqlite3_open_v2(location.description, &_handle, flags | SQLITE_OPEN_FULLMUTEX, nil)) queue.setSpecific(key: /*Migrator FIXME: Use a variable of type DispatchSpecificKey*/ Connection.queueKey, value: queueContext) } @@ -356,14 +356,14 @@ public final class Connection { fileprivate func transaction(_ begin: String, _ block: @escaping () throws -> Void, _ commit: String, or rollback: String) throws { return try sync { - _ = try self.run(begin) + try self.run(begin) do { try block() } catch { - _ = try self.run(rollback) + try self.run(rollback) throw error } - _ = try self.run(commit) + try self.run(commit) } } @@ -590,7 +590,7 @@ public final class Connection { let rstr = String(cString: rhs.bindMemory(to: UInt8.self, capacity: 0)) return Int32(Int(block(lstr, rstr).rawValue)) } - _ = try check(sqlite3_create_collation_v2(handle, collation, SQLITE_UTF8, unsafeBitCast(box, to: UnsafeMutableRawPointer.self), { callback, _, lhs, _, rhs in + try check(sqlite3_create_collation_v2(handle, collation, SQLITE_UTF8, unsafeBitCast(box, to: UnsafeMutableRawPointer.self), { callback, _, lhs, _, rhs in unsafeBitCast(callback, to: Collation.self)(lhs!, rhs!) }, nil)) collations[collation] = box @@ -625,7 +625,7 @@ public final class Connection { return success! } - func check(_ resultCode: Int32, statement: Statement? = nil) throws -> Int32 { + @discardableResult func check(_ resultCode: Int32, statement: Statement? = nil) throws -> Int32 { guard let error = Result(errorCode: resultCode, connection: self, statement: statement) else { return resultCode } diff --git a/SQLite/Core/Statement.swift b/SQLite/Core/Statement.swift index f0c05bb8..a7664993 100644 --- a/SQLite/Core/Statement.swift +++ b/SQLite/Core/Statement.swift @@ -37,7 +37,7 @@ public final class Statement { init(_ connection: Connection, _ SQL: String) throws { self.connection = connection - _ = try connection.check(sqlite3_prepare_v2(connection.handle, SQL, -1, &handle, nil)) + try connection.check(sqlite3_prepare_v2(connection.handle, SQL, -1, &handle, nil)) } deinit { @@ -120,7 +120,7 @@ public final class Statement { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement object (useful for chaining). - public func run(_ bindings: Binding?...) throws -> Statement { + @discardableResult public func run(_ bindings: Binding?...) throws -> Statement { guard bindings.isEmpty else { return try run(bindings) } @@ -135,7 +135,7 @@ public final class Statement { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement object (useful for chaining). - public func run(_ bindings: [Binding?]) throws -> Statement { + @discardableResult public func run(_ bindings: [Binding?]) throws -> Statement { return try bind(bindings).run() } @@ -145,7 +145,7 @@ public final class Statement { /// - Throws: `Result.Error` if query execution fails. /// /// - Returns: The statement object (useful for chaining). - public func run(_ bindings: [String: Binding?]) throws -> Statement { + @discardableResult public func run(_ bindings: [String: Binding?]) throws -> Statement { return try bind(bindings).run() } diff --git a/SQLite/Extensions/FTS4.swift b/SQLite/Extensions/FTS4.swift index bd8c7b2d..ecaf2507 100644 --- a/SQLite/Extensions/FTS4.swift +++ b/SQLite/Extensions/FTS4.swift @@ -141,7 +141,7 @@ extension Tokenizer : CustomStringConvertible { extension Connection { public func registerTokenizer(_ submoduleName: String, next: @escaping (String) -> (String, Range)?) throws { - _ = try check(_SQLiteRegisterTokenizer(handle, Tokenizer.moduleName, submoduleName) { input, offset, length in + try check(_SQLiteRegisterTokenizer(handle, Tokenizer.moduleName, submoduleName) { input, offset, length in let string = String(cString: input) guard let (token, range) = next(string) else { return nil } @@ -178,7 +178,7 @@ open class FTSConfig { open func columns(_ columns: [Expressible]) -> Self { for column in columns { - _ = self.column(column) + self.column(column) } return self } @@ -217,15 +217,15 @@ open class FTSConfig { func options() -> Options { var options = Options() - _ = options.append(formatColumnDefinitions()) + options.append(formatColumnDefinitions()) if let tokenizer = tokenizer { - _ = options.append("tokenize", value: Expression(literal: tokenizer.description)) + options.append("tokenize", value: Expression(literal: tokenizer.description)) } - _ = options.appendCommaSeparated("prefix", values:prefixes.sorted().map { String($0) }) + options.appendCommaSeparated("prefix", values:prefixes.sorted().map { String($0) }) if isContentless { - _ = options.append("content", value: "") + options.append("content", value: "") } else if let externalContentSchema = externalContentSchema { - _ = options.append("content", value: externalContentSchema.tableName()) + options.append("content", value: externalContentSchema.tableName()) } return options } @@ -238,7 +238,7 @@ open class FTSConfig { return self } - mutating func appendCommaSeparated(_ key: String, values: [String]) -> Options { + @discardableResult mutating func appendCommaSeparated(_ key: String, values: [String]) -> Options { if values.isEmpty { return self } else { @@ -246,7 +246,7 @@ open class FTSConfig { } } - mutating func append(_ key: String, value: CustomStringConvertible?) -> Options { + @discardableResult mutating func append(_ key: String, value: CustomStringConvertible?) -> Options { return append(key, value: value?.description) } @@ -332,11 +332,11 @@ open class FTS4Config : FTSConfig { for (column, _) in (columnDefinitions.filter { $0.options.contains(.unindexed) }) { options.append("notindexed", value: column) } - _ = options.append("languageid", value: languageId) - _ = options.append("compress", value: compressFunction) - _ = options.append("uncompress", value: uncompressFunction) - _ = options.append("matchinfo", value: matchInfo) - _ = options.append("order", value: order) + options.append("languageid", value: languageId) + options.append("compress", value: compressFunction) + options.append("uncompress", value: uncompressFunction) + options.append("matchinfo", value: matchInfo) + options.append("order", value: order) return options } } diff --git a/SQLite/Extensions/FTS5.swift b/SQLite/Extensions/FTS5.swift index 9204d5b2..763927ff 100644 --- a/SQLite/Extensions/FTS5.swift +++ b/SQLite/Extensions/FTS5.swift @@ -77,11 +77,11 @@ open class FTS5Config : FTSConfig { override func options() -> Options { var options = super.options() - _ = options.append("content_rowid", value: contentRowId) + options.append("content_rowid", value: contentRowId) if let columnSize = columnSize { - _ = options.append("columnsize", value: Expression(value: columnSize)) + options.append("columnsize", value: Expression(value: columnSize)) } - _ = options.append("detail", value: detail) + options.append("detail", value: detail) return options } diff --git a/SQLite/Typed/Query.swift b/SQLite/Typed/Query.swift index 0e54392b..af6549de 100644 --- a/SQLite/Typed/Query.swift +++ b/SQLite/Typed/Query.swift @@ -971,7 +971,7 @@ extension Connection { public func run(_ query: Insert) throws -> Int64 { let expression = query.expression return try sync { - _ = try self.run(expression.template, expression.bindings) + try self.run(expression.template, expression.bindings) return self.lastInsertRowid! } } @@ -987,7 +987,7 @@ extension Connection { public func run(_ query: Update) throws -> Int { let expression = query.expression return try sync { - _ = try self.run(expression.template, expression.bindings) + try self.run(expression.template, expression.bindings) return self.changes } } @@ -1002,7 +1002,7 @@ extension Connection { public func run(_ query: Delete) throws -> Int { let expression = query.expression return try sync { - _ = try self.run(expression.template, expression.bindings) + try self.run(expression.template, expression.bindings) return self.changes } } diff --git a/SQLiteTests/ConnectionTests.swift b/SQLiteTests/ConnectionTests.swift index 4db671ad..3eb2b915 100644 --- a/SQLiteTests/ConnectionTests.swift +++ b/SQLiteTests/ConnectionTests.swift @@ -48,7 +48,7 @@ class ConnectionTests : SQLiteTestCase { } func test_lastInsertRowid_returnsLastIdAfterInserts() { - _ = try! InsertUser("alice") + try! InsertUser("alice") XCTAssertEqual(1, db.lastInsertRowid!) } @@ -57,17 +57,17 @@ class ConnectionTests : SQLiteTestCase { } func test_changes_returnsNumberOfChanges() { - _ = try! InsertUser("alice") + try! InsertUser("alice") XCTAssertEqual(1, db.changes) - _ = try! InsertUser("betsy") + try! InsertUser("betsy") XCTAssertEqual(1, db.changes) } func test_totalChanges_returnsTotalNumberOfChanges() { XCTAssertEqual(0, db.totalChanges) - _ = try! InsertUser("alice") + try! InsertUser("alice") XCTAssertEqual(1, db.totalChanges) - _ = try! InsertUser("betsy") + try! InsertUser("betsy") XCTAssertEqual(2, db.totalChanges) } @@ -79,10 +79,10 @@ class ConnectionTests : SQLiteTestCase { } func test_run_preparesRunsAndReturnsStatements() { - _ = try! db.run("SELECT * FROM users WHERE admin = 0") - _ = try! db.run("SELECT * FROM users WHERE admin = ?", 0) - _ = try! db.run("SELECT * FROM users WHERE admin = ?", [0]) - _ = try! db.run("SELECT * FROM users WHERE admin = $admin", ["$admin": 0]) + try! db.run("SELECT * FROM users WHERE admin = 0") + try! db.run("SELECT * FROM users WHERE admin = ?", 0) + try! db.run("SELECT * FROM users WHERE admin = ?", [0]) + try! db.run("SELECT * FROM users WHERE admin = $admin", ["$admin": 0]) AssertSQL("SELECT * FROM users WHERE admin = 0", 4) } @@ -116,7 +116,7 @@ class ConnectionTests : SQLiteTestCase { let stmt = try! db.prepare("INSERT INTO users (email) VALUES (?)", "alice@example.com") try! db.transaction { - _ = try stmt.run() + try stmt.run() } AssertSQL("BEGIN DEFERRED TRANSACTION") @@ -130,8 +130,8 @@ class ConnectionTests : SQLiteTestCase { do { try db.transaction { - _ = try stmt.run() - _ = try stmt.run() + try stmt.run() + try stmt.run() } } catch { } @@ -147,7 +147,7 @@ class ConnectionTests : SQLiteTestCase { try! db.savepoint("1") { try db.savepoint("2") { - _ = try db.run("INSERT INTO users (email) VALUES (?)", "alice@example.com") + try db.run("INSERT INTO users (email) VALUES (?)", "alice@example.com") } } @@ -167,14 +167,14 @@ class ConnectionTests : SQLiteTestCase { do { try db.savepoint("1") { try db.savepoint("2") { - _ = try stmt.run() - _ = try stmt.run() - _ = try stmt.run() + try stmt.run() + try stmt.run() + try stmt.run() } try db.savepoint("2") { - _ = try stmt.run() - _ = try stmt.run() - _ = try stmt.run() + try stmt.run() + try stmt.run() + try stmt.run() } } } catch { @@ -198,12 +198,12 @@ class ConnectionTests : SQLiteTestCase { XCTAssertEqual(1, rowid) done() } - _ = try! InsertUser("alice") + try! InsertUser("alice") } } func test_updateHook_setsUpdateHook_withUpdate() { - _ = try! InsertUser("alice") + try! InsertUser("alice") async { done in db.updateHook { operation, db, table, rowid in XCTAssertEqual(Connection.Operation.update, operation) @@ -212,12 +212,12 @@ class ConnectionTests : SQLiteTestCase { XCTAssertEqual(1, rowid) done() } - _ = try! db.run("UPDATE users SET email = 'alice@example.com'") + try! db.run("UPDATE users SET email = 'alice@example.com'") } } func test_updateHook_setsUpdateHook_withDelete() { - _ = try! InsertUser("alice") + try! InsertUser("alice") async { done in db.updateHook { operation, db, table, rowid in XCTAssertEqual(Connection.Operation.delete, operation) @@ -226,7 +226,7 @@ class ConnectionTests : SQLiteTestCase { XCTAssertEqual(1, rowid) done() } - _ = try! db.run("DELETE FROM users WHERE id = 1") + try! db.run("DELETE FROM users WHERE id = 1") } } @@ -236,7 +236,7 @@ class ConnectionTests : SQLiteTestCase { done() } try! db.transaction { - _ = try self.InsertUser("alice") + try self.InsertUser("alice") } XCTAssertEqual(1, try! db.scalar("SELECT count(*) FROM users") as? Int64) } @@ -247,8 +247,8 @@ class ConnectionTests : SQLiteTestCase { db.rollbackHook(done) do { try db.transaction { - _ = try self.InsertUser("alice") - _ = try self.InsertUser("alice") // throw + try self.InsertUser("alice") + try self.InsertUser("alice") // throw } } catch { } @@ -264,7 +264,7 @@ class ConnectionTests : SQLiteTestCase { db.rollbackHook(done) do { try db.transaction { - _ = try self.InsertUser("alice") + try self.InsertUser("alice") } } catch { } @@ -308,7 +308,7 @@ class ConnectionTests : SQLiteTestCase { } let stmt = try! db.prepare("SELECT *, sleep(?) FROM users", 0.1) - _ = try! stmt.run() + try! stmt.run() _ = DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.background).asyncAfter(deadline: DispatchTime.now() + Double(Int64(10 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC), execute: db.interrupt) AssertThrows(try stmt.run()) diff --git a/SQLiteTests/FTS4Tests.swift b/SQLiteTests/FTS4Tests.swift index 92f197a2..0148efc3 100644 --- a/SQLiteTests/FTS4Tests.swift +++ b/SQLiteTests/FTS4Tests.swift @@ -198,10 +198,10 @@ class FTS4IntegrationTests : SQLiteTestCase { return (token as String, string.range(of: input as String)!) } - _ = try! db.run(emails.create(.FTS4([subject, body], tokenize: .Custom(tokenizerName)))) + try! db.run(emails.create(.FTS4([subject, body], tokenize: .Custom(tokenizerName)))) AssertSQL("CREATE VIRTUAL TABLE \"emails\" USING fts4(\"subject\", \"body\", tokenize=\"SQLite.swift\" \"tokenizer\")") - _ = try! db.run(emails.insert(subject <- "Aún más cáfe!")) + try! db.run(emails.insert(subject <- "Aún más cáfe!")) XCTAssertEqual(1, try! db.scalar(emails.filter(emails.match("aun")).count)) } #endif diff --git a/SQLiteTests/TestHelpers.swift b/SQLiteTests/TestHelpers.swift index 7b7715b1..8c33bf6a 100644 --- a/SQLiteTests/TestHelpers.swift +++ b/SQLiteTests/TestHelpers.swift @@ -37,10 +37,10 @@ class SQLiteTestCase : XCTestCase { } func InsertUsers(_ names: [String]) throws { - for name in names { _ = try InsertUser(name) } + for name in names { try InsertUser(name) } } - func InsertUser(_ name: String, age: Int? = nil, admin: Bool = false) throws -> Statement { + @discardableResult func InsertUser(_ name: String, age: Int? = nil, admin: Bool = false) throws -> Statement { return try db.run( "INSERT INTO \"users\" (email, age, admin) values (?, ?, ?)", "\(name)@example.com", age?.datatypeValue, admin.datatypeValue @@ -56,7 +56,7 @@ class SQLiteTestCase : XCTestCase { } func AssertSQL(_ SQL: String, _ statement: Statement, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) { - _ = try! statement.run() + try! statement.run() AssertSQL(SQL, 1, message, file: file, line: line) if let count = trace[SQL] { trace[SQL] = count - 1 } } From 6bf844a1c6c2c6bbeadaab594124fc9874026ded Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 8 Oct 2016 13:59:55 +0200 Subject: [PATCH 25/36] Fix warnings --- SQLite/Core/Trace.swift | 2 ++ SQLite/Extensions/FTS4.swift | 10 +++++----- SQLite/Typed/Query.swift | 2 +- SQLiteTests/ConnectionTests.swift | 2 +- SQLiteTests/FTS4Tests.swift | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 SQLite/Core/Trace.swift diff --git a/SQLite/Core/Trace.swift b/SQLite/Core/Trace.swift new file mode 100644 index 00000000..350c82fa --- /dev/null +++ b/SQLite/Core/Trace.swift @@ -0,0 +1,2 @@ + +import Foundation diff --git a/SQLite/Extensions/FTS4.swift b/SQLite/Extensions/FTS4.swift index ecaf2507..7bbca7a5 100644 --- a/SQLite/Extensions/FTS4.swift +++ b/SQLite/Extensions/FTS4.swift @@ -171,12 +171,12 @@ open class FTSConfig { var isContentless: Bool = false /// Adds a column definition - open func column(_ column: Expressible, _ options: [ColumnOption] = []) -> Self { + @discardableResult open func column(_ column: Expressible, _ options: [ColumnOption] = []) -> Self { self.columnDefinitions.append((column, options)) return self } - open func columns(_ columns: [Expressible]) -> Self { + @discardableResult open func columns(_ columns: [Expressible]) -> Self { for column in columns { self.column(column) } @@ -233,7 +233,7 @@ open class FTSConfig { struct Options { var arguments = [Expressible]() - mutating func append(_ columns: [Expressible]) -> Options { + @discardableResult mutating func append(_ columns: [Expressible]) -> Options { arguments.append(contentsOf: columns) return self } @@ -250,11 +250,11 @@ open class FTSConfig { return append(key, value: value?.description) } - mutating func append(_ key: String, value: String?) -> Options { + @discardableResult mutating func append(_ key: String, value: String?) -> Options { return append(key, value: value.map { Expression($0) }) } - mutating func append(_ key: String, value: Expressible?) -> Options { + @discardableResult mutating func append(_ key: String, value: Expressible?) -> Options { if let value = value { arguments.append("=".join([Expression(literal: key), value])) } diff --git a/SQLite/Typed/Query.swift b/SQLite/Typed/Query.swift index af6549de..75f29afd 100644 --- a/SQLite/Typed/Query.swift +++ b/SQLite/Typed/Query.swift @@ -886,7 +886,7 @@ extension Connection { let columnNames: [String: Int] = try { var (columnNames, idx) = ([String: Int](), 0) - column: for each in query.clauses.select.columns ?? [Expression(literal: "*")] { + column: for each in query.clauses.select.columns { var names = each.expression.template.characters.split { $0 == "." }.map(String.init) let column = names.removeLast() let namespace = names.joined(separator: ".") diff --git a/SQLiteTests/ConnectionTests.swift b/SQLiteTests/ConnectionTests.swift index 3eb2b915..1d18bdca 100644 --- a/SQLiteTests/ConnectionTests.swift +++ b/SQLiteTests/ConnectionTests.swift @@ -310,7 +310,7 @@ class ConnectionTests : SQLiteTestCase { let stmt = try! db.prepare("SELECT *, sleep(?) FROM users", 0.1) try! stmt.run() - _ = DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.background).asyncAfter(deadline: DispatchTime.now() + Double(Int64(10 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC), execute: db.interrupt) + _ = DispatchQueue.global(qos: .background).asyncAfter(deadline: DispatchTime.now() + Double(Int64(10 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC), execute: db.interrupt) AssertThrows(try stmt.run()) } diff --git a/SQLiteTests/FTS4Tests.swift b/SQLiteTests/FTS4Tests.swift index 0148efc3..b2ccc86c 100644 --- a/SQLiteTests/FTS4Tests.swift +++ b/SQLiteTests/FTS4Tests.swift @@ -201,7 +201,7 @@ class FTS4IntegrationTests : SQLiteTestCase { try! db.run(emails.create(.FTS4([subject, body], tokenize: .Custom(tokenizerName)))) AssertSQL("CREATE VIRTUAL TABLE \"emails\" USING fts4(\"subject\", \"body\", tokenize=\"SQLite.swift\" \"tokenizer\")") - try! db.run(emails.insert(subject <- "Aún más cáfe!")) + try! _ = db.run(emails.insert(subject <- "Aún más cáfe!")) XCTAssertEqual(1, try! db.scalar(emails.filter(emails.match("aun")).count)) } #endif From 15490620c798e7715b43acec889af80230deedd6 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 8 Oct 2016 14:01:06 +0200 Subject: [PATCH 26/36] Accidental commit --- SQLite/Core/Trace.swift | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 SQLite/Core/Trace.swift diff --git a/SQLite/Core/Trace.swift b/SQLite/Core/Trace.swift deleted file mode 100644 index 350c82fa..00000000 --- a/SQLite/Core/Trace.swift +++ /dev/null @@ -1,2 +0,0 @@ - -import Foundation From 5bc521eb8abd7f125a0fab8338f61064e19811d7 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 8 Oct 2016 14:39:51 +0200 Subject: [PATCH 27/36] Only available on OS X 10.10 or newer --- SQLiteTests/ConnectionTests.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SQLiteTests/ConnectionTests.swift b/SQLiteTests/ConnectionTests.swift index 1d18bdca..33fa113d 100644 --- a/SQLiteTests/ConnectionTests.swift +++ b/SQLiteTests/ConnectionTests.swift @@ -310,7 +310,8 @@ class ConnectionTests : SQLiteTestCase { let stmt = try! db.prepare("SELECT *, sleep(?) FROM users", 0.1) try! stmt.run() - _ = DispatchQueue.global(qos: .background).asyncAfter(deadline: DispatchTime.now() + Double(Int64(10 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC), execute: db.interrupt) + let deadline = DispatchTime.now() + Double(Int64(10 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC) + _ = DispatchQueue.global(priority: .background).asyncAfter(deadline: deadline, execute: db.interrupt) AssertThrows(try stmt.run()) } From f11f6b8985bc5da530022a047f51b6d5585a72a9 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sun, 9 Oct 2016 08:52:59 +0200 Subject: [PATCH 28/36] cleanup --- SQLite/Core/Connection.swift | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index bd4cafb3..ad97466b 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -584,15 +584,20 @@ public final class Connection { /// - block: A collation function that takes two strings and returns the /// comparison result. public func createCollation(_ collation: String, _ block: @escaping (_ lhs: String, _ rhs: String) -> ComparisonResult) throws { - // TODO correct capacity - let box: Collation = { lhs, rhs in - let lstr = String(cString: lhs.bindMemory(to: UInt8.self, capacity: 0)) - let rstr = String(cString: rhs.bindMemory(to: UInt8.self, capacity: 0)) - return Int32(Int(block(lstr, rstr).rawValue)) + let box: Collation = { (lhs:UnsafeRawPointer, rhs:UnsafeRawPointer) in + let lstr = String(cString: lhs.assumingMemoryBound(to: UInt8.self)) + let rstr = String(cString: rhs.assumingMemoryBound(to: UInt8.self)) + return Int32(block(lstr, rstr).rawValue) } - try check(sqlite3_create_collation_v2(handle, collation, SQLITE_UTF8, unsafeBitCast(box, to: UnsafeMutableRawPointer.self), { callback, _, lhs, _, rhs in - unsafeBitCast(callback, to: Collation.self)(lhs!, rhs!) - }, nil)) + try check(sqlite3_create_collation_v2(handle, collation, SQLITE_UTF8, + unsafeBitCast(box, to: UnsafeMutableRawPointer.self), + { (callback:UnsafeMutableRawPointer?, _, lhs:UnsafeRawPointer?, _, rhs:UnsafeRawPointer?) in /* xCompare */ + if let lhs = lhs, let rhs = rhs { + return unsafeBitCast(callback, to: Collation.self)(lhs, rhs) + } else { + fatalError("sqlite3_create_collation_v2 callback called with NULL pointer") + } + }, nil /* xDestroy */)) collations[collation] = box } fileprivate typealias Collation = @convention(block) (UnsafeRawPointer, UnsafeRawPointer) -> Int32 From 6152ee3c17abe952ebea291f8d04557086b2ab07 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sun, 9 Oct 2016 16:20:19 +0200 Subject: [PATCH 29/36] Documentation updates --- Documentation/Index.md | 42 +++++++++++++++++++++--------------------- README.md | 4 ++-- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Documentation/Index.md b/Documentation/Index.md index 3063d095..8b136246 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -65,7 +65,7 @@ ## Installation -> _Note:_ SQLite.swift requires Swift 2 (and [Xcode 7](https://developer.apple.com/xcode/downloads/)) or greater. +> _Note:_ SQLite.swift requires Swift 3 (and [Xcode 8](https://developer.apple.com/xcode/downloads/)) or greater. ### Carthage @@ -203,10 +203,10 @@ On OS X, you can use your app’s **Application Support** directory: ``` swift var path = NSSearchPathForDirectoriesInDomains( .applicationSupportDirectory, .userDomainMask, true -).first! + NSBundle.mainBundle().bundleIdentifier! +).first! + Bundle.main.bundleIdentifier! // create parent directory iff it doesn’t exist -try NSFileManager.defaultManager().createDirectoryAtPath( +try FileManager.default.createDirectoryAtPath( path, withIntermediateDirectories: true, attributes: nil ) @@ -219,7 +219,7 @@ let db = try Connection("\(path)/db.sqlite3") If you bundle a database with your app (_i.e._, you’ve copied a database file into your Xcode project and added it to your application target), you can establish a _read-only_ connection to it. ``` swift -let path = NSBundle.mainBundle().pathForResource("db", ofType: "sqlite3")! +let path = Bundle.main.pathForResource("db", ofType: "sqlite3")! let db = try Connection(path, readonly: true) ``` @@ -1114,16 +1114,16 @@ Once extended, the type can be used [_almost_](#custom-type-caveats) wherever ty ### Date-Time Values -In SQLite, `DATETIME` columns can be treated as strings or numbers, so we can transparently bridge `NSDate` objects through Swift’s `String` or `Int` types. +In SQLite, `DATETIME` columns can be treated as strings or numbers, so we can transparently bridge `Date` objects through Swift’s `String` or `Int` types. -To serialize `NSDate` objects as `TEXT` values (in ISO 8601), we’ll use `String`. +To serialize `Date` objects as `TEXT` values (in ISO 8601), we’ll use `String`. ``` swift -extension NSDate: Value { +extension Date: Value { class var declaredDatatype: String { return String.declaredDatatype } - class func fromDatatypeValue(stringValue: String) -> NSDate { + class func fromDatatypeValue(stringValue: String) -> Date { return SQLDateFormatter.dateFromString(stringValue)! } var datatypeValue: String { @@ -1131,11 +1131,11 @@ extension NSDate: Value { } } -let SQLDateFormatter: NSDateFormatter = { - let formatter = NSDateFormatter() +let SQLDateFormatter: DateFormatter = { + let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS" - formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") - formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) + formatter.locale = Locale(localeIdentifier: "en_US_POSIX") + formatter.timeZone = TimeZone(forSecondsFromGMT: 0) return formatter }() ``` @@ -1143,12 +1143,12 @@ let SQLDateFormatter: NSDateFormatter = { We can also treat them as `INTEGER` values using `Int`. ``` swift -extension NSDate: Value { +extension Date: Value { class var declaredDatatype: String { return Int.declaredDatatype } class func fromDatatypeValue(intValue: Int) -> Self { - return self(timeIntervalSince1970: NSTimeInterval(intValue)) + return self(timeIntervalSince1970: TimeInterval(intValue)) } var datatypeValue: Int { return Int(timeIntervalSince1970) @@ -1161,9 +1161,9 @@ extension NSDate: Value { Once defined, we can use these types directly in SQLite statements. ``` swift -let published_at = Expression("published_at") +let published_at = Expression("published_at") -let published = posts.filter(published_at <= NSDate()) +let published = posts.filter(published_at <= Date()) // extension where Datatype == String: // SELECT * FROM "posts" WHERE "published_at" <= '2014-11-18 12:45:30' // extension where Datatype == Int: @@ -1175,10 +1175,10 @@ let published = posts.filter(published_at <= NSDate()) Any object that can be encoded and decoded can be stored as a blob of data in SQL. -We can create an `NSData` bridge rather trivially. +We can create an `Data` bridge rather trivially. ``` swift -extension NSData: Value { +extension Data: Value { class var declaredDatatype: String { return Blob.declaredDatatype } @@ -1191,16 +1191,16 @@ extension NSData: Value { } ``` -We can bridge any type that can be initialized from and encoded to `NSData`. +We can bridge any type that can be initialized from and encoded to `Data`. ``` swift -// assumes NSData conformance, above +// assumes Data conformance, above extension UIImage: Value { public class var declaredDatatype: String { return Blob.declaredDatatype } public class func fromDatatypeValue(blobValue: Blob) -> UIImage { - return UIImage(data: NSData.fromDatatypeValue(blobValue))! + return UIImage(data: Data.fromDatatypeValue(blobValue))! } public var datatypeValue: Blob { return UIImagePNGRepresentation(self)!.datatypeValue diff --git a/README.md b/README.md index 53d654fb..bdd652f2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SQLite.swift -[![Build Status][Badge]][Travis] [![CocoaPods Version](https://cocoapod-badges.herokuapp.com/v/SQLite.swift/badge.png)](http://cocoadocs.org/docsets/SQLite.swift) [![Platform](https://cocoapod-badges.herokuapp.com/p/SQLite.swift/badge.png)](http://cocoadocs.org/docsets/SQLite.swift) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Join the chat at https://gitter.im/stephencelis/SQLite.swift](https://badges.gitter.im/stephencelis/SQLite.swift.svg)](https://gitter.im/stephencelis/SQLite.swift) +[![Build Status][Badge]][Travis] [![CocoaPods Version](https://cocoapod-badges.herokuapp.com/v/SQLite.swift/badge.png)](http://cocoadocs.org/docsets/SQLite.swift) [![Swift](https://img.shields.io/badge/swift-3-orange.svg?style=flat)](https://developer.apple.com/swift/) [![Platform](https://cocoapod-badges.herokuapp.com/p/SQLite.swift/badge.png)](http://cocoadocs.org/docsets/SQLite.swift) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Join the chat at https://gitter.im/stephencelis/SQLite.swift](https://badges.gitter.im/stephencelis/SQLite.swift.svg)](https://gitter.im/stephencelis/SQLite.swift) A type-safe, [Swift][]-language layer over [SQLite3][]. @@ -109,7 +109,7 @@ For a more comprehensive example, see [this article](http://masteringswift.blogs ## Installation -> _Note:_ SQLite.swift requires Swift 2 (and [Xcode][] 7) or greater. +> _Note:_ SQLite.swift requires Swift 3 (and [Xcode][] 8) or greater. > > The following instructions apply to targets that support embedded > Swift frameworks. To use SQLite.swift in iOS 7 or an OS X command line From bbab40147c17ab1c68f5a57d68b564d97c8a4f1a Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sun, 9 Oct 2016 16:24:47 +0200 Subject: [PATCH 30/36] Remove FIXME --- SQLite/Core/Connection.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index ad97466b..f95246fd 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -101,7 +101,7 @@ public final class Connection { public init(_ location: Location = .inMemory, readonly: Bool = false) throws { let flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE try check(sqlite3_open_v2(location.description, &_handle, flags | SQLITE_OPEN_FULLMUTEX, nil)) - queue.setSpecific(key: /*Migrator FIXME: Use a variable of type DispatchSpecificKey*/ Connection.queueKey, value: queueContext) + queue.setSpecific(key: Connection.queueKey, value: queueContext) } /// Initializes a new connection to a database. From 96238f558d776354ceeafe52d04bc17df280bb34 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sun, 9 Oct 2016 16:36:41 +0200 Subject: [PATCH 31/36] sqlite3_trace --- SQLite/Core/Connection.swift | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index f95246fd..d836f1d4 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -419,9 +419,13 @@ public final class Connection { } let box: Trace = { callback(String(cString: $0)) } - sqlite3_trace(handle, { callback, SQL in - unsafeBitCast(callback, to: Trace.self)(SQL!) - }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) + sqlite3_trace(handle, { + (callback: UnsafeMutableRawPointer?, SQL: UnsafePointer?) in + guard let callback = callback, let SQL = SQL else { return } + unsafeBitCast(callback, to: Trace.self)(SQL) + }, + unsafeBitCast(box, to: UnsafeMutableRawPointer.self) + ) trace = box } fileprivate typealias Trace = @convention(block) (UnsafePointer) -> Void @@ -584,14 +588,14 @@ public final class Connection { /// - block: A collation function that takes two strings and returns the /// comparison result. public func createCollation(_ collation: String, _ block: @escaping (_ lhs: String, _ rhs: String) -> ComparisonResult) throws { - let box: Collation = { (lhs:UnsafeRawPointer, rhs:UnsafeRawPointer) in + let box: Collation = { (lhs: UnsafeRawPointer, rhs: UnsafeRawPointer) in let lstr = String(cString: lhs.assumingMemoryBound(to: UInt8.self)) let rstr = String(cString: rhs.assumingMemoryBound(to: UInt8.self)) return Int32(block(lstr, rstr).rawValue) } try check(sqlite3_create_collation_v2(handle, collation, SQLITE_UTF8, unsafeBitCast(box, to: UnsafeMutableRawPointer.self), - { (callback:UnsafeMutableRawPointer?, _, lhs:UnsafeRawPointer?, _, rhs:UnsafeRawPointer?) in /* xCompare */ + { (callback: UnsafeMutableRawPointer?, _, lhs: UnsafeRawPointer?, _, rhs: UnsafeRawPointer?) in /* xCompare */ if let lhs = lhs, let rhs = rhs { return unsafeBitCast(callback, to: Collation.self)(lhs, rhs) } else { From b392eaf6620a662e477597518e240760f48a04cd Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sun, 9 Oct 2016 16:42:54 +0200 Subject: [PATCH 32/36] Remove unneeded typealias --- SQLite/Core/Connection.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index d836f1d4..6aa27dc6 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -576,9 +576,6 @@ public final class Connection { fileprivate typealias Function = @convention(block) (OpaquePointer?, Int32, UnsafeMutablePointer?) -> Void fileprivate var functions = [String: [Int: Function]]() - /// The return type of a collation comparison function. - public typealias ComparisonResult = Foundation.ComparisonResult - /// Defines a new collating sequence. /// /// - Parameters: From 8ba973e2fed5e008b7129596107a215578090c54 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Mon, 10 Oct 2016 15:13:41 +0200 Subject: [PATCH 33/36] Remove outdated sample code (#516) --- Documentation/Index.md | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Documentation/Index.md b/Documentation/Index.md index 8b136246..91f631ef 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -1173,28 +1173,9 @@ let published = posts.filter(published_at <= Date()) ### Binary Data -Any object that can be encoded and decoded can be stored as a blob of data in SQL. - -We can create an `Data` bridge rather trivially. - -``` swift -extension Data: Value { - class var declaredDatatype: String { - return Blob.declaredDatatype - } - class func fromDatatypeValue(blobValue: Blob) -> Self { - return self(bytes: blobValue.bytes, length: blobValue.length) - } - var datatypeValue: Blob { - return Blob(bytes: bytes, length: length) - } -} -``` - We can bridge any type that can be initialized from and encoded to `Data`. ``` swift -// assumes Data conformance, above extension UIImage: Value { public class var declaredDatatype: String { return Blob.declaredDatatype From 681e21926f3b8bb813c91319d63e04cab4eb3f76 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Mon, 10 Oct 2016 19:33:51 +0200 Subject: [PATCH 34/36] Update bundler --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d280766b..925ceee3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ matrix: - env: VALIDATOR_SUBSPEC="standard" - env: VALIDATOR_SUBSPEC="standalone" before_install: + - gem update bundler - gem install xcpretty --no-document script: - ./run-tests.sh From db8f39b0a1cc845f0158f70a27c6e29e5d8d9e28 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 11 Oct 2016 15:08:03 +0200 Subject: [PATCH 35/36] Only import module when building with CocoaPods --- SQLite/Core/Connection.swift | 2 +- SQLite/Core/Statement.swift | 2 +- SQLite/Helpers.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SQLite/Core/Connection.swift b/SQLite/Core/Connection.swift index 6aa27dc6..22f09c27 100644 --- a/SQLite/Core/Connection.swift +++ b/SQLite/Core/Connection.swift @@ -26,7 +26,7 @@ import Foundation.NSUUID import Dispatch #if SQLITE_SWIFT_STANDALONE import sqlite3 -#else +#elseif COCOAPODS import CSQLite #endif diff --git a/SQLite/Core/Statement.swift b/SQLite/Core/Statement.swift index a7664993..64b9017f 100644 --- a/SQLite/Core/Statement.swift +++ b/SQLite/Core/Statement.swift @@ -24,7 +24,7 @@ #if SQLITE_SWIFT_STANDALONE import sqlite3 -#else +#elseif COCOAPODS import CSQLite #endif diff --git a/SQLite/Helpers.swift b/SQLite/Helpers.swift index e9a17ce6..febdc949 100644 --- a/SQLite/Helpers.swift +++ b/SQLite/Helpers.swift @@ -24,7 +24,7 @@ #if SQLITE_SWIFT_STANDALONE import sqlite3 -#else +#elseif COCOAPODS import CSQLite #endif From 6b4cb81e78852c203397bf9132f75d78bab92b1c Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 11 Oct 2016 15:51:13 +0200 Subject: [PATCH 36/36] Mention swift-2.3 branch in documentation --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bdd652f2..87d283d6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# SQLite.swift +# SQLite.swift [![Build Status][Badge]][Travis] [![CocoaPods Version](https://cocoapod-badges.herokuapp.com/v/SQLite.swift/badge.png)](http://cocoadocs.org/docsets/SQLite.swift) [![Swift](https://img.shields.io/badge/swift-3-orange.svg?style=flat)](https://developer.apple.com/swift/) [![Platform](https://cocoapod-badges.herokuapp.com/p/SQLite.swift/badge.png)](http://cocoadocs.org/docsets/SQLite.swift) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Join the chat at https://gitter.im/stephencelis/SQLite.swift](https://badges.gitter.im/stephencelis/SQLite.swift.svg)](https://gitter.im/stephencelis/SQLite.swift) @@ -109,7 +109,9 @@ For a more comprehensive example, see [this article](http://masteringswift.blogs ## Installation -> _Note:_ SQLite.swift requires Swift 3 (and [Xcode][] 8) or greater. +> _Note:_ SQLite.swift requires Swift 3 (and [Xcode][] 8) or greater. If you absolutely +> need compatibility with Swift 2.3 you can use the [swift-2.3][] branch or older +> released versions. New development will happen exclusively on the master/Swift 3 branch. > > The following instructions apply to targets that support embedded > Swift frameworks. To use SQLite.swift in iOS 7 or an OS X command line @@ -199,7 +201,7 @@ To install SQLite.swift as an Xcode sub-project: - Found a **bug** or have a **feature request**? [Open an issue][]. - Want to **contribute**? [Submit a pull request][]. -[See the planning document]: /Documentation/Planning.md +[See the planning document]: /Documentation/Planning.md [Read the contributing guidelines]: ./CONTRIBUTING.md#contributing [Ask on Stack Overflow]: http://stackoverflow.com/questions/tagged/sqlite.swift [Open an issue]: https://github.com/stephencelis/SQLite.swift/issues/new @@ -237,3 +239,4 @@ Looking for something else? Try another Swift wrapper (or [FMDB][]): - [SwiftSQLite](https://github.com/chrismsimpson/SwiftSQLite) [FMDB]: https://github.com/ccgus/fmdb +[swift-2.3]: https://github.com/stephencelis/SQLite.swift/tree/swift-2.3