You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The fact that `insert()`, `update()`, and `delete()` have a number of
overloads that can only be disambiguated by specifying a type, a tuple
member, or `!` is a big point of confusion for new users of
SQLite.swift. The overloads add some interesting patterns to the mix,
but aren't worth the pain points.
If we eliminate the overloads, we can insert/update/delete in place.
This allows for subtle bugs to be introduced into apps (where the
developer doesn't check for a rowid or that an update/delete was
successful), but is a tradeoff we'll have to make. It doesn't make sense
to enforce a different kind of interface/access at the expense of
confusion.
Given:
let user = email <- "[email protected]")
The old way:
users.insert(user)!
let rowid = users.insert(user)!
if let rowid = users.insert(user) { /* ... */ }
let (rowid, statement) = users.insert(user)
// etc.
The new way:
users.insert(user)
let rowid = users.insert(user).rowid!
if let rowid = users.insert(user).rowid { /* ... */ }
let (rowid, statement) = users.insert(user)
// etc.
Slightly and rarely more verbose and readable, with less confusing
compiler errors and hand-holding.
Signed-off-by: Stephen Celis <[email protected]>
Copy file name to clipboardExpand all lines: Documentation/Index.md
+46-90Lines changed: 46 additions & 90 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -393,62 +393,33 @@ Additional constraints may be provided outside the scope of a single column usin
393
393
394
394
## Inserting Rows
395
395
396
-
We can insert rows into a table by calling a [query’s](#queries) `insert` function with a list of [setters](#setters), typically [typed column expressions](#expressions) and values (which can also be expressions), each joined by the `<-` operator.
396
+
We can insert rows into a table by calling a [query’s](#queries) `insert` function with a list of [setters](#setters)—typically [typed column expressions](#expressions) and values (which can also be expressions)—each joined by the `<-` operator.
// INSERT INTO "users" ("email", "name") VALUES ('[email protected]', 'Alice')
401
401
402
402
users.insert(or: .Replace, email <-"[email protected]", name <-"Alice B.")
403
403
// INSERT OR REPLACE INTO "users" ("email", "name") VALUES ('[email protected]', 'Alice B.')
404
404
```
405
405
406
-
The `insert` function can return several different types that are useful in different contexts.
406
+
The `insert` function returns a tuple with an `Int64?` representing the inserted row’s [`ROWID`][ROWID] (or `nil` on failure) and the associated `Statement`.
407
407
408
-
- An `Int64?` representing the inserted row’s [`ROWID`][ROWID] (or `nil` on failure), for simplicity.
The [`update`](#updating-rows) and [`delete`](#deleting-rows) functions follow similar patterns.
447
418
448
419
> _Note:_ If `insert` is called without any arguments, the statement will run with a `DEFAULT VALUES` clause. The table must not have any constraints that aren’t fulfilled by default values.
We can update a table’s rows by calling a [query’s](#queries) `update` function with a list of [setters](#setters), typically [typed column expressions](#expressions) and values (which can also be expressions), each joined by the `<-` operator.
790
+
We can update a table’s rows by calling a [query’s](#queries) `update` function with a list of [setters](#setters)—typically [typed column expressions](#expressions) and values (which can also be expressions)—each joined by the `<-` operator.
820
791
821
792
When an unscoped query calls `update`, it will update _every_ row in the table.
Using the `transaction` and `savepoint` functions, we can run a series of statements, committing the changes to the database if they all succeed. If a single statement fails, we can bail out early and roll back.
852
+
Using the `transaction` and `savepoint` functions, we can run a series of statements chained together (using `&&`). If a single statement fails, we can short-circuit the series (using `||`) and roll back the changes.
900
853
901
854
``` swift
902
855
db.transaction()
@@ -905,18 +858,21 @@ db.transaction()
905
858
&& db.commit() || db.rollback()
906
859
```
907
860
908
-
The former statement can also be written as
861
+
> _Note:_ Each statement is captured in an auto-closure and won’t execute till the preceding statement succeeds. This is why we can use the `lastInsertRowid` property on `Database` to reference the previous statement’s insert [`ROWID`][ROWID].
862
+
863
+
For more complex transactions and savepoints, block helpers exist. Using a block helper, the former statement can be written (more verbosely) as follows:
if users.insert(email <-"[email protected]", manager_id <- db.lastInsertRowid).rowid !=nil {
869
+
return .Commit
870
+
}
913
871
}
914
-
return .Commit|| .Rollback
872
+
return .Rollback
915
873
}
916
874
```
917
875
918
-
> _Note:_ Each statement is captured in an auto-closure and won’t execute till the preceding statement succeeds. This means we can use the `lastInsertRowid` property on `Database` to reference the previous statement’s insert [`ROWID`][ROWID].
0 commit comments