Skip to content

Commit 3c08194

Browse files
authored
Merge pull request #54 (Add DuckDB querying)
Add DuckDB querying
2 parents cdf493c + d60ba73 commit 3c08194

File tree

15 files changed

+982
-42
lines changed

15 files changed

+982
-42
lines changed

.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,9 @@
22
"go.buildTags": "vtable fts5 sqlite_json sqlite_math_functions",
33
"yaml.schemas": {
44
"https://spec.openapis.org/oas/3.1/schema/2022-10-07": "file:///Users/julien/Code/anyquery/other/llm/openapi-actions.yaml"
5-
}
5+
},
6+
"go.lintFlags": [
7+
"-tags",
8+
"vtable fts5 sqlite_json sqlite_math_functions"
9+
]
610
}

controller/connection.go

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"path/filepath"
78
"regexp"
89
"slices"
910
"strings"
@@ -101,7 +102,7 @@ func ConnectionAdd(cmd *cobra.Command, args []string) error {
101102
if len(args) > 1 {
102103
databaseType = args[1]
103104
if !slices.Contains(namespace.SupportedConnections, databaseType) {
104-
return fmt.Errorf("unsupported connection type %s. Make sure it's one of %s. Also ensure Anyquery is up to date.", databaseType, strings.Join(namespace.SupportedConnections, ", "))
105+
return fmt.Errorf("unsupported connection type %s. Make sure it's one of %s. Also ensure Anyquery is up to date", databaseType, strings.Join(namespace.SupportedConnections, ", "))
105106
}
106107
} else {
107108
options := make([]huh.Option[string], len(namespace.SupportedConnections))
@@ -120,21 +121,37 @@ func ConnectionAdd(cmd *cobra.Command, args []string) error {
120121
return err
121122
}
122123
} else {
123-
/* urlExample := "username:password@tcp(host:1234)/database"
124-
switch databaseType {
125-
case "PostgreSQL":
126-
urlExample = "postgresql://user:password@host:port/database"
127-
case "SQLite":
128-
urlExample = "file:/path/to/database.db?mode=ro"
129-
case "ClickHouse":
130-
urlExample = "clickhouse://user:password@host:port/database"
131-
} */
124+
132125
fields = append(fields, huh.NewInput().
133-
Title("Connection string (URL)").
134-
Description(fmt.Sprintf("The connection string to the database. For example, for MySQL, it should be in the format `username:password@tcp(host:port)/database`.\n"+
135-
"Refer to https://anyquery.dev/docs/database/ for more information on the connection string format.")).
126+
TitleFunc(func() string {
127+
if databaseType == "SQLite" || databaseType == "DuckDB" {
128+
return "Database file path"
129+
}
130+
return "Connection string (URL)"
131+
}, &databaseType).
132+
DescriptionFunc(func() string {
133+
urlExample := "username:password@tcp(host:1234)/database"
134+
prefixConnectionString := "connection string for MySQL (see https://anyquery.dev/docs/database/mysql/#connection)"
135+
switch databaseType {
136+
case "PostgreSQL":
137+
urlExample = "postgresql://user:password@host:port/database"
138+
prefixConnectionString = "connection string for PostgreSQL (see https://anyquery.dev/docs/database/postgresql/#connection)"
139+
case "SQLite":
140+
urlExample = "file:/path/to/database.db?mode=ro"
141+
prefixConnectionString = "path to the SQLite database file (see https://anyquery.dev/docs/database/sqlite)"
142+
case "ClickHouse":
143+
urlExample = "clickhouse://user:password@host:port/database"
144+
prefixConnectionString = "connection string for ClickHouse (see https://anyquery.dev/docs/database/clickhouse/#connection)"
145+
case "DuckDB":
146+
urlExample = "/path/to/database.duckdb"
147+
prefixConnectionString = "path to the DuckDB database file (see https://anyquery.dev/docs/database/duckdb/)"
148+
}
149+
150+
return fmt.Sprintf("The %s. For example: `%s`.", prefixConnectionString, urlExample)
151+
}, &databaseType).
136152
Validate(validateConnectionURL).
137-
Value(&connectionString))
153+
Value(&connectionString),
154+
)
138155
}
139156
if len(args) > 3 {
140157
filter = args[3]
@@ -155,6 +172,10 @@ func ConnectionAdd(cmd *cobra.Command, args []string) error {
155172
}
156173
grp := huh.NewGroup(fields...).Title("Connection information").Description("Let's add a new database connection to Anyquery")
157174
err := huh.NewForm(grp).Run()
175+
if err == huh.ErrUserAborted {
176+
fmt.Println("👋 Bye (no connection added)")
177+
return nil
178+
}
158179
if err != nil {
159180
return fmt.Errorf("could not ask for the connection information: %w", err)
160181
}
@@ -164,6 +185,19 @@ func ConnectionAdd(cmd *cobra.Command, args []string) error {
164185
filter = "true" // Default filter to import all tables
165186
}
166187

188+
// In case the user adds a connection using DuckDB, if the path is relative, we make it absolute
189+
// If the user changes the CWD, Anyquery will still be able to find the DuckDB database file
190+
if databaseType == "DuckDB" {
191+
if !filepath.IsAbs(connectionString) {
192+
// Make the path absolute
193+
absPath, err := filepath.Abs(connectionString)
194+
if err != nil {
195+
return fmt.Errorf("could not make the path to the DuckDB database absolute: %w. Make sure the path is valid", err)
196+
}
197+
connectionString = absPath
198+
}
199+
}
200+
167201
// Add the connection
168202
err = querier.AddConnection(context.Background(), model.AddConnectionParams{
169203
Connectionname: connectionName,

go.mod

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ require (
3535
github.com/hashicorp/go-hclog v1.6.3
3636
github.com/hashicorp/go-plugin v1.6.3
3737
github.com/hjson/hjson-go/v4 v4.5.0
38-
github.com/huandu/go-sqlbuilder v1.35.0
38+
github.com/huandu/go-sqlbuilder v1.35.1
3939
github.com/jackc/pgx/v5 v5.7.5
4040
github.com/jmoiron/sqlx v1.4.0
4141
github.com/julien040/go-ternary v1.0.1
@@ -51,10 +51,10 @@ require (
5151
github.com/stretchr/testify v1.10.0
5252
github.com/trivago/grok v1.0.0
5353
github.com/twpayne/go-geom v1.6.1
54-
golang.org/x/crypto v0.38.0
54+
golang.org/x/crypto v0.39.0
5555
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6
56-
golang.org/x/mod v0.24.0
57-
golang.org/x/net v0.40.0
56+
golang.org/x/mod v0.25.0
57+
golang.org/x/net v0.41.0
5858
golang.org/x/term v0.32.0
5959
gopkg.in/yaml.v3 v3.0.1
6060
vitess.io/vitess v0.22.0
@@ -168,7 +168,7 @@ require (
168168
github.com/jmespath/go-jmespath v0.4.0 // indirect
169169
github.com/json-iterator/go v1.1.12 // indirect
170170
github.com/klauspost/compress v1.18.0 // indirect
171-
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
171+
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
172172
github.com/klauspost/reedsolomon v1.12.0 // indirect
173173
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
174174
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
@@ -266,9 +266,9 @@ require (
266266
go.uber.org/multierr v1.11.0 // indirect
267267
go.uber.org/zap v1.27.0 // indirect
268268
golang.org/x/oauth2 v0.30.0 // indirect
269-
golang.org/x/sync v0.14.0 // indirect
269+
golang.org/x/sync v0.15.0 // indirect
270270
golang.org/x/sys v0.33.0 // indirect
271-
golang.org/x/text v0.25.0 // indirect
271+
golang.org/x/text v0.26.0 // indirect
272272
golang.org/x/time v0.11.0 // indirect
273273
golang.org/x/tools v0.33.0 // indirect
274274
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect

go.sum

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,8 +1093,8 @@ github.com/hjson/hjson-go/v4 v4.5.0 h1:ZHLiZ+HaGqPOtEe8T6qY8QHnoEsAeBv8wqxniQAp+
10931093
github.com/hjson/hjson-go/v4 v4.5.0/go.mod h1:4zx6c7Y0vWcm8IRyVoQJUHAPJLXLvbG6X8nk1RLigSo=
10941094
github.com/huandu/go-assert v1.1.6 h1:oaAfYxq9KNDi9qswn/6aE0EydfxSa+tWZC1KabNitYs=
10951095
github.com/huandu/go-assert v1.1.6/go.mod h1:JuIfbmYG9ykwvuxoJ3V8TB5QP+3+ajIA54Y44TmkMxs=
1096-
github.com/huandu/go-sqlbuilder v1.35.0 h1:ESvxFHN8vxCTudY1Vq63zYpU5yJBESn19sf6k4v2T5Q=
1097-
github.com/huandu/go-sqlbuilder v1.35.0/go.mod h1:mS0GAtrtW+XL6nM2/gXHRJax2RwSW1TraavWDFAc1JA=
1096+
github.com/huandu/go-sqlbuilder v1.35.1 h1:znTuAksxq3T1rYfr3nsD4P0brWDY8qNzdZnI6+vtia4=
1097+
github.com/huandu/go-sqlbuilder v1.35.1/go.mod h1:mS0GAtrtW+XL6nM2/gXHRJax2RwSW1TraavWDFAc1JA=
10981098
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
10991099
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
11001100
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
@@ -1141,8 +1141,8 @@ github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrD
11411141
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
11421142
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
11431143
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
1144-
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
1145-
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
1144+
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
1145+
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
11461146
github.com/klauspost/reedsolomon v1.12.0 h1:I5FEp3xSwVCcEh3F5A7dofEfhXdF/bWhQWPH+XwBFno=
11471147
github.com/klauspost/reedsolomon v1.12.0/go.mod h1:EPLZJeh4l27pUGC3aXOjheaoh1I9yut7xTURiW3LQ9Y=
11481148
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -1534,8 +1534,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
15341534
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
15351535
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
15361536
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
1537-
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
1538-
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
1537+
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
1538+
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
15391539
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
15401540
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
15411541
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1598,8 +1598,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
15981598
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
15991599
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
16001600
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
1601-
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
1602-
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
1601+
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
1602+
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
16031603
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
16041604
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
16051605
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1666,8 +1666,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
16661666
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
16671667
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
16681668
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
1669-
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
1670-
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
1669+
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
1670+
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
16711671
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
16721672
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
16731673
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1719,8 +1719,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
17191719
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
17201720
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
17211721
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
1722-
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
1723-
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
1722+
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
1723+
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
17241724
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
17251725
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
17261726
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1857,8 +1857,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
18571857
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
18581858
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
18591859
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
1860-
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
1861-
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
1860+
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
1861+
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
18621862
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
18631863
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
18641864
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

module/clickhouse.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import (
1717
"github.com/mattn/go-sqlite3"
1818
)
1919

20-
var clickhouseSuffix = "/* Query sent by Anyquery */"
21-
2220
var fetchClickHouseSchemaSQLQuery = `
2321
SELECT DISTINCT
2422
lower(table_schema),

module/db_helper.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,109 @@ func constructSQLQuery(
122122
return
123123
}
124124

125+
// Same as constructSQLQuery, but omit columns that are not queried
126+
func efficientConstructSQLQuery(
127+
cst []sqlite3.InfoConstraint,
128+
ob []sqlite3.InfoOrderBy,
129+
columns []databaseColumn,
130+
table string,
131+
colUsed uint64,
132+
133+
) (query *sqlbuilder.SelectBuilder, limit int, offset int, used []bool) {
134+
135+
// Initialize the SQL query builder
136+
query = sqlbuilder.NewSelectBuilder()
137+
// Add all the columns to the query
138+
cols := []string{}
139+
for i, col := range columns {
140+
if colUsed&(1<<i) == 0 && i < 62 { // colUsed is a bitmask, and the 63rd bit is reserved to say, it means more columns are used
141+
// If the column is not used, we skip it
142+
continue
143+
}
144+
cols = append(cols, col.Realname)
145+
}
146+
147+
query.Select(cols...).From(table)
148+
149+
// Add the constraints (where, limit, offset)
150+
limit = -1
151+
offset = -1
152+
153+
used = make([]bool, len(cst))
154+
155+
andConditions := []string{}
156+
j := 0
157+
for i, c := range cst {
158+
// If the constraint is not usable, we skip it
159+
if !c.Usable {
160+
continue
161+
}
162+
// Note the LIMIT and OFFSET constraints indexes in the constraints
163+
if c.Op == sqlite3.OpLIMIT {
164+
limit = j
165+
used[i] = true
166+
j++
167+
continue
168+
} else if c.Op == sqlite3.OpOFFSET {
169+
offset = j
170+
used[i] = true
171+
j++
172+
continue
173+
}
174+
175+
// If we don't have information about the column, we skip it
176+
if c.Column < 0 || c.Column >= len(columns) {
177+
continue
178+
}
179+
180+
// If the column is not supported, we skip it
181+
colInfo := columns[c.Column]
182+
if !colInfo.Supported {
183+
continue
184+
}
185+
186+
switch c.Op {
187+
case sqlite3.OpEQ:
188+
andConditions = append(andConditions, query.Equal(colInfo.Realname, colInfo.DefaultValue))
189+
case sqlite3.OpGT:
190+
andConditions = append(andConditions, query.GreaterThan(colInfo.Realname, colInfo.DefaultValue))
191+
case sqlite3.OpGE:
192+
andConditions = append(andConditions, query.GreaterEqualThan(colInfo.Realname, colInfo.DefaultValue))
193+
case sqlite3.OpLT:
194+
andConditions = append(andConditions, query.LessThan(colInfo.Realname, colInfo.DefaultValue))
195+
case sqlite3.OpLE:
196+
andConditions = append(andConditions, query.LessEqualThan(colInfo.Realname, colInfo.DefaultValue))
197+
case sqlite3.OpLIKE:
198+
andConditions = append(andConditions, query.Like(colInfo.Realname, colInfo.DefaultValue))
199+
case sqlite3.OpGLOB:
200+
// Not supported
201+
continue
202+
case sqlite3.OpREGEXP:
203+
// Not supported
204+
continue
205+
case sqlite3.OpLIMIT:
206+
limit = int(c.Column)
207+
case sqlite3.OpOFFSET:
208+
offset = int(c.Column)
209+
}
210+
used[i] = true
211+
j++
212+
}
213+
214+
query.Where(andConditions...)
215+
216+
// Add the order by
217+
for _, o := range ob {
218+
if o.Desc {
219+
query.OrderBy(columns[o.Column].Realname + " DESC")
220+
} else {
221+
query.OrderBy(columns[o.Column].Realname + " ASC")
222+
}
223+
}
224+
225+
return
226+
}
227+
125228
type SQLQueryToExecute struct {
126229
// The SQL query to execute
127230
Query string
@@ -134,6 +237,9 @@ type SQLQueryToExecute struct {
134237

135238
// The index in the constraints for the offset (-1 if not present)
136239
OffsetIndex int
240+
241+
// The columns used in the query
242+
ColumnsUsed uint64
137243
}
138244

139245
func castInt(value interface{}) int64 {

0 commit comments

Comments
 (0)