Skip to content

Commit 1f618b1

Browse files
committed
fix, test
1 parent 9ed42a9 commit 1f618b1

2 files changed

Lines changed: 120 additions & 24 deletions

File tree

src/QuerySQLite.jl

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
module QuerySQLite
22

33
import Base: !, &, |, ==, !=, coalesce, getproperty, in, isequal, isless, ismissing, occursin, startswith
4-
using Base: NamedTuple, tail
4+
using Base: Generator, NamedTuple, tail
55
import Base.Iterators: drop, take
66
using Base.Meta: quot
77
import DataFrames: DataFrame
88
import MacroTools
99
using MacroTools: @capture
1010
import QueryOperators
11-
import QueryOperators: query
11+
import QueryOperators: orderby, query
1212
import SQLite
1313
using SQLite: columns, DB, tables
1414

@@ -185,14 +185,15 @@ translate_call(::typeof(backwards), column) =
185185
translate_call(::typeof(coalesce), arguments...) =
186186
string("COALESCE(", join(map_unrolled(translate, arguments...), ", "), ")")
187187

188-
@code_instead distinct OutsideCode
189-
translate_call(::typeof(distinct), repeated) =
190-
replace(translate(repeated), r"\bSELECT\b" => "SELECT DISTINCT")
191-
192188
@code_instead drop OutsideCode Integer
193189
translate_call(::typeof(drop), iterator, number) =
194190
string(translate(iterator), " OFFSET ", number)
195191

