-
-
Notifications
You must be signed in to change notification settings - Fork 171
JSON select support for sqlite #536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
934c02b
42a0d9c
386f742
1c89a01
b390687
02a42f4
32e9a07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ package sqlite | |
| import ( | ||
| "encoding/hex" | ||
| "fmt" | ||
|
|
||
| "github.com/go-jet/jet/v2/internal/jet" | ||
| ) | ||
|
|
||
|
|
@@ -29,6 +30,24 @@ func newDialect() jet.Dialect { | |
| ValuesDefaultColumnName: func(index int) string { | ||
| return fmt.Sprintf("column%d", index+1) | ||
| }, | ||
| JsonValueEncode: func(expr Expression) Expression { | ||
| switch e := expr.(type) { | ||
| case BlobExpression: | ||
| return TO_BASE64(e) | ||
|
|
||
| // CustomExpression used bellow (instead DATE_FORMAT function) so that only expr is parametrized | ||
| case TimestampExpression: | ||
| return CustomExpression(Token("strftime('%Y-%m-%dT%H:%M:%fZ', "), e, Token(")")) | ||
| case TimeExpression: | ||
| return CustomExpression(Token("strftime('%Y-%m-%dT%H:%M:%fZ', "), e, Token(")")) | ||
| case DateExpression: | ||
| return CustomExpression(Token("strftime('%Y-%m-%dT00:00:00Z', "), e, Token(")")) | ||
| case BoolExpression: | ||
| return CustomExpression(Token("CASE"), e, Token("WHEN 1 THEN json('true') ELSE json('false') END")) | ||
| } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All this types needs to be covered by tests as well. Check
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay I will take a look at the mysql tests and add them to the sqlite tests as well |
||
|
|
||
| return expr | ||
| }, | ||
| } | ||
|
|
||
| return jet.NewDialect(mySQLDialectParams) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| package sqlite | ||
|
|
||
| import ( | ||
| "github.com/go-jet/jet/v2/internal/jet" | ||
| ) | ||
|
|
||
| type SelectJsonStatement interface { | ||
| Statement | ||
| jet.Serializer | ||
|
|
||
| AS(alias string) Projection | ||
|
|
||
| FROM(table ReadableTable) SelectJsonStatement | ||
| WHERE(condition BoolExpression) SelectJsonStatement | ||
| ORDER_BY(orderByClauses ...OrderByClause) SelectJsonStatement | ||
| LIMIT(limit int64) SelectJsonStatement | ||
| OFFSET(offset int64) SelectJsonStatement | ||
| } | ||
|
|
||
| // SELECT_JSON_ARR creates a new SelectJsonStatement with a list of projections. | ||
| func SELECT_JSON_ARR(projections ...Projection) SelectJsonStatement { | ||
| return newSelectStatementJson(projections, jet.SelectJsonArrStatementType) | ||
| } | ||
|
|
||
| // SELECT_JSON_OBJ creates a new SelectJsonStatement with a list of projections. | ||
| func SELECT_JSON_OBJ(projections ...Projection) SelectJsonStatement { | ||
| return newSelectStatementJson(projections, jet.SelectJsonObjStatementType) | ||
| } | ||
|
|
||
| type selectJsonStatement struct { | ||
| *selectStatementImpl | ||
| } | ||
|
|
||
| func newSelectStatementJson(projections []Projection, statementType jet.StatementType) SelectJsonStatement { | ||
| newSelect := &selectJsonStatement{ | ||
| selectStatementImpl: newSelectStatement(statementType, nil, nil), | ||
| } | ||
|
|
||
| newSelect.Select.ProjectionList = ProjectionList{constructJsonFunc(projections, statementType).AS("json")} | ||
|
|
||
| return newSelect | ||
| } | ||
|
|
||
| func constructJsonFunc(projections []Projection, statementType jet.StatementType) Expression { | ||
| jsonObj := Func("JSON_OBJECT", CustomExpression(jet.JsonObjProjectionList(projections))) | ||
|
|
||
| if statementType == jet.SelectJsonArrStatementType { | ||
| return Func("JSON_GROUP_ARRAY", jsonObj) | ||
| } | ||
|
|
||
| return jsonObj | ||
| } | ||
|
|
||
| func (s *selectJsonStatement) FROM(table ReadableTable) SelectJsonStatement { | ||
| s.From.Tables = []jet.Serializer{table} | ||
|
|
||
| return s | ||
| } | ||
|
|
||
| func (s *selectJsonStatement) WHERE(condition BoolExpression) SelectJsonStatement { | ||
| s.Where.Condition = condition | ||
| return s | ||
| } | ||
|
|
||
| func (s *selectJsonStatement) ORDER_BY(orderByClauses ...OrderByClause) SelectJsonStatement { | ||
| s.OrderBy.List = orderByClauses | ||
| return s | ||
| } | ||
|
|
||
| func (s *selectJsonStatement) LIMIT(limit int64) SelectJsonStatement { | ||
| s.Limit.Count = limit | ||
| return s | ||
| } | ||
|
|
||
| func (s *selectJsonStatement) OFFSET(offset int64) SelectJsonStatement { | ||
| s.Offset.Count = Int(offset) | ||
| return s | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this code is ever called in your tests. This case is active only when SELECT_JSON appears as a column inside regular SELECT statement - wiki.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, now that I check, it seems that this test is missing for mysql.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is needed though since I was using the select_json inside a regular select in my own code and otherwise there was convert error. I can copy the tests from postgres into sqlite to see check if all cases work correctly. The tests for mysql should probably be in another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that makes sense.