I wonder if this library could be written even safer.
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- sqlite, swift
- Domain
- backend-api-design, databases
Research direction
Start by reviewing the current Expression, Table, and database access APIs described in the issue; no implementation file or test is identified. Establish whether the proposed column and table validation belongs in a future major version, then implement and test the agreed design so references are tied to valid database objects.
Written by the indexing model from the issue text.
Description
One thing I love about this library is that you don't reference columns by string literals, but instead by variables that hold expressions. Like here:
let name = Expression<String?>("name")
users.insert(name <- "Alice")
And here:
for user in try db.prepare(users) {
print(user[name])
}
However, these expressions are not necessarily tied to the table that you are using them on. You are just initializing them yourself and then using them on the table. There is no guarantee that the users table actually has a column named "name". One could also easily make a typo when writing the string literal "name".
So I was wondering, what if you made a new struct called Column or something, which has a private initializer, so only the library can initialize it. It would work a bit like this:
guard let name = users.columns["name"] else {
throw AnError("the name column does not exist")
}
users.insert(name <- "Alice")
let user = users.first!
print(user[name])
You see this way we can at least 90% guarantee that the name column is actually a valid column for the users table. It's still not 100% of course, because a developer could still write the following and the compiler would not complain:
guard let name = users.columns["name"] else {
throw AnError("the name column does not exist")
}
posts.insert(name <- "Alice") // note the incorrect table
However, I reckon this situation is far less likely than someone making a mistake in the current system.
I'd even want to go one step further and apply the same to tables. So right now you can just initialize a table (let users = Table("users")) and start using it, even if there is no such table in the database. You can make that much safer by doing something like this:
let users: Table
if let existingUsersTable = db.tables["users"] {
users = existingUsersTable
} else {
users = db.createTable("users") {
// haven't thought this part out yet...
}
}
What do you guys think? Of course this would be quite a big overhaul so this could only be implemented in the next major version if you actually like this change.
- Dominant language
- Swift
- Stars
- 10.2k
- Forks
- 1.6k
- Avg merge
- 6d 2h
- Merged PRs (30d)
- 2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from stephencelis/SQLite.swift
-
Difficulty 1/5 Under an hour Newbie friendliness 95/100
stephencelis/SQLite.swift#1375 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
stephencelis/SQLite.swift#1293 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 38/100
stephencelis/SQLite.swift#1347 · 7 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
stephencelis/SQLite.swift#1338 · 1 comment ·
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
stephencelis/SQLite.swift#1337 · 3 comments ·
All issues in stephencelis/SQLite.swift
Similar issues
-
tvOS
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
skiptools/skip-fuse-ui#147 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
OneBusAway/onebusaway-ios#1438 · 1 reaction ·