Skip to content

Commit 6eba24d

Browse files
committed
Merge branch 'development'
2 parents c7205b1 + bd3ac9e commit 6eba24d

18 files changed

+269
-53
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
77

88
#### 7.x Releases
99

10+
- `7.3.x` Releases - [7.3.0](#730)
1011
- `7.2.x` Releases - [7.2.0](#720)
1112
- `7.1.x` Releases - [7.1.0](#710)
1213
- `7.0.x` Releases - [7.0.0](#700)
@@ -134,6 +135,13 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
134135

135136
---
136137

138+
## 7.3.0
139+
140+
Released February 23, 2025
141+
142+
- **New**: Support for temporary virtual tables by [@groue](https://github.com/groue) in [#1731](https://github.com/groue/GRDB.swift/pull/1731)
143+
- Fixed a compiler error in Xcode 16.3 beta ([#1729](https://github.com/groue/GRDB.swift/pull/1729), [#1730](https://github.com/groue/GRDB.swift/pull/1730))
144+
137145
## 7.2.0
138146

139147
Released February 12, 2025

Documentation/FullTextSearch.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Generally speaking, FTS5 is better than FTS4 which improves on FTS3. But this do
9191

9292
**FTS3 and FTS4 full-text tables store and index textual content.**
9393

94-
Create tables with the `create(virtualTable:using:)` method:
94+
Create tables with the `create(virtualTable:options:using:_:)` method:
9595

9696
```swift
9797
// CREATE VIRTUAL TABLE document USING fts3(content)
@@ -326,7 +326,7 @@ let documents = try Document.filter(Column("content").match(pattern)).fetchAll(d
326326

327327
To use FTS5, you'll need a [custom SQLite build] that activates the `SQLITE_ENABLE_FTS5` compilation option.
328328

329-
Create FTS5 tables with the `create(virtualTable:using:)` method:
329+
Create FTS5 tables with the `create(virtualTable:options:using:_:)` method:
330330

331331
```swift
332332
// CREATE VIRTUAL TABLE document USING fts5(content)

GRDB.swift.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'GRDB.swift'
3-
s.version = '7.2.0'
3+
s.version = '7.3.0'
44

55
s.license = { :type => 'MIT', :file => 'LICENSE' }
66
s.summary = 'A toolkit for SQLite databases, with a focus on application development.'

GRDB/Documentation.docc/DatabaseSchemaModifications.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ Unique constraints and unique indexes are somewhat different: don't miss the tip
252252

253253
- ``Database/alter(table:body:)``
254254
- ``Database/create(table:options:body:)``
255-
- ``Database/create(virtualTable:ifNotExists:using:)``
256-
- ``Database/create(virtualTable:ifNotExists:using:_:)``
255+
- ``Database/create(virtualTable:options:using:)``
256+
- ``Database/create(virtualTable:options:using:_:)``
257257
- ``Database/drop(table:)``
258258
- ``Database/dropFTS4SynchronizationTriggers(forTable:)``
259259
- ``Database/dropFTS5SynchronizationTriggers(forTable:)``
@@ -265,6 +265,7 @@ Unique constraints and unique indexes are somewhat different: don't miss the tip
265265
- ``TableDefinition``
266266
- ``TableOptions``
267267
- ``VirtualTableModule``
268+
- ``VirtualTableOptions``
268269

269270
### Database Views
270271

@@ -288,3 +289,5 @@ Those are legacy interfaces that are preserved for backwards compatibility. Thei
288289

289290
- ``Database/create(index:on:columns:unique:ifNotExists:condition:)``
290291
- ``Database/create(table:temporary:ifNotExists:withoutRowID:body:)``
292+
- ``Database/create(virtualTable:ifNotExists:using:)``
293+
- ``Database/create(virtualTable:ifNotExists:using:_:)``

GRDB/FTS/FTS3.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// The virtual table module for the FTS3 full-text engine.
22
///
33
/// To create FTS3 tables, use the ``Database`` method
4-
/// ``Database/create(virtualTable:ifNotExists:using:_:)``:
4+
/// ``Database/create(virtualTable:options:using:_:)``:
55
///
66
/// ```swift
77
/// // CREATE VIRTUAL TABLE document USING fts3(content)
@@ -63,7 +63,7 @@ public struct FTS3 {
6363
/// }
6464
/// ```
6565
///
66-
/// See ``Database/create(virtualTable:ifNotExists:using:_:)``
66+
/// See ``Database/create(virtualTable:options:using:_:)``
6767
public init() { }
6868

6969
/// Returns an array of tokens found in the string argument.
@@ -143,7 +143,7 @@ extension FTS3: VirtualTableModule {
143143
/// virtual table.
144144
///
145145
/// You don't create instances of this class. Instead, you use the `Database`
146-
/// ``Database/create(virtualTable:ifNotExists:using:_:)`` method:
146+
/// ``Database/create(virtualTable:options:using:_:)`` method:
147147
///
148148
/// ```swift
149149
/// try db.create(virtualTable: "document", using: FTS3()) { t in // t is FTS3TableDefinition

GRDB/FTS/FTS3TokenizerDescriptor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ public struct FTS3TokenizerDescriptor: Sendable {
106106
if !separators.isEmpty {
107107
// TODO: test "=" and "\"", "(" and ")" as separators, with
108108
// both FTS3Pattern(matchingAnyTokenIn:tokenizer:)
109-
// and Database.create(virtualTable:using:)
109+
// and Database.create(virtualTable:options:using:_:)
110110
arguments.append("separators=" + separators.sorted().map { String($0) }.joined())
111111
}
112112
if !tokenCharacters.isEmpty {
113113
// TODO: test "=" and "\"", "(" and ")" as tokenCharacters, with
114114
// both FTS3Pattern(matchingAnyTokenIn:tokenizer:)
115-
// and Database.create(virtualTable:using:)
115+
// and Database.create(virtualTable:options:using:_:)
116116
arguments.append("tokenchars=" + tokenCharacters.sorted().map { String($0) }.joined())
117117
}
118118
return FTS3TokenizerDescriptor("unicode61", arguments: arguments)

GRDB/FTS/FTS4.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// The virtual table module for the FTS4 full-text engine.
22
///
33
/// To create FTS4 tables, use the ``Database`` method
4-
/// ``Database/create(virtualTable:ifNotExists:using:_:)``:
4+
/// ``Database/create(virtualTable:options:using:_:)``:
55
///
66
/// ```swift
77
/// // CREATE VIRTUAL TABLE document USING fts4(content)
@@ -31,7 +31,7 @@ public struct FTS4 {
3131
/// }
3232
/// ```
3333
///
34-
/// See ``Database/create(virtualTable:ifNotExists:using:_:)``
34+
/// See ``Database/create(virtualTable:options:using:_:)``
3535
public init() { }
3636
}
3737

@@ -102,6 +102,16 @@ extension FTS4: VirtualTableModule {
102102
case .synchronized(let contentTable):
103103
// https://www.sqlite.org/fts3.html#_external_content_fts4_tables_
104104

105+
if definition.configuration.temporary {
106+
// SQLite can't rebuild the index of temporary tables:
107+
//
108+
// sqlite> CREATE TABLE t(id INTEGER PRIMARY KEY, a, b, c);
109+
// sqlite> CREATE VIRTUAL TABLE temp.ft USING fts4(content="t", b, c);
110+
// sqlite> INSERT INTO ft(ft) VALUES('rebuild');
111+
// Runtime error: SQL logic error
112+
fatalError("Temporary external content FTS4 tables are not supported.")
113+
}
114+
105115
let rowIDColumn = try db.primaryKey(contentTable).rowIDColumn ?? Column.rowID.name
106116
let ftsTable = tableName.quotedDatabaseIdentifier
107117
let content = contentTable.quotedDatabaseIdentifier
@@ -149,7 +159,7 @@ extension FTS4: VirtualTableModule {
149159
/// virtual table.
150160
///
151161
/// You don't create instances of this class. Instead, you use the `Database`
152-
/// ``Database/create(virtualTable:ifNotExists:using:_:)`` method:
162+
/// ``Database/create(virtualTable:options:using:_:)`` method:
153163
///
154164
/// ```swift
155165
/// try db.create(virtualTable: "document", using: FTS4()) { t in // t is FTS4TableDefinition

GRDB/FTS/FTS5.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Foundation
1313
/// The virtual table module for the FTS5 full-text engine.
1414
///
1515
/// To create FTS5 tables, use the ``Database`` method
16-
/// ``Database/create(virtualTable:ifNotExists:using:_:)``:
16+
/// ``Database/create(virtualTable:options:using:_:)``:
1717
///
1818
/// ```swift
1919
/// // CREATE VIRTUAL TABLE document USING fts5(content)
@@ -85,7 +85,7 @@ public struct FTS5 {
8585
/// }
8686
/// ```
8787
///
88-
/// See ``Database/create(virtualTable:ifNotExists:using:_:)``
88+
/// See ``Database/create(virtualTable:options:using:_:)``
8989
public init() { }
9090

9191
// Support for FTS5Pattern initializers. Don't make public. Users tokenize
@@ -143,7 +143,7 @@ extension FTS5: VirtualTableModule {
143143

144144
/// Reserved; part of the VirtualTableModule protocol.
145145
///
146-
/// See Database.create(virtualTable:using:)
146+
/// See Database.create(virtualTable:options:using:_:)
147147
public func makeTableDefinition(configuration: VirtualTableConfiguration) -> FTS5TableDefinition {
148148
FTS5TableDefinition(configuration: configuration)
149149
}
@@ -219,14 +219,24 @@ extension FTS5: VirtualTableModule {
219219

220220
/// Reserved; part of the VirtualTableModule protocol.
221221
///
222-
/// See Database.create(virtualTable:using:)
222+
/// See Database.create(virtualTable:options:using:_:)
223223
public func database(_ db: Database, didCreate tableName: String, using definition: FTS5TableDefinition) throws {
224224
switch definition.contentMode {
225225
case .raw:
226226
break
227227
case .synchronized(let contentTable):
228228
// https://sqlite.org/fts5.html#external_content_tables
229229

230+
if definition.configuration.temporary {
231+
// SQLite can't rebuild the index of temporary tables:
232+
//
233+
// sqlite> CREATE TABLE t(id INTEGER PRIMARY KEY, a, b, c);
234+
// sqlite> CREATE VIRTUAL TABLE temp.ft USING fts5(content="t",content_rowid="a",b,c);
235+
// sqlite> INSERT INTO ft(ft) VALUES('rebuild');
236+
// Runtime error: SQL logic error
237+
fatalError("Temporary external content FTS5 tables are not supported.")
238+
}
239+
230240
let rowIDColumn = try db.primaryKey(contentTable).rowIDColumn ?? Column.rowID.name
231241
let ftsTable = tableName.quotedDatabaseIdentifier
232242
let content = contentTable.quotedDatabaseIdentifier
@@ -274,7 +284,7 @@ extension FTS5: VirtualTableModule {
274284
/// virtual table.
275285
///
276286
/// You don't create instances of this class. Instead, you use the `Database`
277-
/// ``Database/create(virtualTable:ifNotExists:using:_:)`` method:
287+
/// ``Database/create(virtualTable:options:using:_:)`` method:
278288
///
279289
/// ```swift
280290
/// try db.create(virtualTable: "document", using: FTS5()) { t in // t is FTS5TableDefinition

GRDB/FTS/FTS5TokenizerDescriptor.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,14 @@ public struct FTS5TokenizerDescriptor: Sendable {
112112
if !separators.isEmpty {
113113
// TODO: test "=" and "\"", "(" and ")" as separators, with
114114
// both FTS3Pattern(matchingAnyTokenIn:tokenizer:)
115-
// and Database.create(virtualTable:using:)
115+
// and Database.create(virtualTable:options:using:_:)
116116
components.append("separators")
117117
components.append(separators.sorted().map { String($0) }.joined())
118118
}
119119
if !tokenCharacters.isEmpty {
120120
// TODO: test "=" and "\"", "(" and ")" as tokenCharacters, with
121121
// both FTS3Pattern(matchingAnyTokenIn:tokenizer:)
122-
// and Database.create(virtualTable:using:)
122+
// and Database.create(virtualTable:options:using:_:)
123123
components.append("tokenchars")
124124
components.append(tokenCharacters.sorted().map { String($0) }.joined())
125125
}
@@ -197,14 +197,14 @@ public struct FTS5TokenizerDescriptor: Sendable {
197197
if !separators.isEmpty {
198198
// TODO: test "=" and "\"", "(" and ")" as separators, with
199199
// both FTS3Pattern(matchingAnyTokenIn:tokenizer:)
200-
// and Database.create(virtualTable:using:)
200+
// and Database.create(virtualTable:options:using:_:)
201201
components.append("separators")
202202
components.append(separators.sorted().map { String($0) }.joined())
203203
}
204204
if !tokenCharacters.isEmpty {
205205
// TODO: test "=" and "\"", "(" and ")" as tokenCharacters, with
206206
// both FTS3Pattern(matchingAnyTokenIn:tokenizer:)
207-
// and Database.create(virtualTable:using:)
207+
// and Database.create(virtualTable:options:using:_:)
208208
components.append("tokenchars")
209209
components.append(tokenCharacters.sorted().map { String($0) }.joined())
210210
}

0 commit comments

Comments
 (0)