Skip to content

Commit 5f8867c

Browse files
authored
Update README.md
1 parent a548471 commit 5f8867c

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

README.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</strong>
1313
</p>
1414

15-
## Overview
15+
# Overview
1616
Otter is a pure Swift SQL compiler that allow developers to write plain comile time safe SQL.
1717

1818
- [Installation](#installation)
@@ -21,7 +21,9 @@ Otter is a pure Swift SQL compiler that allow developers to write plain comile t
2121
- [Operators](#operators)
2222
- [Dependency Injection](#dependency-injection)
2323

24-
As a primer here is a quick example. First, in SQL we will create our migrations and our first query.
24+
## Basic Primer
25+
26+
As a quick intro, here is an basic example. First, in SQL we will create our migrations and our first query.
2527
```sql
2628
-- Located in Migrations/1.sql
2729
CREATE TABLE todo (
@@ -184,15 +186,15 @@ let users: [User] = try await query.execute()
184186
```
185187

186188
### Input and Output Types
187-
In the example above, since we selected all columns from a single table the query will return the `User` struct that was generated for the table. If additional columns are selected a new structure will be generated to match the output. In the following example we will join in the `post` table to get a users post count.
189+
In the example above, since we selected all columns from a single table the query will return the `User` struct that was generated for the table. If additional columns are selected a new structure will be generated to match the selected columns. In the following example we will join in the `post` table to get a users post count.
188190
```sql
189191
DEFINE QUERY fetchUsers AS
190192
SELECT user.*, COUNT(post.*) AS numberOfPosts
191193
OUTER JOIN post ON post.userId = user.id
192194
GROUP BY user.id;
193195
```
194196

195-
The following `struct` would automatically be generated for the query. Since we used the syntax `user.*` it will embed the `User` struct instead of replicating it's columns. Any embeded table struct will also get a `@dynamicMemberLookup` method generated so it can be accessed directly like the other column values.
197+
The following `struct` would automatically be generated for the query. Since we used the syntax `user.*` it will embed the `User` struct instead of replicating it's columns. Any embeded table struct will also get a `@dynamicMemberLookup` method generated so it can be accessed directly like the other column values. This allows extensions on the table struct to work across many queries.
196198
```swift
197199
@dynamicMemberLookup
198200
FetchUsersOutput {
@@ -219,7 +221,11 @@ struct UserPostsInput {
219221
let dateUpper: Date
220222
}
221223

224+
// Using the extension
222225
let posts = try await database.userQueries.userPosts.execute(id: id, dateLower: lower, dateUpper: upper)
226+
227+
// Or using the input type directly
228+
let posts = try await database.userQueries.userPosts.execute(with: UserPostInput(...))
223229
```
224230

225231
### Naming
@@ -229,7 +235,7 @@ DEFINE QUERY queryName(input: InputName, output: OutputName) AS ...
229235
```
230236

231237
# Types
232-
SQLite is a unique SQL database engine in that it is fairly lawless when it comes to typing. SQLite will allow you create a column with an `INTEGER` and gladly insert a `TEXT` into it. It will even let you make up your own type names and will take them. Otter will not allow this and tends to operate more strictly like the table option `STRICT`. Only the core types that SQLite recognizes are usable for the column type.
238+
SQLite is a unique SQL database engine in that it is fairly lawless when it comes to typing. SQLite will allow you create a column with an `INTEGER` and gladly insert a `TEXT` into it. It will even let you make up your own type names and it will take them. Otter will not allow this and tends to operate more strictly like the table option `STRICT`. Only the core types that SQLite recognizes are usable for the column type.
233239
| SQLite | Swift |
234240
|---------|--------|
235241
| INTEGER | Int |
@@ -238,7 +244,7 @@ SQLite is a unique SQL database engine in that it is fairly lawless when it come
238244
| BLOB | Data |
239245
| ANY | SQLAny |
240246

241-
#### Custom Types
247+
### Custom Types
242248
While your column only can be one of the core SQLite types, what type that ends up as in Swift can be different. Using the `AS` keyword you can specify the Swift type to decode it to. Think of the column type as the storage type while the type in the `AS` will be the type actually in the interface.
243249

244250
Using the `AS` keyword you can specify the type to use in `Swift`
@@ -265,7 +271,7 @@ func then<Next>(
265271
```
266272

267273
## Dependency Injection
268-
> TLDR; Avoid the repository pattern, inject queries.
274+
> TL;DR Avoid the repository pattern, inject queries.
269275
270276
Otter was written with application development in mind. One of the common walls when talking to a database is dependecy injection.
271277
Normally this would mean wrapping your database calls in a repository or some other layer to keep the model layer testable without needing a database connection.

0 commit comments

Comments
 (0)