Skip to content

Commit cb31f49

Browse files
committed
Fixed typos in README
1 parent 9867e41 commit cb31f49

2 files changed

Lines changed: 16 additions & 16 deletions

File tree

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
</p>
1414

1515
# Overview
16-
Otter is a pure Swift SQL compiler that allow developers to simply write plain SQL with compile time safety.
16+
Otter is a pure Swift SQL compiler that allows developers to simply write plain SQL with compile time safety.
1717
If your database schema changes, you will get compile time errors for the places that need to be fixed.
18-
It just doesn't generate the code to talk to SQLite, but rather your entire data layer in a testable
18+
It doesn't just generate the code to talk to SQLite, but rather your entire data layer in a testable
1919
flexible manner. No more writing mocks or wrappers. Just pass in the query.
2020

2121
- [Installation](#installation)
@@ -79,7 +79,7 @@ Otter can even run within a Swift macro by adding the `@Database` macro to a `st
7979
@Database
8080
struct DB {
8181
@Query("SELECT * FROM foo")
82-
var selectFooQuery: any SelectFooQuery
82+
var selectFoo: any SelectFooQuery
8383

8484
static var migrations: [String] {
8585
return [
@@ -106,7 +106,7 @@ func main() async throws {
106106

107107
> [!IMPORTANT]
108108
> As of now it is not recommended for larger projects. There are quite a few limitations
109-
that won't scale well beyond a fairly simple schema and a handfull of queries.
109+
that won't scale well beyond a fairly simple schema and a handful of queries.
110110

111111
#### Anatomy of a @Query
112112
```swift
@@ -205,7 +205,7 @@ let database = try DB(path: "...")
205205
let database = try DB.inMemory()
206206

207207
// Or open up using the configuration.
208-
var config = DatbaseConfig()
208+
var config = DatabaseConfig()
209209
config.path = "" // if nil, it will be in memory
210210
config.maxConnectionCount = 8
211211
let database = try DB(config: config)
@@ -267,15 +267,15 @@ SELECT id, name FROM user;
267267
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.
268268
```sql
269269
fetchUsers:
270-
SELECT user.*, COUNT(post.*) AS numberOfPosts
271-
OUTER JOIN post ON post.userId = user.id
270+
SELECT user.*, COUNT(*) AS numberOfPosts
271+
LEFT OUTER JOIN post ON post.userId = user.id
272272
GROUP BY user.id;
273273
```
274274

275275
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.
276276
```swift
277277
@dynamicMemberLookup
278-
FetchUsersOutput {
278+
struct FetchUsersOutput {
279279
let user: User
280280
let numberOfPosts: Int
281281

@@ -284,7 +284,7 @@ FetchUsersOutput {
284284
```
285285

286286
### Inputs
287-
When a query has multiple inputs it will have a struct generated for it's inputs similar to the output. Also, so the input struct does not have to be initialized everytime, an extension will be created that takes each parameter individually, rather then the full type.
287+
When a query has multiple inputs it will have a struct generated for it's inputs similar to the output. Also, so the input struct does not have to be initialized every time, an extension will be created that takes each parameter individually, rather then the full type.
288288
```sql
289289
userPosts:
290290
SELECT * FROM post WHERE userId = ? AND date BETWEEN ? AND ?;
@@ -294,13 +294,13 @@ Would generate the following Swift code
294294

295295
```swift
296296
struct UserPostsInput {
297-
let id: Int
297+
let userId: Int
298298
let dateLower: Date
299299
let dateUpper: Date
300300
}
301301

302302
// Using the extension
303-
let posts = try await database.userQueries.userPosts.execute(id: id, dateLower: lower, dateUpper: upper)
303+
let posts = try await database.userQueries.userPosts.execute(userId: id, dateLower: lower, dateUpper: upper)
304304

305305
// Or using the input type directly
306306
let posts = try await database.userQueries.userPosts.execute(with: UserPostInput(...))
@@ -314,7 +314,7 @@ queryName(input: InputName, output: OutputName):
314314
```
315315

316316
# Types
317-
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.
317+
SQLite is a unique SQL database engine in that it is fairly lawless when it comes to typing. SQLite will allow you to 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.
318318
| SQLite | Swift |
319319
|---------|--------|
320320
| INTEGER | Int |
@@ -339,7 +339,7 @@ TEXT AS "Todo.ID"
339339
## Dependency Injection
340340
> TL;DR Avoid the repository pattern, inject queries.
341341
342-
Otter was written with application development in mind. One of the common walls when talking to a database is dependecy injection.
342+
Otter was written with application development in mind. One of the pain points when talking to a database is dependency injection.
343343
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.
344344
This is all good but that means writing different protocols and mocks. When writing the protocol you need to decide whether to just make it `async` or maybe a `publisher`.
345345
Sometimes you need both... Otter solves these problems and was designed to have injection builtin.
@@ -394,7 +394,7 @@ CREATE VIRTUAL TABLE searchIndex USING fts5 (
394394
);
395395

396396
SELECT * FROM searchIndex
397-
WHERE foo MATCH 'search terms'
397+
WHERE text MATCH 'search terms'
398398
ORDER BY rank;
399399
```
400400

@@ -409,7 +409,7 @@ Below are some idea that I would love input on!
409409
- SQLite supports custom functions which are a great way to share common logic amongst queries
410410
- Queries with multiple statements
411411
- Would allow for easier loading of more complex models that have many joins
412-
- Want to allow other queries to be called from within the body to help centrize logic.
412+
- Want to allow other queries to be called from within the body to help centralize logic.
413413
- Postgres support for server side swift
414414

415415
## Contributions

Sources/Otter/Database.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import Foundation
99

1010
/// The base protocol every generated database conforms too.
11-
public protocol Database {
11+
public protocol Database: ConnectionWrapper {
1212
/// The connection to use
1313
init(connection: any Connection)
1414
/// An ordered list of migrations to be run.

0 commit comments

Comments
 (0)