Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 15 additions & 6 deletions Sources/StructuredQueriesSQLiteCore/FTS5.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension TableDefinition where QueryValue: FTS5 {
public func bm25(
_ rankings: KeyValuePairs<PartialKeyPath<Self>, Double> = [:]
) -> some QueryExpression<Double> {
var queryFragments: [QueryFragment] = ["\(QueryValue.self)"]
var queryFragments: [QueryFragment] = ["\(quote: QueryValue.tableName)"]
if !rankings.isEmpty {
var columnNameToRanking: QueryFragment = """
CASE "name"
Expand Down Expand Up @@ -89,7 +89,12 @@ extension TableDefinition where QueryValue: FTS5 {
}
}

extension TableColumnExpression where Root: FTS5 {
extension TableColumnExpression
where
Root: FTS5,
Value.QueryOutput: _OptionalPromotable,
Value.QueryOutput._Optionalized.Wrapped: StringProtocol
{
/// A string expression highlighting matches in this column using the given delimiters.
///
/// - Parameters:
Expand All @@ -99,11 +104,11 @@ extension TableColumnExpression where Root: FTS5 {
public func highlight(
_ open: some StringProtocol,
_ close: some StringProtocol
) -> some QueryExpression<String> {
) -> some QueryExpression<Value> {
SQLQueryExpression(
"""
highlight(\
\(Root.self), \
\(quote: Root.tableName), \
(\(cid)),
\(quote: "\(open)", delimiter: .text), \
\(quote: "\(close)", delimiter: .text)\
Expand Down Expand Up @@ -139,11 +144,11 @@ extension TableColumnExpression where Root: FTS5 {
_ close: some StringProtocol,
_ ellipsis: some StringProtocol,
_ tokens: Int
) -> some QueryExpression<String> {
) -> some QueryExpression<Value> {
SQLQueryExpression(
"""
snippet(\
\(Root.self), \
\(quote: Root.tableName), \
(\(cid)),
\(quote: "\(open)", delimiter: .text), \
\(quote: "\(close)", delimiter: .text), \
Expand All @@ -165,3 +170,7 @@ extension TableColumnExpression {
)
}
}

extension Optional: FTS5 where Wrapped: FTS5 {}

extension TableAlias: FTS5 where Base: FTS5 {}
65 changes: 65 additions & 0 deletions Tests/StructuredQueriesTests/FTSTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,70 @@ extension SnapshotTests {
"""
}
}

@Test func outerJoin() {
assertQuery(
Reminder
.leftJoin(ReminderText.all) { $0.rowid.eq($1.rowid) }
.select { $1.tags.highlight("**", "**") }
.order { $1.bm25() }
) {
"""
SELECT highlight("reminderTexts", (SELECT "cid" FROM pragma_table_info('reminderTexts') WHERE "name" = 'tags'),
'**', '**')
FROM "reminders"
LEFT JOIN "reminderTexts" ON ("reminders"."rowid" = "reminderTexts"."rowid")
ORDER BY bm25("reminderTexts")
"""
} results: {
"""
┌────────────────────┐
│ "someday optional" │
│ "someday optional" │
│ "" │
│ "car kids" │
│ "" │
│ "" │
│ "" │
│ "" │
│ "" │
│ "" │
└────────────────────┘
"""
}
}

@Test func alias() {
enum RT: AliasName {}
assertQuery(
Reminder
.leftJoin(ReminderText.as(RT.self).all) { $0.rowid.eq($1.rowid) }
.select { $1.tags.highlight("**", "**") }
.order { $1.bm25() }
) {
"""
SELECT highlight("reminderTexts", (SELECT "cid" FROM pragma_table_info('reminderTexts') WHERE "name" = 'tags'),
'**', '**')
FROM "reminders"
LEFT JOIN "reminderTexts" AS "rTs" ON ("reminders"."rowid" = "rTs"."rowid")
ORDER BY bm25("reminderTexts")
"""
} results: {
"""
┌────────────────────┐
│ "someday optional" │
│ "someday optional" │
│ "" │
│ "car kids" │
│ "" │
│ "" │
│ "" │
│ "" │
│ "" │
│ "" │
└────────────────────┘
"""
}
}
}
}