192+
change_row(::typeof(getproperty), outside_tables::OutsideTables, table_name) =
193+
model_row(OutsideTable(outside_tables.outside, table_name))
194+
translate_call(::typeof(getproperty), outside_row::OutsideRow, column_name) =
195+
column_name
196+
196197
"""
197198
if_else(switch, yes, no)
198199
@@ -252,23 +253,54 @@ translate_call(::typeof(isless), left, right) =
252253
translate_call(::typeof(ismissing), maybe) =
253254
string(translate(maybe), " IS NULL")
254255

255-
@code_instead QueryOperators.filter OutsideCode Any
256-
translate_call(::typeof(QueryOperators.filter), iterator, call) =
256+
@code_instead QueryOperators.drop OutsideCode Integer
257+
translate_call(::typeof(QueryOperators.drop), iterator, number) =
258+
string(translate(iterator), " OFFSET ", number)
259+
260+
@code_instead QueryOperators.filter OutsideCode Any Expr
261+
translate_call(::typeof(QueryOperators.filter), iterator, call, call_expression) =
257262
string(
258263
translate(iterator),
259264
" WHERE ",
260265
translate(call(model_row(iterator)).code)
261266
)
262267

263-
@code_instead QueryOperators.map OutsideCode Any
264-
change_row(::typeof(QueryOperators.map), iterator, call) = call(model_row(iterator))
265-
select_as((name, model)::Tuple{Symbol, OutsideCode}) =
266-
string(translate(model.code), " AS ", name)
267-
function translate_call(::typeof(QueryOperators.map), select_table, call)
268+
@code_instead QueryOperators.orderby OutsideCode Any Expr
269+
translate_call(::typeof(QueryOperators.orderby), unordered, key_function, key_function_expression) = string(
270+
translate(unordered),
271+
" ORDER BY ",
272+
translate(key_function(model_row(unordered)).code)
273+
)
274+
@code_instead QueryOperators.thenby OutsideCode Any Expr
275+
translate_call(::typeof(QueryOperators.thenby), unordered, key_function, key_function_expression) = string(
276+
translate(unordered),
277+
", ",
278+
translate(key_function(model_row(unordered)).code)
279+
)
280+
@code_instead QueryOperators.orderby_descending OutsideCode Any Expr
281+
translate_call(::typeof(QueryOperators.orderby_descending), unordered, key_function, key_function_expression) = string(
282+
translate(unordered),
283+
" ORDER BY ",
284+
translate(key_function(model_row(unordered)).code),
285+
" DESC"
286+
)
287+
@code_instead QueryOperators.thenby_descending OutsideCode Any Expr
288+
translate_call(::typeof(QueryOperators.thenby_descending), unordered, key_function, key_function_expression) = string(
289+
translate(unordered),
290+
", ",
291+
translate(key_function(model_row(unordered)).code),
292+
"DESC"
293+
)
294+
295+
@code_instead QueryOperators.map OutsideCode Any Expr
296+
change_row(::typeof(QueryOperators.map), iterator, call, call_expression) = call(model_row(iterator))
297+
select_as(new_name_model::Pair{Symbol, <: OutsideCode}) =
298+
string(translate(new_name_model.second.code), " AS ", new_name_model.first)
299+
function translate_call(::typeof(QueryOperators.map), select_table, call, call_expression)
268300
if @capture select_table $getproperty(outsidetables_OutsideTables, name_)
269301
string(
270302
"SELECT ",
271-
join(map_unrolled(select_as, pairs(call(model_row(select_table)))), ", "),
303+
join(Generator(select_as, pairs(call(model_row(select_table)))), ", "),
272304
" FROM ",
273305
name
274306
)
@@ -277,6 +309,30 @@ function translate_call(::typeof(QueryOperators.map), select_table, call)
277309
end
278310
end
279311

312+
@code_instead QueryOperators.take OutsideCode Any
313+
translate_call(::typeof(QueryOperators.take), iterator, number) =
314+
if @capture iterator $(QueryOperators.drop)(inneriterator_, offset_)
315+
string(
316+
translate(inneriterator),
317+
" LIMIT ",
318+
number,
319+
" OFFSET ",
320+
offset
321+
)
322+
else
323+
string(translate(iterator), " LIMIT ", number)
324+
end
325+
326+
@code_instead QueryOperators.unique OutsideCode Any Expr
327+
function translate_call(::typeof(QueryOperators.unique), repeated, key_function, key_function_expression)
328+
model = model_row(repeated)
329+
if key_function(model) !== model
330+
error("Key functions not supported for unique")
331+
else
332+
replace(translate(repeated), r"\bSELECT\b" => "SELECT DISTINCT")
333+
end
334+
end
335+
280336
@code_instead occursin AbstractString OutsideCode
281337
@code_instead occursin Regex OutsideCode
282338
translate_call(::typeof(occursin), needle::AbstractString, haystack) = string(
@@ -296,8 +352,21 @@ translate_call(::typeof(occursin), needle, haystack) = string(
296352
translate(needle)
297353
)
298354

355+
make_outside_column(outside_table, column_name) =
356+
OutsideCode(
357+
outside_table.outside,
358+
Expr(:call, getproperty, OutsideRow(outside_table), column_name)
359+
)
360+
function model_row(outside_table::OutsideTable)
361+
column_names = get_column_names(outside_table.outside, outside_table.table_name)
362+
NamedTuple{column_names}(partial_map(
363+
make_outside_column,
364+
outside_table,
365+
column_names
366+
))
367+
end
299368
translate(outside_table::OutsideTable) =
300-
string("SELECT * FROM ", check_table)
369+
string("SELECT * FROM ", outside_table.table_name)
301370

302371
@code_instead startswith OutsideCode Any
303372
@code_instead startswith Any OutsideCode
@@ -327,10 +396,10 @@ translate_call(::typeof(take), iterator, number) =
327396

328397
change_row(arbitrary_function, iterator, arguments...) = model_row(iterator)
329398

330-
ignore_name((new_name, model)::Tuple{Symbol, OutsideCode}) =
331-
translate(model.code)
399+
ignore_name(new_name_model::Pair{Symbol, <: OutsideCode}) =
400+
translate(new_name_model.second.code)
332401

333-
column_or_columns(row::NamedTuple) = map_unrolled(ignore_name, pairs(row))
402+
column_or_columns(row::NamedTuple) = map(ignore_name, (pairs(row)...,))
334403
column_or_columns(outside_code::OutsideCode) = (translate(outside_code.code),)
335404

336405
# SQLite interface

test/runtests.jl

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,43 @@
1-
using QuerySQLite
21
using Query
3-
using QueryTables
4-
using Test
2+
using Test: @test, @testset
53

64
@testset "QuerySQLite" begin
75

86
filename = joinpath(@__DIR__, "Chinook_Sqlite.sqlite")
97

10-
c = SQLiteConnection(filename)
8+
database = NamedTuple(OutsideTables(DB(filename)))
119

12-
dt = c.Album |> @filter(_.a > 3) |> @mutate(c = _.a * 3) |> DataTable
10+
database.Album |> @rename(:AlbumId => :AlbumId2) |> @filter(_.AlbumId2 > 3) |> DataFrame
1311

14-
@test length(dt)==347
12+
@test names(database.Track |>
13+
@map({_.TrackId, _.Name, _.Composer, _.UnitPrice}) |>
14+
DataFrame) == [:TrackId, :Name, :Composer, :UnitPrice]
15+
16+
@test (database.Customer |>
17+
@map({_.City, _.Country}) |>
18+
@orderby(_.Country) |>
19+
DataFrame).Country[1] == "Argentina"
20+
21+
@test length((database.Customer |>
22+
@map({_.City}) |>
23+
@unique() |>
24+
DataFrame).City) == 53
25+
26+
@test length((database.Track |>
27+
@map({_.TrackId, _.Name}) |>
28+
@take(10) |>
29+
DataFrame).Name) == 10
30+
31+
@test first((database.Track |>
32+
@map({_.TrackId, _.Name}) |>
33+
@drop(10) |>
34+
@take(10) |>
35+
DataFrame).Name) == "C.O.D."
36+
37+
@test first((database.Track |>
38+
@map({_.TrackId, _.Name, _.Bytes}) |>
39+
@orderby_descending(_.Bytes) |>
40+
@thenby(_.Name) |>
41+
DataFrame).Bytes) == 1059546140
1542

1643
end

0 commit comments

Comments
 (0)