├── docs
├── docsets
│ ├── .tgz
│ └── .docset
│ │ └── Contents
│ │ ├── Resources
│ │ ├── docSet.dsidx
│ │ └── Documents
│ │ │ ├── undocumented.json
│ │ │ ├── img
│ │ │ ├── dash.png
│ │ │ ├── gh.png
│ │ │ └── carat.png
│ │ │ ├── js
│ │ │ └── jazzy.js
│ │ │ ├── index.html
│ │ │ ├── Enums.html
│ │ │ ├── Enums
│ │ │ └── SQLiteError.html
│ │ │ ├── css
│ │ │ ├── highlight.css
│ │ │ └── jazzy.css
│ │ │ ├── Classes.html
│ │ │ └── Classes
│ │ │ └── SQLite.html
│ │ └── Info.plist
├── img
│ ├── dash.png
│ ├── gh.png
│ └── carat.png
├── undocumented.json
├── js
│ └── jazzy.js
├── index.html
├── Enums.html
├── Enums
│ └── SQLiteError.html
├── css
│ ├── highlight.css
│ └── jazzy.css
├── Classes.html
└── Classes
│ └── SQLite.html
├── Tests
├── LinuxMain.swift
└── PerfectSQLiteTests
│ └── XCTestManifests.swift
├── .jazzy.yaml
├── Package.swift
├── .gitignore
├── README.md
├── LICENSE
└── Sources
└── PerfectSQLite
├── SQLiteCRUD.swift
└── SQLite.swift
/docs/docsets/.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PerfectlySoft/Perfect-SQLite/HEAD/docs/docsets/.tgz
--------------------------------------------------------------------------------
/docs/img/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PerfectlySoft/Perfect-SQLite/HEAD/docs/img/dash.png
--------------------------------------------------------------------------------
/docs/img/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PerfectlySoft/Perfect-SQLite/HEAD/docs/img/gh.png
--------------------------------------------------------------------------------
/docs/img/carat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PerfectlySoft/Perfect-SQLite/HEAD/docs/img/carat.png
--------------------------------------------------------------------------------
/docs/undocumented.json:
--------------------------------------------------------------------------------
1 | {"warnings":[],"source_directory":"/Users/taplin/Documents/PerfectProjects/Perfect-SQLite/Xcode/Perfect-SQLite"}
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import PerfectSQLiteTests
3 |
4 | XCTMain([
5 | testCase(PerfectSQLiteTests.allTests),
6 | ])
7 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/docSet.dsidx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PerfectlySoft/Perfect-SQLite/HEAD/docs/docsets/.docset/Contents/Resources/docSet.dsidx
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/undocumented.json:
--------------------------------------------------------------------------------
1 | {"warnings":[],"source_directory":"/Users/taplin/Documents/PerfectProjects/Perfect-SQLite/Xcode/Perfect-SQLite"}
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/img/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PerfectlySoft/Perfect-SQLite/HEAD/docs/docsets/.docset/Contents/Resources/Documents/img/dash.png
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/img/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PerfectlySoft/Perfect-SQLite/HEAD/docs/docsets/.docset/Contents/Resources/Documents/img/gh.png
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/img/carat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PerfectlySoft/Perfect-SQLite/HEAD/docs/docsets/.docset/Contents/Resources/Documents/img/carat.png
--------------------------------------------------------------------------------
/.jazzy.yaml:
--------------------------------------------------------------------------------
1 | module: PerfectSQLite
2 | author: PerfectlySoft
3 | author_url: https://perfect.org
4 | github_url: https://github.com/PerfectlySoft/Perfect-SQLite
5 | copyright: '© 2016 PerfectlySoft Inc. and the Perfect project authors'
6 | theme: fullwidth
7 | xcodebuild_arguments: [-target, SQLite, -toolchain, org.swift.3020160620a]
8 | clean: true
9 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | com.jazzy.
7 | CFBundleName
8 |
9 | DocSetPlatformFamily
10 | jazzy
11 | isDashDocset
12 |
13 | dashIndexFilePath
14 | index.html
15 | isJavaScriptEnabled
16 |
17 | DashDocSetFamily
18 | dashtoc
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Tests/PerfectSQLiteTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // XCTestManifests.swift
3 | //
4 | // Created by Kyle Jessup on 2015-10-19.
5 | // Copyright © 2015 PerfectlySoft. All rights reserved.
6 | //
7 | //===----------------------------------------------------------------------===//
8 | //
9 | // This source file is part of the Perfect.org open source project
10 | //
11 | // Copyright (c) 2015 - 2016 PerfectlySoft Inc. and the Perfect project authors
12 | // Licensed under Apache License v2.0
13 | //
14 | // See http://perfect.org/licensing.html for license information
15 | //
16 | //===----------------------------------------------------------------------===//
17 | //
18 |
19 | import XCTest
20 |
21 | #if !os(OSX)
22 | public func allTests() -> [XCTestCaseEntry] {
23 | return [
24 | testCase(PerfectSQLiteTests.allTests)
25 | ]
26 | }
27 | #endif
28 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 | // Generated automatically by Perfect Assistant
3 | // Date: 2018-12-25 02:23:42 +0000
4 | import PackageDescription
5 |
6 | #if os(Linux)
7 | let package = Package(
8 | name: "PerfectSQLite",
9 | products: [
10 | .library(name: "PerfectSQLite", targets: ["PerfectSQLite"])
11 | ],
12 | dependencies: [
13 | .package(url: "https://github.com/PerfectlySoft/Perfect-CRUD.git", from: "2.0.0"),
14 | .package(url: "https://github.com/PerfectlySoft/Perfect-sqlite3-support.git", from: "3.0.0"),
15 | ],
16 | targets: [
17 | .target(name: "PerfectSQLite", dependencies: ["PerfectCRUD"]),
18 | .testTarget(name: "PerfectSQLiteTests", dependencies: ["PerfectSQLite"])
19 | ]
20 | )
21 | #else
22 | let package = Package(
23 | name: "PerfectSQLite",
24 | platforms: [
25 | .macOS(.v10_15)
26 | ],
27 | products: [
28 | .library(name: "PerfectSQLite", targets: ["PerfectSQLite"])
29 | ],
30 | dependencies: [
31 | .package(url: "https://github.com/PerfectlySoft/Perfect-CRUD.git", from: "2.0.0")
32 | ],
33 | targets: [
34 | .target(name: "PerfectSQLite", dependencies: ["PerfectCRUD"]),
35 | .testTarget(name: "PerfectSQLiteTests", dependencies: ["PerfectSQLite"])
36 | ]
37 | )
38 | #endif
39 |
--------------------------------------------------------------------------------
/docs/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | // On doc load, toggle the URL hash discussion if present
12 | $(document).ready(function() {
13 | if (!window.jazzy.docset) {
14 | var linkToHash = $('a[href="' + window.location.hash +'"]');
15 | linkToHash.trigger("click");
16 | }
17 | });
18 |
19 | // On token click, toggle its discussion and animate token.marginLeft
20 | $(".token").click(function(event) {
21 | if (window.jazzy.docset) {
22 | return;
23 | }
24 | var link = $(this);
25 | var animationDuration = 300;
26 | var tokenOffset = "15px";
27 | var original = link.css('marginLeft') == tokenOffset;
28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration);
29 | $content = link.parent().parent().next();
30 | $content.slideToggle(animationDuration);
31 |
32 | // Keeps the document from jumping to the hash.
33 | var href = $(this).attr('href');
34 | if (history.pushState) {
35 | history.pushState({}, '', href);
36 | } else {
37 | location.hash = href;
38 | }
39 | event.preventDefault();
40 | });
41 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | // On doc load, toggle the URL hash discussion if present
12 | $(document).ready(function() {
13 | if (!window.jazzy.docset) {
14 | var linkToHash = $('a[href="' + window.location.hash +'"]');
15 | linkToHash.trigger("click");
16 | }
17 | });
18 |
19 | // On token click, toggle its discussion and animate token.marginLeft
20 | $(".token").click(function(event) {
21 | if (window.jazzy.docset) {
22 | return;
23 | }
24 | var link = $(this);
25 | var animationDuration = 300;
26 | var tokenOffset = "15px";
27 | var original = link.css('marginLeft') == tokenOffset;
28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration);
29 | $content = link.parent().parent().next();
30 | $content.slideToggle(animationDuration);
31 |
32 | // Keeps the document from jumping to the hash.
33 | var href = $(this).attr('href');
34 | if (history.pushState) {
35 | history.pushState({}, '', href);
36 | } else {
37 | location.hash = href;
38 | }
39 | event.preventDefault();
40 | });
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata
19 |
20 | ## Other
21 | *.xccheckout
22 | *.moved-aside
23 | *.xcuserstate
24 | *.xcscmblueprint
25 |
26 | ## Obj-C/Swift specific
27 | *.hmap
28 | *.ipa
29 |
30 | ## Playgrounds
31 | timeline.xctimeline
32 | playground.xcworkspace
33 |
34 | # Swift Package Manager
35 | #
36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
37 | # Packages/
38 | .build/
39 |
40 | # CocoaPods
41 | #
42 | # We recommend against adding the Pods directory to your .gitignore. However
43 | # you should judge for yourself, the pros and cons are mentioned at:
44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
45 | #
46 | # Pods/
47 |
48 | # Carthage
49 | #
50 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
51 | # Carthage/Checkouts
52 |
53 | Carthage/Build
54 |
55 | # fastlane
56 | #
57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
58 | # screenshots whenever they are needed.
59 | # For more information about the recommended setup visit:
60 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
61 |
62 | fastlane/report.xml
63 | fastlane/screenshots
64 |
65 | Packages/
66 | SQLite.xcodeproj/
67 | .DS_Store
68 | .build_lin/
69 | .packages_lin/
70 | PADockerfile_build
71 | PADockerfile_deploy
72 | Package.pins
73 | Package.resolved
74 | buildlinux
75 | *.xcodeproj/
76 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Docs (100% documented)
17 |
18 |
19 |
20 |
21 | Reference
22 |
23 | Reference
24 |
25 |
26 |
27 |
50 |
51 |
52 |
53 |
54 | Authors
55 |
56 |
57 |
58 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Docs (100% documented)
17 |
18 |
19 |
20 |
21 | Reference
22 |
23 | Reference
24 |
25 |
26 |
27 |
50 |
51 |
52 |
53 |
54 | Authors
55 |
56 |
57 |
58 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/docs/Enums.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Enums Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Docs (100% documented)
17 |
18 |
19 |
20 |
21 | Reference
22 |
23 | Enums Reference
24 |
25 |
26 |
27 |
50 |
51 |
52 |
53 | Enums
54 | The following enums are available globally.
55 |
56 |
57 |
58 |
59 |
60 |
61 |
68 |
69 |
70 |
71 |
72 |
73 |
This enum type indicates an exception when dealing with a SQLite database
74 |
75 |
See more
76 |
77 |
78 |
Declaration
79 |
80 |
Swift
81 |
public enum SQLiteError : ErrorProtocol
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/Enums.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Enums Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Docs (100% documented)
17 |
18 |
19 |
20 |
21 | Reference
22 |
23 | Enums Reference
24 |
25 |
26 |
27 |
50 |
51 |
52 |
53 | Enums
54 | The following enums are available globally.
55 |
56 |
57 |
58 |
59 |
60 |
61 |
68 |
69 |
70 |
71 |
72 |
73 |
This enum type indicates an exception when dealing with a SQLite database
74 |
75 |
See more
76 |
77 |
78 |
Declaration
79 |
80 |
Swift
81 |
public enum SQLiteError : ErrorProtocol
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/docs/Enums/SQLiteError.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SQLiteError Enum Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
Docs (100% documented)
18 |
19 |
20 |
21 |
22 | Reference
23 |
24 | SQLiteError Enum Reference
25 |
26 |
27 |
28 |
51 |
52 |
53 |
54 | SQLiteError
55 |
56 |
57 |
public enum SQLiteError : ErrorProtocol
58 |
59 |
60 |
61 | This enum type indicates an exception when dealing with a SQLite database
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | Error
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
A SQLite error code and message.
81 |
82 |
83 |
84 |
Declaration
85 |
86 |
Swift
87 |
case Error ( code : Int , msg : String )
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/Enums/SQLiteError.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SQLiteError Enum Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
Docs (100% documented)
18 |
19 |
20 |
21 |
22 | Reference
23 |
24 | SQLiteError Enum Reference
25 |
26 |
27 |
28 |
51 |
52 |
53 |
54 | SQLiteError
55 |
56 |
57 |
public enum SQLiteError : ErrorProtocol
58 |
59 |
60 |
61 | This enum type indicates an exception when dealing with a SQLite database
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | Error
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
A SQLite error code and message.
81 |
82 |
83 |
84 |
Declaration
85 |
86 |
Swift
87 |
case Error ( code : Int , msg : String )
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/docs/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/Classes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Classes Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Docs (100% documented)
17 |
18 |
19 |
20 |
21 | Reference
22 |
23 | Classes Reference
24 |
25 |
26 |
27 |
50 |
51 |
52 |
53 | Classes
54 | The following classes are available globally.
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | SQLite
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
A SQLite database
74 |
75 |
See more
76 |
77 |
78 |
Declaration
79 |
80 |
Swift
81 |
public class SQLite
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
96 |
97 |
98 |
99 |
100 |
101 |
A compiled SQLite statement
102 |
103 |
See more
104 |
105 |
106 |
Declaration
107 |
108 |
Swift
109 |
public class SQLiteStmt
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/Classes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Classes Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Docs (100% documented)
17 |
18 |
19 |
20 |
21 | Reference
22 |
23 | Classes Reference
24 |
25 |
26 |
27 |
50 |
51 |
52 |
53 | Classes
54 | The following classes are available globally.
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | SQLite
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
A SQLite database
74 |
75 |
See more
76 |
77 |
78 |
Declaration
79 |
80 |
Swift
81 |
public class SQLite
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
96 |
97 |
98 |
99 |
100 |
101 |
A compiled SQLite statement
102 |
103 |
See more
104 |
105 |
106 |
Declaration
107 |
108 |
Swift
109 |
public class SQLiteStmt
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Perfect - SQLite Connector
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | This project provides a Swift wrapper around the SQLite 3 library.
44 |
45 | This package builds with Swift Package Manager and is part of the [Perfect](https://github.com/PerfectlySoft/Perfect) project. It was written to be stand-alone and so does not require PerfectLib or any other components.
46 |
47 | Ensure you have installed and activated the latest Swift 4.0 tool chain.
48 |
49 | To learn more, you can read the full documentation guide [here](https://github.com/PerfectlySoft/PerfectDocs/blob/master/guide/SQLite.md) or jump to the example [here](#Usage-Example)
50 |
51 |
52 | ## Linux Build Notes
53 |
54 | Ensure that you have installed sqlite3.
55 |
56 | ```
57 | sudo apt-get install sqlite3
58 | ```
59 |
60 | ## Building
61 |
62 | Add this project as a dependency in your Package.swift file.
63 |
64 | ```
65 | .Package(url: "https://github.com/PerfectlySoft/Perfect-SQLite.git", majorVersion: 3)
66 | ```
67 |
68 | ### Edge Case
69 | If you encounter error like such ``` sqlite3.h file not found ``` during ```$ swift build ```, one solution is to install the sqlite3-dev i.e. ```$ sudo apt-get install libsqlite3-dev```
70 |
71 |
72 | ## Usage Example
73 |
74 | Let’s assume you’d like to host a blog in Swift. First we need tables. Assuming you’ve created an SQLite file `./db/database`, we simply need to connect and add the tables.
75 |
76 | ```swift
77 | let dbPath = "./db/database"
78 |
79 | do {
80 | let sqlite = try SQLite(dbPath)
81 | defer {
82 | sqlite.close()
83 | }
84 |
85 | try sqlite.execute(statement: "CREATE TABLE IF NOT EXISTS posts (id INTEGER PRIMARY KEY NOT NULL, post_title TEXT NOT NULL, post_content TEXT NOT NULL, featured_image_uri TEXT NOT NULL)")
86 | } catch {
87 | print("Failure creating database tables") //Handle Errors
88 | }
89 | ```
90 |
91 | Next, we would need to add some content.
92 |
93 | ```swift
94 | let dbPath = "./db/database"
95 | let postTitle = "Test Title"
96 | let postContent = "Lorem ipsum dolor sit amet…"
97 |
98 | do {
99 | let sqlite = try SQLite(dbPath)
100 | defer {
101 | sqlite.close()
102 | }
103 |
104 | try sqlite.execute(statement: "INSERT INTO posts (post_title, post_content) VALUES (:1,:2)") {
105 | (stmt:SQLiteStmt) -> () in
106 |
107 | try stmt.bind(position: 1, postTitle)
108 | try stmt.bind(position: 2, postContent)
109 | }
110 | } catch {
111 | //Handle Errors
112 | }
113 | ```
114 |
115 | Finally, we retrieve posts and post titles from an SQLite database full of blog content. Each id, post, and title is appended to a dictionary for use elsewhere.
116 |
117 | ``` swift
118 | let dbPath = "./db/database"
119 | var contentDict = [String: Any]()
120 |
121 | do {
122 | let sqlite = try SQLite(dbPath)
123 | defer {
124 | sqlite.close() // This makes sure we close our connection.
125 | }
126 |
127 | let demoStatement = "SELECT post_title, post_content FROM posts ORDER BY id DESC LIMIT :1"
128 |
129 | try sqlite.forEachRow(statement: demoStatement, doBindings: {
130 |
131 | (statement: SQLiteStmt) -> () in
132 |
133 | let bindValue = 5
134 | try statement.bind(position: 1, bindValue)
135 |
136 | }) {(statement: SQLiteStmt, i:Int) -> () in
137 |
138 | self.contentDict.append([
139 | "id": statement.columnText(position: 0),
140 | "second_field": statement.columnText(position: 1),
141 | "third_field": statement.columnText(position: 2)
142 | ])
143 | }
144 |
145 | } catch {
146 | //Handle Errors
147 | }
148 | ```
149 |
150 | ## Further Information
151 | For more information on the Perfect project, please visit [perfect.org](http://www.perfect.org/docs/SQLite.html).
152 |
--------------------------------------------------------------------------------
/docs/css/jazzy.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td {
2 | background: transparent;
3 | border: 0;
4 | margin: 0;
5 | outline: 0;
6 | padding: 0;
7 | vertical-align: baseline; }
8 |
9 | body {
10 | background-color: #f2f2f2;
11 | font-family: Helvetica, freesans, Arial, sans-serif;
12 | font-size: 14px;
13 | -webkit-font-smoothing: subpixel-antialiased;
14 | word-wrap: break-word; }
15 |
16 | h1, h2, h3 {
17 | margin-top: 0.8em;
18 | margin-bottom: 0.3em;
19 | font-weight: 100;
20 | color: black; }
21 |
22 | h1 {
23 | font-size: 2.5em; }
24 |
25 | h2 {
26 | font-size: 2em;
27 | border-bottom: 1px solid #e2e2e2; }
28 |
29 | h4 {
30 | font-size: 13px;
31 | line-height: 1.5;
32 | margin-top: 21px; }
33 |
34 | h5 {
35 | font-size: 1.1em; }
36 |
37 | h6 {
38 | font-size: 1.1em;
39 | color: #777; }
40 |
41 | .section-name {
42 | color: gray;
43 | display: block;
44 | font-family: Helvetica;
45 | font-size: 22px;
46 | font-weight: 100;
47 | margin-bottom: 15px; }
48 |
49 | pre, code {
50 | font: 0.95em Menlo, monospace;
51 | color: #777;
52 | word-wrap: normal; }
53 |
54 | p code, li code {
55 | background-color: #eee;
56 | padding: 2px 4px;
57 | border-radius: 4px; }
58 |
59 | a {
60 | color: #0088cc;
61 | text-decoration: none; }
62 |
63 | ul {
64 | padding-left: 15px; }
65 |
66 | li {
67 | line-height: 1.8em; }
68 |
69 | img {
70 | max-width: 100%; }
71 |
72 | blockquote {
73 | margin-left: 0;
74 | padding: 0 10px;
75 | border-left: 4px solid #ccc; }
76 |
77 | .content-wrapper {
78 | margin: 0 auto;
79 | width: 980px; }
80 |
81 | header {
82 | font-size: 0.85em;
83 | line-height: 26px;
84 | background-color: #414141;
85 | position: fixed;
86 | width: 100%;
87 | z-index: 1; }
88 | header img {
89 | padding-right: 6px;
90 | vertical-align: -4px;
91 | height: 16px; }
92 | header a {
93 | color: #fff; }
94 | header p {
95 | float: left;
96 | color: #999; }
97 | header .header-right {
98 | float: right;
99 | margin-left: 16px; }
100 |
101 | #breadcrumbs {
102 | background-color: #f2f2f2;
103 | height: 27px;
104 | padding-top: 17px;
105 | position: fixed;
106 | width: 100%;
107 | z-index: 1;
108 | margin-top: 26px; }
109 | #breadcrumbs #carat {
110 | height: 10px;
111 | margin: 0 5px; }
112 |
113 | .sidebar {
114 | background-color: #f9f9f9;
115 | border: 1px solid #e2e2e2;
116 | overflow-y: auto;
117 | overflow-x: hidden;
118 | position: fixed;
119 | top: 70px;
120 | bottom: 0;
121 | width: 230px;
122 | word-wrap: normal; }
123 |
124 | .nav-groups {
125 | list-style-type: none;
126 | background: #fff;
127 | padding-left: 0; }
128 |
129 | .nav-group-name {
130 | border-bottom: 1px solid #e2e2e2;
131 | font-size: 1.1em;
132 | font-weight: 100;
133 | padding: 15px 0 15px 20px; }
134 | .nav-group-name > a {
135 | color: #333; }
136 |
137 | .nav-group-tasks {
138 | margin-top: 5px; }
139 |
140 | .nav-group-task {
141 | font-size: 0.9em;
142 | list-style-type: none;
143 | white-space: nowrap; }
144 | .nav-group-task a {
145 | color: #888; }
146 |
147 | .main-content {
148 | background-color: #fff;
149 | border: 1px solid #e2e2e2;
150 | margin-left: 246px;
151 | position: absolute;
152 | overflow: hidden;
153 | padding-bottom: 60px;
154 | top: 70px;
155 | width: 734px; }
156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote {
157 | margin-bottom: 1em; }
158 | .main-content p {
159 | line-height: 1.8em; }
160 | .main-content section .section:first-child {
161 | margin-top: 0;
162 | padding-top: 0; }
163 | .main-content section .task-group-section .task-group:first-of-type {
164 | padding-top: 10px; }
165 | .main-content section .task-group-section .task-group:first-of-type .section-name {
166 | padding-top: 15px; }
167 |
168 | .section {
169 | padding: 0 25px; }
170 |
171 | .highlight {
172 | background-color: #eee;
173 | padding: 10px 12px;
174 | border: 1px solid #e2e2e2;
175 | border-radius: 4px;
176 | overflow-x: auto; }
177 |
178 | .declaration .highlight {
179 | overflow-x: initial;
180 | padding: 0 40px 40px 0;
181 | margin-bottom: -25px;
182 | background-color: transparent;
183 | border: none; }
184 |
185 | .section-name {
186 | margin: 0;
187 | margin-left: 18px; }
188 |
189 | .task-group-section {
190 | padding-left: 6px;
191 | border-top: 1px solid #e2e2e2; }
192 |
193 | .task-group {
194 | padding-top: 0px; }
195 |
196 | .task-name-container a[name]:before {
197 | content: "";
198 | display: block;
199 | padding-top: 70px;
200 | margin: -70px 0 0; }
201 |
202 | .item {
203 | padding-top: 8px;
204 | width: 100%;
205 | list-style-type: none; }
206 | .item a[name]:before {
207 | content: "";
208 | display: block;
209 | padding-top: 70px;
210 | margin: -70px 0 0; }
211 | .item code {
212 | background-color: transparent;
213 | padding: 0; }
214 | .item .token {
215 | padding-left: 3px;
216 | margin-left: 15px;
217 | font-size: 11.9px; }
218 | .item .declaration-note {
219 | font-size: .85em;
220 | color: gray;
221 | font-style: italic; }
222 |
223 | .pointer-container {
224 | border-bottom: 1px solid #e2e2e2;
225 | left: -23px;
226 | padding-bottom: 13px;
227 | position: relative;
228 | width: 110%; }
229 |
230 | .pointer {
231 | background: #f9f9f9;
232 | border-left: 1px solid #e2e2e2;
233 | border-top: 1px solid #e2e2e2;
234 | height: 12px;
235 | left: 21px;
236 | top: -7px;
237 | -webkit-transform: rotate(45deg);
238 | -moz-transform: rotate(45deg);
239 | -o-transform: rotate(45deg);
240 | transform: rotate(45deg);
241 | position: absolute;
242 | width: 12px; }
243 |
244 | .height-container {
245 | display: none;
246 | left: -25px;
247 | padding: 0 25px;
248 | position: relative;
249 | width: 100%;
250 | overflow: hidden; }
251 | .height-container .section {
252 | background: #f9f9f9;
253 | border-bottom: 1px solid #e2e2e2;
254 | left: -25px;
255 | position: relative;
256 | width: 100%;
257 | padding-top: 10px;
258 | padding-bottom: 5px; }
259 |
260 | .aside, .language {
261 | padding: 6px 12px;
262 | margin: 12px 0;
263 | border-left: 5px solid #dddddd;
264 | overflow-y: hidden; }
265 | .aside .aside-title, .language .aside-title {
266 | font-size: 9px;
267 | letter-spacing: 2px;
268 | text-transform: uppercase;
269 | padding-bottom: 0;
270 | margin: 0;
271 | color: #aaa;
272 | -webkit-user-select: none; }
273 | .aside p:last-child, .language p:last-child {
274 | margin-bottom: 0; }
275 |
276 | .language {
277 | border-left: 5px solid #cde9f4; }
278 | .language .aside-title {
279 | color: #4b8afb; }
280 |
281 | .aside-warning {
282 | border-left: 5px solid #ff6666; }
283 | .aside-warning .aside-title {
284 | color: #ff0000; }
285 |
286 | .graybox {
287 | border-collapse: collapse;
288 | width: 100%; }
289 | .graybox p {
290 | margin: 0;
291 | word-break: break-word;
292 | min-width: 50px; }
293 | .graybox td {
294 | border: 1px solid #e2e2e2;
295 | padding: 5px 25px 5px 10px;
296 | vertical-align: middle; }
297 | .graybox tr td:first-of-type {
298 | text-align: right;
299 | padding: 7px;
300 | vertical-align: top;
301 | word-break: normal;
302 | width: 40px; }
303 |
304 | .slightly-smaller {
305 | font-size: 0.9em; }
306 |
307 | #footer {
308 | position: absolute;
309 | bottom: 10px;
310 | margin-left: 25px; }
311 | #footer p {
312 | margin: 0;
313 | color: #aaa;
314 | font-size: 0.8em; }
315 |
316 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar {
317 | display: none; }
318 | html.dash .main-content {
319 | width: 980px;
320 | margin-left: 0;
321 | border: none;
322 | width: 100%;
323 | top: 0;
324 | padding-bottom: 0; }
325 | html.dash .height-container {
326 | display: block; }
327 | html.dash .item .token {
328 | margin-left: 0; }
329 | html.dash .content-wrapper {
330 | width: auto; }
331 | html.dash #footer {
332 | position: static; }
333 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/css/jazzy.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td {
2 | background: transparent;
3 | border: 0;
4 | margin: 0;
5 | outline: 0;
6 | padding: 0;
7 | vertical-align: baseline; }
8 |
9 | body {
10 | background-color: #f2f2f2;
11 | font-family: Helvetica, freesans, Arial, sans-serif;
12 | font-size: 14px;
13 | -webkit-font-smoothing: subpixel-antialiased;
14 | word-wrap: break-word; }
15 |
16 | h1, h2, h3 {
17 | margin-top: 0.8em;
18 | margin-bottom: 0.3em;
19 | font-weight: 100;
20 | color: black; }
21 |
22 | h1 {
23 | font-size: 2.5em; }
24 |
25 | h2 {
26 | font-size: 2em;
27 | border-bottom: 1px solid #e2e2e2; }
28 |
29 | h4 {
30 | font-size: 13px;
31 | line-height: 1.5;
32 | margin-top: 21px; }
33 |
34 | h5 {
35 | font-size: 1.1em; }
36 |
37 | h6 {
38 | font-size: 1.1em;
39 | color: #777; }
40 |
41 | .section-name {
42 | color: gray;
43 | display: block;
44 | font-family: Helvetica;
45 | font-size: 22px;
46 | font-weight: 100;
47 | margin-bottom: 15px; }
48 |
49 | pre, code {
50 | font: 0.95em Menlo, monospace;
51 | color: #777;
52 | word-wrap: normal; }
53 |
54 | p code, li code {
55 | background-color: #eee;
56 | padding: 2px 4px;
57 | border-radius: 4px; }
58 |
59 | a {
60 | color: #0088cc;
61 | text-decoration: none; }
62 |
63 | ul {
64 | padding-left: 15px; }
65 |
66 | li {
67 | line-height: 1.8em; }
68 |
69 | img {
70 | max-width: 100%; }
71 |
72 | blockquote {
73 | margin-left: 0;
74 | padding: 0 10px;
75 | border-left: 4px solid #ccc; }
76 |
77 | .content-wrapper {
78 | margin: 0 auto;
79 | width: 980px; }
80 |
81 | header {
82 | font-size: 0.85em;
83 | line-height: 26px;
84 | background-color: #414141;
85 | position: fixed;
86 | width: 100%;
87 | z-index: 1; }
88 | header img {
89 | padding-right: 6px;
90 | vertical-align: -4px;
91 | height: 16px; }
92 | header a {
93 | color: #fff; }
94 | header p {
95 | float: left;
96 | color: #999; }
97 | header .header-right {
98 | float: right;
99 | margin-left: 16px; }
100 |
101 | #breadcrumbs {
102 | background-color: #f2f2f2;
103 | height: 27px;
104 | padding-top: 17px;
105 | position: fixed;
106 | width: 100%;
107 | z-index: 1;
108 | margin-top: 26px; }
109 | #breadcrumbs #carat {
110 | height: 10px;
111 | margin: 0 5px; }
112 |
113 | .sidebar {
114 | background-color: #f9f9f9;
115 | border: 1px solid #e2e2e2;
116 | overflow-y: auto;
117 | overflow-x: hidden;
118 | position: fixed;
119 | top: 70px;
120 | bottom: 0;
121 | width: 230px;
122 | word-wrap: normal; }
123 |
124 | .nav-groups {
125 | list-style-type: none;
126 | background: #fff;
127 | padding-left: 0; }
128 |
129 | .nav-group-name {
130 | border-bottom: 1px solid #e2e2e2;
131 | font-size: 1.1em;
132 | font-weight: 100;
133 | padding: 15px 0 15px 20px; }
134 | .nav-group-name > a {
135 | color: #333; }
136 |
137 | .nav-group-tasks {
138 | margin-top: 5px; }
139 |
140 | .nav-group-task {
141 | font-size: 0.9em;
142 | list-style-type: none;
143 | white-space: nowrap; }
144 | .nav-group-task a {
145 | color: #888; }
146 |
147 | .main-content {
148 | background-color: #fff;
149 | border: 1px solid #e2e2e2;
150 | margin-left: 246px;
151 | position: absolute;
152 | overflow: hidden;
153 | padding-bottom: 60px;
154 | top: 70px;
155 | width: 734px; }
156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote {
157 | margin-bottom: 1em; }
158 | .main-content p {
159 | line-height: 1.8em; }
160 | .main-content section .section:first-child {
161 | margin-top: 0;
162 | padding-top: 0; }
163 | .main-content section .task-group-section .task-group:first-of-type {
164 | padding-top: 10px; }
165 | .main-content section .task-group-section .task-group:first-of-type .section-name {
166 | padding-top: 15px; }
167 |
168 | .section {
169 | padding: 0 25px; }
170 |
171 | .highlight {
172 | background-color: #eee;
173 | padding: 10px 12px;
174 | border: 1px solid #e2e2e2;
175 | border-radius: 4px;
176 | overflow-x: auto; }
177 |
178 | .declaration .highlight {
179 | overflow-x: initial;
180 | padding: 0 40px 40px 0;
181 | margin-bottom: -25px;
182 | background-color: transparent;
183 | border: none; }
184 |
185 | .section-name {
186 | margin: 0;
187 | margin-left: 18px; }
188 |
189 | .task-group-section {
190 | padding-left: 6px;
191 | border-top: 1px solid #e2e2e2; }
192 |
193 | .task-group {
194 | padding-top: 0px; }
195 |
196 | .task-name-container a[name]:before {
197 | content: "";
198 | display: block;
199 | padding-top: 70px;
200 | margin: -70px 0 0; }
201 |
202 | .item {
203 | padding-top: 8px;
204 | width: 100%;
205 | list-style-type: none; }
206 | .item a[name]:before {
207 | content: "";
208 | display: block;
209 | padding-top: 70px;
210 | margin: -70px 0 0; }
211 | .item code {
212 | background-color: transparent;
213 | padding: 0; }
214 | .item .token {
215 | padding-left: 3px;
216 | margin-left: 15px;
217 | font-size: 11.9px; }
218 | .item .declaration-note {
219 | font-size: .85em;
220 | color: gray;
221 | font-style: italic; }
222 |
223 | .pointer-container {
224 | border-bottom: 1px solid #e2e2e2;
225 | left: -23px;
226 | padding-bottom: 13px;
227 | position: relative;
228 | width: 110%; }
229 |
230 | .pointer {
231 | background: #f9f9f9;
232 | border-left: 1px solid #e2e2e2;
233 | border-top: 1px solid #e2e2e2;
234 | height: 12px;
235 | left: 21px;
236 | top: -7px;
237 | -webkit-transform: rotate(45deg);
238 | -moz-transform: rotate(45deg);
239 | -o-transform: rotate(45deg);
240 | transform: rotate(45deg);
241 | position: absolute;
242 | width: 12px; }
243 |
244 | .height-container {
245 | display: none;
246 | left: -25px;
247 | padding: 0 25px;
248 | position: relative;
249 | width: 100%;
250 | overflow: hidden; }
251 | .height-container .section {
252 | background: #f9f9f9;
253 | border-bottom: 1px solid #e2e2e2;
254 | left: -25px;
255 | position: relative;
256 | width: 100%;
257 | padding-top: 10px;
258 | padding-bottom: 5px; }
259 |
260 | .aside, .language {
261 | padding: 6px 12px;
262 | margin: 12px 0;
263 | border-left: 5px solid #dddddd;
264 | overflow-y: hidden; }
265 | .aside .aside-title, .language .aside-title {
266 | font-size: 9px;
267 | letter-spacing: 2px;
268 | text-transform: uppercase;
269 | padding-bottom: 0;
270 | margin: 0;
271 | color: #aaa;
272 | -webkit-user-select: none; }
273 | .aside p:last-child, .language p:last-child {
274 | margin-bottom: 0; }
275 |
276 | .language {
277 | border-left: 5px solid #cde9f4; }
278 | .language .aside-title {
279 | color: #4b8afb; }
280 |
281 | .aside-warning {
282 | border-left: 5px solid #ff6666; }
283 | .aside-warning .aside-title {
284 | color: #ff0000; }
285 |
286 | .graybox {
287 | border-collapse: collapse;
288 | width: 100%; }
289 | .graybox p {
290 | margin: 0;
291 | word-break: break-word;
292 | min-width: 50px; }
293 | .graybox td {
294 | border: 1px solid #e2e2e2;
295 | padding: 5px 25px 5px 10px;
296 | vertical-align: middle; }
297 | .graybox tr td:first-of-type {
298 | text-align: right;
299 | padding: 7px;
300 | vertical-align: top;
301 | word-break: normal;
302 | width: 40px; }
303 |
304 | .slightly-smaller {
305 | font-size: 0.9em; }
306 |
307 | #footer {
308 | position: absolute;
309 | bottom: 10px;
310 | margin-left: 25px; }
311 | #footer p {
312 | margin: 0;
313 | color: #aaa;
314 | font-size: 0.8em; }
315 |
316 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar {
317 | display: none; }
318 | html.dash .main-content {
319 | width: 980px;
320 | margin-left: 0;
321 | border: none;
322 | width: 100%;
323 | top: 0;
324 | padding-bottom: 0; }
325 | html.dash .height-container {
326 | display: block; }
327 | html.dash .item .token {
328 | margin-left: 0; }
329 | html.dash .content-wrapper {
330 | width: auto; }
331 | html.dash #footer {
332 | position: static; }
333 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Sources/PerfectSQLite/SQLiteCRUD.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SQLiteCRUD.swift
3 | //
4 | // Created by Kyle Jessup on 2017-11-28.
5 | //
6 |
7 | import Foundation
8 | import PerfectCRUD
9 | // Apple platforms have SQLite3 built-in. Linux? No.
10 | #if os(Linux)
11 | import PerfectCSQLite3
12 | #else
13 | import SQLite3
14 | #endif
15 |
16 | public struct SQLiteCRUDError: Error, CustomStringConvertible {
17 | public let description: String
18 | init(_ m: String) {
19 | description = m
20 | CRUDLogging.log(.error, m)
21 | }
22 | }
23 |
24 | // maps column name to position which must be computed once before row reading action
25 | typealias SQLiteCRUDColumnMap = [String:Int]
26 |
27 | class SQLiteCRUDRowReader: KeyedDecodingContainerProtocol {
28 | typealias Key = K
29 | var codingPath: [CodingKey] = []
30 | var allKeys: [Key] = []
31 | let database: SQLite
32 | let statement: SQLiteStmt
33 | let columns: SQLiteCRUDColumnMap
34 | // the SQLiteStmt has been successfully step()ed to the next row
35 | init(_ db: SQLite, stat: SQLiteStmt, columns cols: SQLiteCRUDColumnMap) {
36 | database = db
37 | statement = stat
38 | columns = cols
39 | }
40 | func columnPosition(_ key: Key) throws -> Int {
41 | guard let pos = columns[key.stringValue] else {
42 | throw CRUDDecoderError("Unrecognized key: \(key.stringValue)")
43 | }
44 | return pos
45 | }
46 | func contains(_ key: Key) -> Bool {
47 | return nil != columns[key.stringValue]
48 | }
49 | func decodeNil(forKey key: Key) throws -> Bool {
50 | return statement.isNull(position: try columnPosition(key))
51 | }
52 | func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool {
53 | return statement.columnInt(position: try columnPosition(key)) == 1
54 | }
55 | func decode(_ type: Int.Type, forKey key: Key) throws -> Int {
56 | return statement.columnInt(position: try columnPosition(key))
57 | }
58 | func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 {
59 | return type.init(statement.columnInt(position: try columnPosition(key)))
60 | }
61 | func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 {
62 | return type.init(statement.columnInt(position: try columnPosition(key)))
63 | }
64 | func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 {
65 | return statement.columnInt32(position: try columnPosition(key))
66 | }
67 | func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 {
68 | return statement.columnInt64(position: try columnPosition(key))
69 | }
70 | func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt {
71 | return type.init(statement.columnInt(position: try columnPosition(key)))
72 | }
73 | func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 {
74 | return type.init(statement.columnInt(position: try columnPosition(key)))
75 | }
76 | func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 {
77 | return type.init(statement.columnInt(position: try columnPosition(key)))
78 | }
79 | func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 {
80 | return type.init(statement.columnInt(position: try columnPosition(key)))
81 | }
82 | func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 {
83 | return type.init(statement.columnInt(position: try columnPosition(key)))
84 | }
85 | func decode(_ type: Float.Type, forKey key: Key) throws -> Float {
86 | return type.init(statement.columnDouble(position: try columnPosition(key)))
87 | }
88 | func decode(_ type: Double.Type, forKey key: Key) throws -> Double {
89 | return statement.columnDouble(position: try columnPosition(key))
90 | }
91 | func decode(_ type: String.Type, forKey key: Key) throws -> String {
92 | return statement.columnText(position: try columnPosition(key))
93 | }
94 | func decode(_ type: T.Type, forKey key: Key) throws -> T where T : Decodable {
95 | let position = try columnPosition(key)
96 | guard let special = SpecialType(type) else {
97 | throw CRUDDecoderError("Unsupported type: \(type) for key: \(key.stringValue)")
98 | }
99 | switch special {
100 | case .uint8Array:
101 | let ret: [UInt8] = statement.columnIntBlob(position: position)
102 | return ret as! T
103 | case .int8Array:
104 | let ret: [Int8] = statement.columnIntBlob(position: position)
105 | return ret as! T
106 | case .data:
107 | let bytes: [UInt8] = statement.columnIntBlob(position: position)
108 | return Data(bytes) as! T
109 | case .uuid:
110 | let str = statement.columnText(position: position)
111 | guard let uuid = UUID(uuidString: str) else {
112 | throw CRUDDecoderError("Invalid UUID string \(str).")
113 | }
114 | return uuid as! T
115 | case .date:
116 | let str = statement.columnText(position: position)
117 | guard let date = Date(fromISO8601: str) else {
118 | throw CRUDDecoderError("Invalid Date string \(str).")
119 | }
120 | return date as! T
121 | case .url:
122 | let str = statement.columnText(position: position)
123 | guard let url = URL(string: str) else {
124 | throw CRUDDecoderError("Invalid URL string \(str).")
125 | }
126 | return url as! T
127 | case .codable:
128 | guard let data = statement.columnText(position: position).data(using: .utf8) else {
129 | throw CRUDDecoderError("Unsupported type: \(type) for key: \(key.stringValue)")
130 | }
131 | return try JSONDecoder().decode(type, from: data)
132 | case .wrapped:
133 | let decoder = CRUDColumnValueDecoder(source: KeyedDecodingContainer(self), key: key)
134 | return try T(from: decoder)
135 | }
136 | }
137 | func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer where NestedKey : CodingKey {
138 | throw CRUDDecoderError("Unimplimented nestedContainer")
139 | }
140 | func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer {
141 | throw CRUDDecoderError("Unimplimented nestedUnkeyedContainer")
142 | }
143 | func superDecoder() throws -> Decoder {
144 | throw CRUDDecoderError("Unimplimented superDecoder")
145 | }
146 | func superDecoder(forKey key: Key) throws -> Decoder {
147 | throw CRUDDecoderError("Unimplimented superDecoder")
148 | }
149 | }
150 |
151 | struct SQLiteColumnInfo: Codable {
152 | let cid: Int
153 | let name: String
154 | let type: String
155 | let notnull: Int
156 | let dflt_value: String
157 | let pk: Bool
158 | }
159 |
160 | class SQLiteGenDelegate: SQLGenDelegate {
161 | let database: SQLite
162 | var parentTableStack: [TableStructure] = []
163 | var bindings: Bindings = []
164 | var extraCreate: [String] = []
165 |
166 | init(_ db: SQLite) {
167 | database = db
168 | }
169 |
170 | func getCreateIndexSQL(forTable name: String, on columns: [String], unique: Bool) throws -> [String] {
171 | let stat =
172 | """
173 | CREATE \(unique ? "UNIQUE " : "")INDEX IF NOT EXISTS \(try quote(identifier: "index_\(columns.joined(separator: "_"))"))
174 | ON \(try quote(identifier: name)) (\(try columns.map{try quote(identifier: $0)}.joined(separator: ",")))
175 | """
176 | return [stat]
177 | }
178 |
179 | func getCreateTableSQL(forTable: TableStructure, policy: TableCreatePolicy) throws -> [String] {
180 | parentTableStack.append(forTable)
181 | defer {
182 | parentTableStack.removeLast()
183 | }
184 | var sub: [String] = []
185 | if policy.contains(.dropTable) {
186 | sub += ["DROP TABLE IF EXISTS \(try quote(identifier: forTable.tableName))"]
187 | }
188 | if !policy.contains(.dropTable),
189 | policy.contains(.reconcileTable),
190 | let existingColumns = getExistingColumnData(forTable: forTable.tableName),
191 | !existingColumns.isEmpty {
192 | let existingColumnMap: [String:SQLiteColumnInfo] = .init(uniqueKeysWithValues: existingColumns.map { ($0.name, $0) })
193 | let newColumnMap: [String:TableStructure.Column] = .init(uniqueKeysWithValues: forTable.columns.map { ($0.name, $0) })
194 |
195 | let addColumns = newColumnMap.keys.filter { existingColumnMap[$0] == nil }
196 | let removeColumns: [String] = existingColumnMap.keys.filter { newColumnMap[$0] == nil }
197 |
198 | if !removeColumns.isEmpty {
199 | let nameQ = try quote(identifier: forTable.tableName)
200 | let tempNameQ = try quote(identifier: "temp_\(forTable.tableName)_temp")
201 | let sharedColumns = existingColumns.map { $0.name }.filter { !removeColumns.contains($0) }
202 | sub += [ // sqlite does not have 'drop column'
203 | "ALTER TABLE \(nameQ) RENAME TO \(tempNameQ)",
204 | """
205 | CREATE TABLE IF NOT EXISTS \(nameQ) (
206 | \(try forTable.columns.map { try getColumnDefinition($0) }.joined(separator: ",\n\t"))
207 | )
208 | """,
209 | """
210 | INSERT INTO \(nameQ) (\(sharedColumns.joined(separator: ",")))
211 | SELECT \(sharedColumns.joined(separator: ","))
212 | FROM \(tempNameQ)
213 | """,
214 | "DROP TABLE \(tempNameQ)"
215 | ]
216 | } else {
217 | sub += try addColumns.compactMap { newColumnMap[$0] }.map {
218 | let nameType = try getColumnDefinition($0)
219 | return """
220 | ALTER TABLE \(try quote(identifier: forTable.tableName)) ADD COLUMN \(nameType)
221 | """
222 | }
223 | }
224 | return sub
225 | } else {
226 | sub += [
227 | """
228 | CREATE TABLE IF NOT EXISTS \(try quote(identifier: forTable.tableName)) (
229 | \((try forTable.columns.map { try getColumnDefinition($0) } + extraCreate).joined(separator: ",\n\t"))
230 | )
231 | """]
232 | }
233 | if !policy.contains(.shallow) {
234 | sub += try forTable.subTables.flatMap {
235 | try getCreateTableSQL(forTable: $0, policy: policy)
236 | }
237 | }
238 | return sub
239 | }
240 |
241 | func getExistingColumnData(forTable: String) -> [SQLiteColumnInfo]? {
242 | do {
243 | let prep = try database.prepare(statement: "PRAGMA table_info(\"\(forTable)\")")
244 | let exeDelegate = SQLiteExeDelegate(database, stat: prep)
245 | var ret: [SQLiteColumnInfo] = []
246 | while try exeDelegate.hasNext() {
247 | let rowDecoder = CRUDRowDecoder(delegate: exeDelegate)
248 | ret.append(try SQLiteColumnInfo(from: rowDecoder))
249 | }
250 | return ret
251 | } catch {
252 | return nil
253 | }
254 | }
255 | private func getTypeName(_ type: Any.Type) throws -> String {
256 | let typeName: String
257 | switch type {
258 | case is Int.Type:
259 | typeName = "INT"
260 | case is Int8.Type:
261 | typeName = "INT"
262 | case is Int16.Type:
263 | typeName = "INT"
264 | case is Int32.Type:
265 | typeName = "INT"
266 | case is Int64.Type:
267 | typeName = "INT"
268 | case is UInt.Type:
269 | typeName = "INT"
270 | case is UInt8.Type:
271 | typeName = "INT"
272 | case is UInt16.Type:
273 | typeName = "INT"
274 | case is UInt32.Type:
275 | typeName = "INT"
276 | case is UInt64.Type:
277 | typeName = "INT"
278 | case is Double.Type:
279 | typeName = "REAL"
280 | case is Float.Type:
281 | typeName = "REAL"
282 | case is Bool.Type:
283 | typeName = "INT"
284 | case is String.Type:
285 | typeName = "TEXT"
286 | default:
287 | guard let special = SpecialType(type) else {
288 | throw SQLiteCRUDError("Unsupported SQL column type \(type)")
289 | }
290 | switch special {
291 | case .uint8Array:
292 | typeName = "BLOB"
293 | case .int8Array:
294 | typeName = "BLOB"
295 | case .data:
296 | typeName = "BLOB"
297 | case .uuid:
298 | typeName = "TEXT"
299 | case .date:
300 | typeName = "TEXT"
301 | case .url:
302 | typeName = "TEXT"
303 | case .codable:
304 | typeName = "TEXT"
305 | case .wrapped:
306 | guard let w = type as? WrappedCodableProvider.Type else {
307 | throw SQLiteCRUDError("Unsupported SQL column type \(type)")
308 | }
309 | return try getTypeName(w)
310 | }
311 | }
312 | return typeName
313 | }
314 | func getColumnDefinition(_ column: TableStructure.Column) throws -> String {
315 | let name = column.name
316 | let type = column.type
317 | let typeName = try getTypeName(type)
318 | var addendum = ""
319 | for prop in column.properties {
320 | switch prop {
321 | case .primaryKey:
322 | addendum += " PRIMARY KEY"
323 | case .foreignKey(let table, let column, let onDelete, let onUpdate):
324 | var str = "FOREIGN KEY(\(name)) REFERENCES \(table)(\(column))"
325 | let scenarios = [(" ON DELETE ", onDelete), (" ON UPDATE ", onUpdate)]
326 | for (scenario, action) in scenarios {
327 | str += scenario
328 | switch action {
329 | case .ignore:
330 | str += "NO ACTION"
331 | case .restrict:
332 | str += "RESTRICT"
333 | case .setNull:
334 | str += "SET NULL"
335 | case .setDefault:
336 | str += "SET DEFAULT"
337 | case .cascade:
338 | str += "CASCADE"
339 | }
340 | }
341 | extraCreate.append(str)
342 | }
343 | }
344 | if !column.properties.contains(.primaryKey) && !column.optional {
345 | addendum += " NOT NULL"
346 | }
347 | return "\(name) \(typeName)\(addendum)"
348 | }
349 | func getBinding(for expr: Expression) throws -> String {
350 | bindings.append(("?", expr))
351 | return "?"
352 | }
353 | func quote(identifier: String) throws -> String {
354 | return "\"\(identifier)\""
355 | }
356 | }
357 |
358 | // maps column name to position which must be computed once before row reading action
359 | typealias SQLiteColumnMap = [String:Int]
360 |
361 | class SQLiteExeDelegate: SQLExeDelegate {
362 | let database: SQLite
363 | let statement: SQLiteStmt
364 | let columnMap: SQLiteColumnMap
365 | init(_ db: SQLite, stat: SQLiteStmt) {
366 | database = db
367 | statement = stat
368 | var m = SQLiteColumnMap()
369 | let count = statement.columnCount()
370 | for i in 0.. Bool {
386 | let step = statement.step()
387 | guard step == SQLITE_ROW || step == SQLITE_DONE else {
388 | throw SQLiteCRUDError(database.errMsg())
389 | }
390 | return step == SQLITE_ROW
391 | }
392 | func next() -> KeyedDecodingContainer ? where A : CodingKey {
393 | return KeyedDecodingContainer(SQLiteCRUDRowReader (database, stat: statement, columns: columnMap))
394 | }
395 | private func bindOne(position: Int, expr: CRUDExpression) throws {
396 | switch expr {
397 | case .lazy(let e):
398 | try bindOne(position: position, expr: e())
399 | case .decimal(let d):
400 | try statement.bind(position: position, d)
401 | case .string(let s):
402 | try statement.bind(position: position, s)
403 | case .blob(let b):
404 | try statement.bind(position: position, b)
405 | case .bool(let b):
406 | try statement.bind(position: position, b ? 1 : 0)
407 | case .null:
408 | try statement.bindNull(position: position)
409 | case .date(let d):
410 | try statement.bind(position: position, d.iso8601())
411 | case .url(let u):
412 | try statement.bind(position: position, u.absoluteString)
413 | case .uuid(let u):
414 | try statement.bind(position: position, u.uuidString)
415 | case .column(_), .and(_, _), .or(_, _),
416 | .equality(_, _), .inequality(_, _),
417 | .not(_), .lessThan(_, _), .lessThanEqual(_, _),
418 | .greaterThan(_, _), .greaterThanEqual(_, _),
419 | .keyPath(_), .in(_, _), .like(_, _, _, _):
420 | throw SQLiteCRUDError("Asked to bind unsupported expression type: \(expr)")
421 | case .integer(let i):
422 | try statement.bind(position: position, i)
423 | case .uinteger(let i):
424 | try statement.bind(position: position, Int(i))
425 | case .integer64(let i):
426 | try statement.bind(position: position, Int(i))
427 | case .uinteger64(let i):
428 | try statement.bind(position: position, Int(i))
429 | case .integer32(let i):
430 | try statement.bind(position: position, Int(i))
431 | case .uinteger32(let i):
432 | try statement.bind(position: position, Int(i))
433 | case .integer16(let i):
434 | try statement.bind(position: position, Int(i))
435 | case .uinteger16(let i):
436 | try statement.bind(position: position, Int(i))
437 | case .integer8(let i):
438 | try statement.bind(position: position, Int(i))
439 | case .uinteger8(let i):
440 | try statement.bind(position: position, Int(i))
441 | case .float(let d):
442 | try statement.bind(position: position, Double(d))
443 | case .sblob(let b):
444 | try statement.bind(position: position, b.map{UInt8(bitPattern: $0)})
445 | }
446 | }
447 | }
448 |
449 | public struct SQLiteDatabaseConfiguration: DatabaseConfigurationProtocol {
450 | public var sqlGenDelegate: SQLGenDelegate {
451 | return SQLiteGenDelegate(sqlite)
452 | }
453 | public func sqlExeDelegate(forSQL sql: String) throws -> SQLExeDelegate {
454 | let prep = try sqlite.prepare(statement: sql)
455 | return SQLiteExeDelegate(sqlite, stat: prep)
456 | }
457 | public let name: String
458 | public let sqlite: SQLite
459 | public init(_ n: String, _ pragmas: [String] = ["PRAGMA foreign_keys = ON"]) throws {
460 | name = n
461 | sqlite = try SQLite(n)
462 | for pragma in pragmas {
463 | try sqlite.execute(statement: pragma)
464 | }
465 | }
466 | public init(url: String?,
467 | name: String?,
468 | host: String?,
469 | port: Int?,
470 | user: String?,
471 | pass: String?) throws {
472 | guard let n = name else {
473 | throw SQLiteCRUDError("Database name must be provided.")
474 | }
475 | try self.init(n)
476 | }
477 | }
478 |
479 | public extension Insert {
480 | func lastInsertId() throws -> Int? {
481 | let exeDelegate = try databaseConfiguration.sqlExeDelegate(forSQL: "SELECT last_insert_rowid()")
482 | guard try exeDelegate.hasNext(), let next: KeyedDecodingContainer = try exeDelegate.next() else {
483 | throw CRUDSQLGenError("Did not get return value from statement \"SELECT last_insert_rowid()\".")
484 | }
485 | let value = try next.decode(Int.self, forKey: ColumnKey(stringValue: "last_insert_rowid()")!)
486 | return value
487 | }
488 | }
489 |
--------------------------------------------------------------------------------
/Sources/PerfectSQLite/SQLite.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SQLite.swift
3 | // PerfectLib
4 | //
5 | // Created by Kyle Jessup on 7/14/15.
6 | // Copyright (C) 2015 PerfectlySoft, Inc.
7 | //
8 | //===----------------------------------------------------------------------===//
9 | //
10 | // This source file is part of the Perfect.org open source project
11 | //
12 | // Copyright (c) 2015 - 2016 PerfectlySoft Inc. and the Perfect project authors
13 | // Licensed under Apache License v2.0
14 | //
15 | // See http://perfect.org/licensing.html for license information
16 | //
17 | //===----------------------------------------------------------------------===//
18 | //
19 |
20 | // Apple platforms have SQLite3 built-in. Linux? No.
21 | #if os(Linux)
22 | import PerfectCSQLite3
23 | import SwiftGlibc
24 | #else
25 | import SQLite3
26 | #endif
27 |
28 | /// This enum type indicates an exception when dealing with a SQLite database
29 | public struct SQLiteError : Error, CustomStringConvertible {
30 | public let code: Int
31 | public let description: String
32 | public init(code: Int, description: String) {
33 | self.code = code
34 | self.description = description
35 | }
36 | }
37 |
38 | /// A SQLite database
39 | public class SQLite {
40 |
41 | let path: String
42 | var sqlite3 = OpaquePointer(bitPattern: 0)
43 |
44 | /// Create or open a SQLite database given a file path.
45 | ///
46 | /// - parameter path: String path to SQLite database
47 | /// - parameter readOnly: Optional, Bool flag for read/write setting, defaults to false
48 | /// - throws: SQLiteError
49 | public init(_ path: String, readOnly: Bool = false, busyTimeoutMillis: Int = 600000) throws {
50 | self.path = path
51 | let flags = readOnly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE
52 | let res = sqlite3_open_v2(path, &self.sqlite3, flags, nil)
53 | if res != SQLITE_OK {
54 | throw SQLiteError(code: Int(res), description: "Unable to open database "+path)
55 | }
56 | sqlite3_busy_timeout(self.sqlite3, Int32(busyTimeoutMillis))
57 | }
58 |
59 | /// Close the SQLite database.
60 | public func close() {
61 | if self.sqlite3 != nil {
62 | sqlite3_close(self.sqlite3)
63 | self.sqlite3 = nil
64 | }
65 | }
66 |
67 | /// Close the SQLite database.
68 | public func close(after: (SQLite) -> T) -> T {
69 | defer {
70 | close()
71 | }
72 | return after(self)
73 | }
74 |
75 | deinit {
76 | close()
77 | }
78 |
79 | /// Compile the SQL statement.
80 | ///
81 | /// - returns: A SQLiteStmt object representing the compiled statement.
82 | public func prepare(statement stat: String) throws -> SQLiteStmt {
83 | var statPtr = OpaquePointer(bitPattern: 0)
84 | let tail = UnsafeMutablePointer?>(nil as OpaquePointer?)
85 | let res = sqlite3_prepare_v2(self.sqlite3, stat, Int32(stat.utf8.count), &statPtr, tail)
86 | try checkRes(res)
87 | return SQLiteStmt(db: self.sqlite3, stat: statPtr)
88 | }
89 |
90 | /// Returns the value of `sqlite3_last_insert_rowid`.
91 | ///
92 | /// - returns: Int last inserted row ID
93 | public func lastInsertRowID() -> Int {
94 | let res = sqlite3_last_insert_rowid(self.sqlite3)
95 | return Int(res)
96 | }
97 |
98 | /// Returns the value of `sqlite3_total_changes`.
99 | ///
100 | /// - returns: Int total changes
101 | public func totalChanges() -> Int {
102 | let res = sqlite3_total_changes(self.sqlite3)
103 | return Int(res)
104 | }
105 |
106 | /// Returns the value of `sqlite3_changes`.
107 | ///
108 | /// - returns: Int number of changes
109 | public func changes() -> Int {
110 | let res = sqlite3_changes(self.sqlite3)
111 | return Int(res)
112 | }
113 |
114 | /// Returns the value of `sqlite3_errcode`.
115 | ///
116 | /// - returns: Int error code
117 | public func errCode() -> Int {
118 | let res = sqlite3_errcode(self.sqlite3)
119 | return Int(res)
120 | }
121 |
122 | /// Returns the value of `sqlite3_errmsg`.
123 | ///
124 | /// - returns: String error message
125 | public func errMsg() -> String {
126 | return String(validatingUTF8: sqlite3_errmsg(self.sqlite3))!
127 | }
128 |
129 | /// Execute the given statement. Assumes there will be no parameter binding or resulting row data.
130 | ///
131 | /// - parameter statement: String statement to be executed
132 | /// - throws: ()
133 | public func execute(statement: String) throws {
134 | try forEachRow(statement: statement, doBindings: { (SQLiteStmt) throws -> () in () }) {
135 | _, _ in
136 | // nothing
137 | }
138 | }
139 |
140 | /// Execute the given statement. Calls the provided callback one time for parameter binding. Assumes there will be no resulting row data.
141 | ///
142 | /// - parameter statement: String statement to be executed
143 | /// - parameter doBindings: Block used for bindings
144 | /// - throws: ()
145 | public func execute(statement: String, doBindings: (SQLiteStmt) throws -> ()) throws {
146 | try forEachRow(statement: statement, doBindings: doBindings) {
147 | _, _ in
148 | // nothing
149 | }
150 | }
151 |
152 | /// Execute the given statement `count` times. Calls the provided callback on each execution for parameter binding. Assumes there will be no resulting row data.
153 | ///
154 | /// - parameter statement: String statement to be executed
155 | /// - parameter count: Int number of times to execute
156 | /// - parameter doBindings: Block to be executed for binding on each call
157 | /// - throws: ()
158 | public func execute(statement: String, count: Int, doBindings: (SQLiteStmt, Int) throws -> ()) throws {
159 | let stat = try prepare(statement: statement)
160 | defer { stat.finalize() }
161 |
162 | for idx in 1...count {
163 | try doBindings(stat, idx)
164 | try forEachRowBody(stat: stat) {
165 | _, _ in
166 | // nothing
167 | }
168 | let _ = try stat.reset()
169 | }
170 | }
171 |
172 | /// Executes a BEGIN, calls the provided closure and executes a ROLLBACK if an exception occurs or a COMMIT if no exception occurs.
173 | ///
174 | /// - parameter closure: Block to be executed inside transaction
175 | /// - throws: ErrorType
176 | public func doWithTransaction(closure: () throws -> ()) throws {
177 | try execute(statement: "BEGIN")
178 | do {
179 | try closure()
180 | try execute(statement: "COMMIT")
181 | } catch let e {
182 | try execute(statement: "ROLLBACK")
183 | throw e
184 | }
185 | }
186 |
187 | /// Executes the statement and calls the closure for each resulting row.
188 | ///
189 | /// - parameter statement: String statement to be executed
190 | /// - parameter handleRow: Block to be executed for each row
191 | /// - throws: ()
192 | public func forEachRow(statement: String, handleRow: (SQLiteStmt, Int) throws -> ()) throws {
193 | let stat = try prepare(statement: statement)
194 | defer { stat.finalize() }
195 |
196 | try forEachRowBody(stat: stat, handleRow: handleRow)
197 | }
198 |
199 | /// Executes the statement, calling `doBindings` to handle parameter bindings and calling `handleRow` for each resulting row.
200 | ///
201 | /// - parameter statement: String statement to be executed
202 | /// - parameter doBindings: Block to perform bindings on statement
203 | /// - parameter handleRow: Block to execute for each row
204 | /// - throws: ()
205 | public func forEachRow(statement: String, doBindings: (SQLiteStmt) throws -> (), handleRow: (SQLiteStmt, Int) throws -> ()) throws {
206 | let stat = try prepare(statement: statement)
207 | defer { stat.finalize() }
208 |
209 | try doBindings(stat)
210 |
211 | try forEachRowBody(stat: stat, handleRow: handleRow)
212 | }
213 |
214 | func forEachRowBody(stat: SQLiteStmt, handleRow: (SQLiteStmt, Int) throws -> ()) throws {
215 | var r = stat.step()
216 | guard r == SQLITE_ROW || r == SQLITE_DONE else {
217 | try checkRes(r)
218 | return
219 | }
220 |
221 | var rowNum = 1
222 | while r == SQLITE_ROW {
223 | try handleRow(stat, rowNum)
224 | rowNum += 1
225 | r = stat.step()
226 | }
227 | }
228 |
229 | func miniSleep(millis: Int) {
230 | var tv = timeval()
231 | tv.tv_sec = millis / 1000
232 | #if os(Linux)
233 | tv.tv_usec = Int((millis % 1000) * 1000)
234 | #else
235 | tv.tv_usec = Int32((millis % 1000) * 1000)
236 | #endif
237 | select(0, nil, nil, nil, &tv)
238 | }
239 |
240 | func checkRes(_ res: Int32) throws {
241 | try checkRes(Int(res))
242 | }
243 |
244 | func checkRes(_ res: Int) throws {
245 | if res != Int(SQLITE_OK) {
246 | throw SQLiteError(code: res, description: String(validatingUTF8: sqlite3_errmsg(self.sqlite3))!)
247 | }
248 | }
249 | }
250 |
251 | /// A compiled SQLite statement
252 | public class SQLiteStmt {
253 |
254 | let db: OpaquePointer?
255 | var stat: OpaquePointer?
256 |
257 | typealias sqlite_destructor = @convention(c) (UnsafeMutableRawPointer?) -> Void
258 |
259 | init(db: OpaquePointer?, stat: OpaquePointer?) {
260 | self.db = db
261 | self.stat = stat
262 | }
263 |
264 | /// Close or "finalize" the statement.
265 | public func close() {
266 | finalize()
267 | }
268 |
269 | /// Close the statement.
270 | public func finalize() {
271 | if self.stat != nil {
272 | sqlite3_finalize(self.stat!)
273 | self.stat = nil
274 | }
275 | }
276 |
277 | /// Advance to the next row.
278 | public func step() -> Int32 {
279 | guard self.stat != nil else {
280 | return SQLITE_MISUSE
281 | }
282 | return sqlite3_step(self.stat!)
283 | }
284 |
285 | /// Bind the Double value to the indicated parameter.
286 | ///
287 | /// - parameter position: Int position of binding
288 | /// - parameter d: Double to be bound
289 | /// - throws: ()
290 | public func bind(position: Int, _ d: Double) throws {
291 | try checkRes(sqlite3_bind_double(self.stat!, Int32(position), d))
292 | }
293 |
294 | /// Bind the Int32 value to the indicated parameter.
295 | ///
296 | /// - parameter position: Int position of binding
297 | /// - parameter i: Int32 to be bound
298 | /// - throws: ()
299 | public func bind(position: Int, _ i: Int32) throws {
300 | try checkRes(sqlite3_bind_int(self.stat!, Int32(position), Int32(i)))
301 | }
302 |
303 | /// Bind the Int value to the indicated parameter.
304 | ///
305 | /// - parameter position: Int position of binding
306 | /// - parameter i: Int to be bound
307 | /// - throws: ()
308 | public func bind(position: Int, _ i: Int) throws {
309 | try checkRes(sqlite3_bind_int64(self.stat!, Int32(position), Int64(i)))
310 | }
311 |
312 | /// Bind the Int64 value to the indicated parameter.
313 | ///
314 | /// - parameter position: Int position of binding
315 | /// - parameter i: Int64 to be bound
316 | /// - throws: ()
317 | public func bind(position: Int, _ i: Int64) throws {
318 | try checkRes(sqlite3_bind_int64(self.stat!, Int32(position), i))
319 | }
320 |
321 | /// Bind the String value to the indicated parameter.
322 | ///
323 | /// - parameter position: Int position of binding
324 | /// - parameter s: String to be bound
325 | /// - throws: ()
326 | public func bind(position: Int, _ s: String) throws {
327 | try checkRes(sqlite3_bind_text(self.stat!, Int32(position), s, Int32(s.utf8.count), unsafeBitCast(OpaquePointer(bitPattern: -1), to: sqlite_destructor.self)))
328 | }
329 |
330 | /// Bind the [Int8] blob value to the indicated parameter.
331 | ///
332 | /// - parameter position: Int position of binding
333 | /// - parameter b: [Int8] blob to be bound
334 | /// - throws: ()
335 | public func bind(position: Int, _ b: [Int8]) throws {
336 | try checkRes(sqlite3_bind_blob(self.stat!, Int32(position), b, Int32(b.count), unsafeBitCast(OpaquePointer(bitPattern: -1), to: sqlite_destructor.self)))
337 | }
338 |
339 | /// Bind the [UInt8] blob value to the indicated parameter.
340 | ///
341 | /// - parameter position: Int position of binding
342 | /// - parameter b: [UInt8] blob to be bound
343 | /// - throws: ()
344 | public func bind(position: Int, _ b: [UInt8]) throws {
345 | try checkRes(sqlite3_bind_blob(self.stat!, Int32(position), b, Int32(b.count), unsafeBitCast(OpaquePointer(bitPattern: -1), to: sqlite_destructor.self)))
346 | }
347 |
348 | /// Bind a blob of `count` zero values to the indicated parameter.
349 | ///
350 | /// - parameter position: Int position of binding
351 | /// - parameter count: Int number of zero values in blob to be bound
352 | /// - throws: ()
353 | public func bindZeroBlob(position: Int, count: Int) throws {
354 | try checkRes(sqlite3_bind_zeroblob(self.stat!, Int32(position), Int32(count)))
355 | }
356 |
357 | /// Bind a null to the indicated parameter.
358 | ///
359 | /// - parameter position: Int position of binding
360 | /// - throws: ()
361 | public func bindNull(position: Int) throws {
362 | try checkRes(sqlite3_bind_null(self.stat!, Int32(position)))
363 | }
364 |
365 | /// Bind the Double value to the indicated parameter.
366 | ///
367 | /// - parameter name: String name of binding
368 | /// - parameter d: Double to be bound
369 | /// - throws: ()
370 | public func bind(name: String, _ d: Double) throws {
371 | try checkRes(sqlite3_bind_double(self.stat!, Int32(bindParameterIndex(name: name)), d))
372 | }
373 |
374 | /// Bind the Int32 value to the indicated parameter.
375 | ///
376 | /// - parameter name: String name of binding
377 | /// - parameter i: Int32 to be bound
378 | /// - throws: ()
379 | public func bind(name: String, _ i: Int32) throws {
380 | try checkRes(sqlite3_bind_int(self.stat!, Int32(bindParameterIndex(name: name)), Int32(i)))
381 | }
382 |
383 | /// Bind the Int value to the indicated parameter.
384 | ///
385 | /// - parameter name: String name of binding
386 | /// - parameter i: Int to be bound
387 | /// - throws: ()
388 | public func bind(name: String, _ i: Int) throws {
389 | try checkRes(sqlite3_bind_int64(self.stat!, Int32(bindParameterIndex(name: name)), Int64(i)))
390 | }
391 |
392 | /// Bind the Int64 value to the indicated parameter.
393 | ///
394 | /// - parameter name: String name of binding
395 | /// - parameter i: Int64 to be bound
396 | /// - throws: ()
397 | public func bind(name: String, _ i: Int64) throws {
398 | try checkRes(sqlite3_bind_int64(self.stat!, Int32(bindParameterIndex(name: name)), i))
399 | }
400 |
401 | /// Bind the String value to the indicated parameter.
402 | ///
403 | /// - parameter name: String name of binding
404 | /// - parameter s: String to be bound
405 | /// - throws: ()
406 | public func bind(name: String, _ s: String) throws {
407 | try checkRes(sqlite3_bind_text(self.stat!, Int32(bindParameterIndex(name: name)), s, Int32(s.utf8.count), unsafeBitCast(OpaquePointer(bitPattern: -1), to: sqlite_destructor.self)))
408 | }
409 |
410 | /// Bind the [Int8] blob value to the indicated parameter.
411 | ///
412 | /// - parameter name: String name of binding
413 | /// - parameter b: [Int8] blob to be bound
414 | /// - throws: ()
415 | public func bind(name: String, _ b: [Int8]) throws {
416 | try checkRes(sqlite3_bind_text(self.stat!, Int32(bindParameterIndex(name: name)), b, Int32(b.count), unsafeBitCast(OpaquePointer(bitPattern: -1), to: sqlite_destructor.self)))
417 | }
418 |
419 | /// Bind a blob of `count` zero values to the indicated parameter.
420 | ///
421 | /// - parameter name: String name of binding
422 | /// - parameter count: Int number of zero values in blob to be bound
423 | /// - throws: ()
424 | public func bindZeroBlob(name: String, count: Int) throws {
425 | try checkRes(sqlite3_bind_zeroblob(self.stat!, Int32(bindParameterIndex(name: name)), Int32(count)))
426 | }
427 |
428 | /// Bind a null to the indicated parameter.
429 | ///
430 | /// - parameter name: String name of binding
431 | /// - throws: ()
432 | public func bindNull(name: String) throws {
433 | try checkRes(sqlite3_bind_null(self.stat!, Int32(bindParameterIndex(name: name))))
434 | }
435 |
436 | /// Returns the index for the named parameter.
437 | ///
438 | /// - parameter name: String name of binding
439 | /// - throws: ()
440 | /// - returns: Int index of parameter
441 | public func bindParameterIndex(name: String) throws -> Int {
442 | let idx = sqlite3_bind_parameter_index(self.stat!, name)
443 | guard idx != 0 else {
444 | throw SQLiteError(code: Int(SQLITE_MISUSE), description: "The indicated bind parameter name was not found.")
445 | }
446 | return Int(idx)
447 | }
448 |
449 | /// Resets the SQL statement.
450 | ///
451 | /// - returns: Int result
452 | public func reset() throws -> Int {
453 | let res = sqlite3_reset(self.stat!)
454 | try checkRes(res)
455 | return Int(res)
456 | }
457 |
458 | /// Return the number of columns in mthe result set.
459 | ///
460 | /// - returns: Int count of columns in result set
461 | public func columnCount() -> Int {
462 | let res = sqlite3_column_count(self.stat!)
463 | return Int(res)
464 | }
465 |
466 | /// Returns the name for the indicated column.
467 | ///
468 | /// - parameter position: Int position of column
469 | /// - returns: String name of column
470 | public func columnName(position: Int) -> String {
471 | return String(validatingUTF8: sqlite3_column_name(self.stat!, Int32(position)))!
472 | }
473 |
474 | /// Returns the name of the declared type for the indicated column.
475 | ///
476 | /// - parameter position: Int position of column
477 | /// - returns: String name of declared type
478 | public func columnDeclType(position: Int) -> String {
479 | return String(validatingUTF8: sqlite3_column_decltype(self.stat!, Int32(position)))!
480 | }
481 |
482 | /// Returns the blob data for the indicated column.
483 | ///
484 | /// - parameter position: Int position of column
485 | /// - returns: [Int8] blob
486 | @available(*, deprecated, renamed:"columnIntBlob")
487 | public func columnBlob(position: Int) -> [Int8] {
488 | return columnIntBlob(position: position)
489 | }
490 |
491 | /// Returns the blob data for the indicated column.
492 | ///
493 | /// - parameter position: Int position of column
494 | /// - returns: [I: BinaryInteger] blob
495 | public func columnIntBlob(position: Int) -> [I] {
496 | let vp = sqlite3_column_blob(self.stat!, Int32(position))
497 | let vpLen = Int(sqlite3_column_bytes(self.stat!, Int32(position)))
498 |
499 | guard vpLen > 0 else {
500 | return []
501 | }
502 |
503 | var ret = [I]()
504 | if var bytesPtr = vp?.bindMemory(to: I.self, capacity: vpLen) {
505 | for _ in 0.. Double {
518 | return Double(sqlite3_column_double(self.stat!, Int32(position)))
519 | }
520 |
521 | /// Returns the Int value for the indicated column.
522 | ///
523 | /// - parameter: Int position of column
524 | /// - returns: Int value for column
525 | public func columnInt(position: Int) -> Int {
526 | return Int(sqlite3_column_int64(self.stat!, Int32(position)))
527 | }
528 |
529 | /// Returns the Int32 value for the indicated column.
530 | ///
531 | /// - parameter: Int position of column
532 | /// - returns: Int32 value for column
533 | public func columnInt32(position: Int) -> Int32 {
534 | return sqlite3_column_int(self.stat!, Int32(position))
535 | }
536 |
537 | /// Returns the Int64 value for the indicated column.
538 | ///
539 | /// - parameter: Int position of column
540 | /// - returns: Int64 value for column
541 | public func columnInt64(position: Int) -> Int64 {
542 | return sqlite3_column_int64(self.stat!, Int32(position))
543 | }
544 |
545 | /// Returns the String value for the indicated column.
546 | ///
547 | /// - parameter: Int position of column
548 | /// - returns: String value for column
549 | public func columnText(position: Int) -> String {
550 | if let res = sqlite3_column_text(self.stat!, Int32(position)) {
551 | return res.withMemoryRebound(to: Int8.self, capacity: 0) {
552 | String(validatingUTF8: $0) ?? ""
553 | }
554 | }
555 | return ""
556 | }
557 |
558 | /// Returns the type for the indicated column.
559 | ///
560 | /// - parameter: Int position of column
561 | /// - returns: Int32
562 | public func columnType(position: Int) -> Int32 {
563 | return sqlite3_column_type(self.stat!, Int32(position))
564 | }
565 |
566 | /// Test if the indicated column is an integer
567 | ///
568 | /// - parameter: Int position of column
569 | /// - returns: Bool
570 | public func isInteger(position: Int) -> Bool {
571 | return SQLITE_INTEGER == columnType(position: position)
572 | }
573 |
574 | /// Test if the indicated column is a Float
575 | ///
576 | /// - parameter: Int position of column
577 | /// - returns: Bool
578 | public func isFloat(position: Int) -> Bool {
579 | return SQLITE_FLOAT == columnType(position: position)
580 | }
581 |
582 | /// Test if the indicated column is Text
583 | ///
584 | /// - parameter: Int position of column
585 | /// - returns: Bool
586 | public func isText(position: Int) -> Bool {
587 | return SQLITE_TEXT == columnType(position: position)
588 | }
589 |
590 | /// Test if the indicated column is a Blob
591 | ///
592 | /// - parameter: Int position of column
593 | /// - returns: Bool
594 | public func isBlob(position: Int) -> Bool {
595 | return SQLITE_BLOB == columnType(position: position)
596 | }
597 |
598 | /// Test if the indicated column is NULL
599 | ///
600 | /// - parameter: Int position of column
601 | /// - returns: Bool
602 | public func isNull(position: Int) -> Bool {
603 | return SQLITE_NULL == columnType(position: position)
604 | }
605 |
606 | func checkRes(_ res: Int32) throws {
607 | try checkRes(Int(res))
608 | }
609 |
610 | func checkRes(_ res: Int) throws {
611 | if res != Int(SQLITE_OK) {
612 | throw SQLiteError(code: res, description: String(validatingUTF8: sqlite3_errmsg(self.db!))!)
613 | }
614 | }
615 |
616 | deinit {
617 | finalize()
618 | }
619 | }
620 |
621 | #if !swift(>=4.1)
622 | // Added for Swift 4.0/4.1 compat
623 | extension Collection {
624 | func compactMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
625 | return try flatMap(transform)
626 | }
627 | }
628 | #endif
629 |
630 |
--------------------------------------------------------------------------------
/docs/Classes/SQLite.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SQLite Class Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
Docs (100% documented)
18 |
19 |
20 |
21 |
22 | Reference
23 |
24 | SQLite Class Reference
25 |
26 |
27 |
28 |
51 |
52 |
53 |
54 | SQLite
55 |
56 |
57 |
public class SQLite
58 |
59 |
60 |
61 | A SQLite database
62 |
63 |
64 |
65 |
66 |
67 |
68 |
75 |
76 |
77 |
78 |
79 |
80 |
Create or open a SQLite database given a file path.
81 |
82 |
83 |
Throws
84 | SQLiteError
85 |
86 |
87 |
88 |
89 |
90 |
Declaration
91 |
92 |
Swift
93 |
public init ( _ path : String , readOnly : Bool = false ) throws
94 |
95 |
96 |
97 |
98 |
Parameters
99 |
100 |
101 |
102 |
103 |
104 | path
105 |
106 |
107 |
108 |
109 |
String path to SQLite database
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | readOnly
118 |
119 |
120 |
121 |
122 |
Optional, Bool flag for read/write setting, defaults to false
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | close()
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
Close the SQLite database.
147 |
148 |
149 |
150 |
Declaration
151 |
152 |
Swift
153 |
public func close ()
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
168 |
169 |
170 |
171 |
172 |
173 |
Compile the SQL statement.
174 |
175 |
176 |
177 |
Declaration
178 |
179 |
Swift
180 |
public func prepare ( statement stat : String ) throws -> SQLiteStmt
181 |
182 |
183 |
184 |
185 |
Return Value
186 |
A SQLiteStmt object representing the compiled statement.
187 |
188 |
189 |
190 |
191 |
192 |
193 |
200 |
201 |
202 |
203 |
204 |
205 |
Returns the value of sqlite3_last_insert_rowid.
206 |
207 |
208 |
209 |
Declaration
210 |
211 |
Swift
212 |
public func lastInsertRowID () -> Int
213 |
214 |
215 |
216 |
217 |
Return Value
218 |
Int last inserted row ID
219 |
220 |
221 |
222 |
223 |
224 |
225 |
232 |
233 |
234 |
235 |
236 |
237 |
Returns the value of sqlite3_total_changes.
238 |
239 |
240 |
241 |
Declaration
242 |
243 |
Swift
244 |
public func totalChanges () -> Int
245 |
246 |
247 |
248 |
249 |
Return Value
250 |
Int total changes
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 | changes()
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
Returns the value of sqlite3_changes.
270 |
271 |
272 |
273 |
Declaration
274 |
275 |
Swift
276 |
public func changes () -> Int
277 |
278 |
279 |
280 |
281 |
Return Value
282 |
Int number of changes
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 | errCode()
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
Returns the value of sqlite3_errcode.
302 |
303 |
304 |
305 |
Declaration
306 |
307 |
Swift
308 |
public func errCode () -> Int
309 |
310 |
311 |
312 |
313 |
Return Value
314 |
Int error code
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 | errMsg()
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
Returns the value of sqlite3_errmsg.
334 |
335 |
336 |
337 |
Declaration
338 |
339 |
Swift
340 |
public func errMsg () -> String
341 |
342 |
343 |
344 |
345 |
Return Value
346 |
String error message
347 |
348 |
349 |
350 |
351 |
352 |
353 |
360 |
361 |
362 |
363 |
364 |
365 |
Execute the given statement. Assumes there will be no parameter binding or resulting row data.
366 |
367 |
368 |
Throws
369 | ()
370 |
371 |
372 |
373 |
374 |
375 |
Declaration
376 |
377 |
Swift
378 |
public func execute ( statement statement : String ) throws
379 |
380 |
381 |
382 |
383 |
Parameters
384 |
385 |
386 |
387 |
388 |
389 | statement
390 |
391 |
392 |
393 |
394 |
String statement to be executed
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
413 |
414 |
415 |
416 |
417 |
418 |
Execute the given statement. Calls the provided callback one time for parameter binding. Assumes there will be no resulting row data.
419 |
420 |
421 |
Throws
422 | ()
423 |
424 |
425 |
426 |
427 |
428 |
Declaration
429 |
430 |
Swift
431 |
public func execute ( statement statement : String , doBindings : ( SQLiteStmt ) throws -> ()) throws
432 |
433 |
434 |
435 |
436 |
Parameters
437 |
438 |
439 |
440 |
441 |
442 | statement
443 |
444 |
445 |
446 |
447 |
String statement to be executed
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 | doBindings
456 |
457 |
458 |
459 |
460 |
Block used for bindings
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
479 |
480 |
481 |
482 |
483 |
484 |
Execute the given statement count times. Calls the provided callback on each execution for parameter binding. Assumes there will be no resulting row data.
485 |
486 |
487 |
Throws
488 | ()
489 |
490 |
491 |
492 |
493 |
494 |
Declaration
495 |
496 |
Swift
497 |
public func execute ( statement statement : String , count : Int , doBindings : ( SQLiteStmt , Int ) throws -> ()) throws
498 |
499 |
500 |
501 |
502 |
Parameters
503 |
504 |
505 |
506 |
507 |
508 | statement
509 |
510 |
511 |
512 |
513 |
String statement to be executed
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 | count
522 |
523 |
524 |
525 |
526 |
Int number of times to execute
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 | doBindings
535 |
536 |
537 |
538 |
539 |
Block to be executed for binding on each call
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
558 |
559 |
560 |
561 |
562 |
563 |
Executes a BEGIN, calls the provided closure and executes a ROLLBACK if an exception occurs or a COMMIT if no exception occurs.
564 |
565 |
566 |
Throws
567 | ErrorType
568 |
569 |
570 |
571 |
572 |
573 |
Declaration
574 |
575 |
Swift
576 |
public func doWithTransaction ( closure : () throws -> ()) throws
577 |
578 |
579 |
580 |
581 |
Parameters
582 |
583 |
584 |
585 |
586 |
587 | closure
588 |
589 |
590 |
591 |
592 |
Block to be executed inside transaction
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
611 |
612 |
613 |
614 |
615 |
616 |
Executes the statement and calls the closure for each resulting row.
617 |
618 |
619 |
Throws
620 | ()
621 |
622 |
623 |
624 |
625 |
626 |
Declaration
627 |
628 |
Swift
629 |
public func forEachRow ( statement statement : String , handleRow : ( SQLiteStmt , Int ) -> ()) throws
630 |
631 |
632 |
633 |
634 |
Parameters
635 |
636 |
637 |
638 |
639 |
640 | statement
641 |
642 |
643 |
644 |
645 |
String statement to be executed
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 | handleRow
654 |
655 |
656 |
657 |
658 |
Block to be executed for each row
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
677 |
678 |
679 |
680 |
681 |
682 |
Executes the statement, calling doBindings to handle parameter bindings and calling handleRow for each resulting row.
683 |
684 |
685 |
Throws
686 | ()
687 |
688 |
689 |
690 |
691 |
692 |
Declaration
693 |
694 |
Swift
695 |
public func forEachRow ( statement statement : String , doBindings : ( SQLiteStmt ) throws -> (), handleRow : ( SQLiteStmt , Int ) -> ()) throws
696 |
697 |
698 |
699 |
700 |
Parameters
701 |
702 |
703 |
704 |
705 |
706 | statement
707 |
708 |
709 |
710 |
711 |
String statement to be executed
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 | doBindings
720 |
721 |
722 |
723 |
724 |
Block to perform bindings on statement
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 | handleRow
733 |
734 |
735 |
736 |
737 |
Block to execute for each row
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
756 |
757 |
758 |
759 |
760 |
761 |
--------------------------------------------------------------------------------
/docs/docsets/.docset/Contents/Resources/Documents/Classes/SQLite.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SQLite Class Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
Docs (100% documented)
18 |
19 |
20 |
21 |
22 | Reference
23 |
24 | SQLite Class Reference
25 |
26 |
27 |
28 |
51 |
52 |
53 |
54 | SQLite
55 |
56 |
57 |
public class SQLite
58 |
59 |
60 |
61 | A SQLite database
62 |
63 |
64 |
65 |
66 |
67 |
68 |
75 |
76 |
77 |
78 |
79 |
80 |
Create or open a SQLite database given a file path.
81 |
82 |
83 |
Throws
84 | SQLiteError
85 |
86 |
87 |
88 |
89 |
90 |
Declaration
91 |
92 |
Swift
93 |
public init ( _ path : String , readOnly : Bool = false ) throws
94 |
95 |
96 |
97 |
98 |
Parameters
99 |
100 |
101 |
102 |
103 |
104 | path
105 |
106 |
107 |
108 |
109 |
String path to SQLite database
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | readOnly
118 |
119 |
120 |
121 |
122 |
Optional, Bool flag for read/write setting, defaults to false
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | close()
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
Close the SQLite database.
147 |
148 |
149 |
150 |
Declaration
151 |
152 |
Swift
153 |
public func close ()
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
168 |
169 |
170 |
171 |
172 |
173 |
Compile the SQL statement.
174 |
175 |
176 |
177 |
Declaration
178 |
179 |
Swift
180 |
public func prepare ( statement stat : String ) throws -> SQLiteStmt
181 |
182 |
183 |
184 |
185 |
Return Value
186 |
A SQLiteStmt object representing the compiled statement.
187 |
188 |
189 |
190 |
191 |
192 |
193 |
200 |
201 |
202 |
203 |
204 |
205 |
Returns the value of sqlite3_last_insert_rowid.
206 |
207 |
208 |
209 |
Declaration
210 |
211 |
Swift
212 |
public func lastInsertRowID () -> Int
213 |
214 |
215 |
216 |
217 |
Return Value
218 |
Int last inserted row ID
219 |
220 |
221 |
222 |
223 |
224 |
225 |
232 |
233 |
234 |
235 |
236 |
237 |
Returns the value of sqlite3_total_changes.
238 |
239 |
240 |
241 |
Declaration
242 |
243 |
Swift
244 |
public func totalChanges () -> Int
245 |
246 |
247 |
248 |
249 |
Return Value
250 |
Int total changes
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 | changes()
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
Returns the value of sqlite3_changes.
270 |
271 |
272 |
273 |
Declaration
274 |
275 |
Swift
276 |
public func changes () -> Int
277 |
278 |
279 |
280 |
281 |
Return Value
282 |
Int number of changes
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 | errCode()
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
Returns the value of sqlite3_errcode.
302 |
303 |
304 |
305 |
Declaration
306 |
307 |
Swift
308 |
public func errCode () -> Int
309 |
310 |
311 |
312 |
313 |
Return Value
314 |
Int error code
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 | errMsg()
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
Returns the value of sqlite3_errmsg.
334 |
335 |
336 |
337 |
Declaration
338 |
339 |
Swift
340 |
public func errMsg () -> String
341 |
342 |
343 |
344 |
345 |
Return Value
346 |
String error message
347 |
348 |
349 |
350 |
351 |
352 |
353 |
360 |
361 |
362 |
363 |
364 |
365 |
Execute the given statement. Assumes there will be no parameter binding or resulting row data.
366 |
367 |
368 |
Throws
369 | ()
370 |
371 |
372 |
373 |
374 |
375 |
Declaration
376 |
377 |
Swift
378 |
public func execute ( statement statement : String ) throws
379 |
380 |
381 |
382 |
383 |
Parameters
384 |
385 |
386 |
387 |
388 |
389 | statement
390 |
391 |
392 |
393 |
394 |
String statement to be executed
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
413 |
414 |
415 |
416 |
417 |
418 |
Execute the given statement. Calls the provided callback one time for parameter binding. Assumes there will be no resulting row data.
419 |
420 |
421 |
Throws
422 | ()
423 |
424 |
425 |
426 |
427 |
428 |
Declaration
429 |
430 |
Swift
431 |
public func execute ( statement statement : String , doBindings : ( SQLiteStmt ) throws -> ()) throws
432 |
433 |
434 |
435 |
436 |
Parameters
437 |
438 |
439 |
440 |
441 |
442 | statement
443 |
444 |
445 |
446 |
447 |
String statement to be executed
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 | doBindings
456 |
457 |
458 |
459 |
460 |
Block used for bindings
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
479 |
480 |
481 |
482 |
483 |
484 |
Execute the given statement count times. Calls the provided callback on each execution for parameter binding. Assumes there will be no resulting row data.
485 |
486 |
487 |
Throws
488 | ()
489 |
490 |
491 |
492 |
493 |
494 |
Declaration
495 |
496 |
Swift
497 |
public func execute ( statement statement : String , count : Int , doBindings : ( SQLiteStmt , Int ) throws -> ()) throws
498 |
499 |
500 |
501 |
502 |
Parameters
503 |
504 |
505 |
506 |
507 |
508 | statement
509 |
510 |
511 |
512 |
513 |
String statement to be executed
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 | count
522 |
523 |
524 |
525 |
526 |
Int number of times to execute
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 | doBindings
535 |
536 |
537 |
538 |
539 |
Block to be executed for binding on each call
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
558 |
559 |
560 |
561 |
562 |
563 |
Executes a BEGIN, calls the provided closure and executes a ROLLBACK if an exception occurs or a COMMIT if no exception occurs.
564 |
565 |
566 |
Throws
567 | ErrorType
568 |
569 |
570 |
571 |
572 |
573 |
Declaration
574 |
575 |
Swift
576 |
public func doWithTransaction ( closure : () throws -> ()) throws
577 |
578 |
579 |
580 |
581 |
Parameters
582 |
583 |
584 |
585 |
586 |
587 | closure
588 |
589 |
590 |
591 |
592 |
Block to be executed inside transaction
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
611 |
612 |
613 |
614 |
615 |
616 |
Executes the statement and calls the closure for each resulting row.
617 |
618 |
619 |
Throws
620 | ()
621 |
622 |
623 |
624 |
625 |
626 |
Declaration
627 |
628 |
Swift
629 |
public func forEachRow ( statement statement : String , handleRow : ( SQLiteStmt , Int ) -> ()) throws
630 |
631 |
632 |
633 |
634 |
Parameters
635 |
636 |
637 |
638 |
639 |
640 | statement
641 |
642 |
643 |
644 |
645 |
String statement to be executed
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 | handleRow
654 |
655 |
656 |
657 |
658 |
Block to be executed for each row
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
677 |
678 |
679 |
680 |
681 |
682 |
Executes the statement, calling doBindings to handle parameter bindings and calling handleRow for each resulting row.
683 |
684 |
685 |
Throws
686 | ()
687 |
688 |
689 |
690 |
691 |
692 |
Declaration
693 |
694 |
Swift
695 |
public func forEachRow ( statement statement : String , doBindings : ( SQLiteStmt ) throws -> (), handleRow : ( SQLiteStmt , Int ) -> ()) throws
696 |
697 |
698 |
699 |
700 |
Parameters
701 |
702 |
703 |
704 |
705 |
706 | statement
707 |
708 |
709 |
710 |
711 |
String statement to be executed
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 | doBindings
720 |
721 |
722 |
723 |
724 |
Block to perform bindings on statement
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 | handleRow
733 |
734 |
735 |
736 |
737 |
Block to execute for each row
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
756 |
757 |
758 |
759 |
760 |
761 |
--------------------------------------------------------------------------------