@@ -11,7 +11,6 @@ import (
1111 "time"
1212
1313 sq "github.com/Masterminds/squirrel"
14- q "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/storage/driver/sql/query"
1514 common2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/storage/driver/sql/query/common"
1615 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/storage/driver/sql/query/cond"
1716 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/storage/driver/sql/sqlite"
@@ -26,48 +25,48 @@ func TestTransactionSql(t *testing.T) {
2625 testCases := []struct {
2726 name string
2827 params driver2.QueryTransactionsParams
29- expectedArgs []common2. Param
28+ expectedArgs []any
3029 expectedSql string
3130 }{
3231 {
3332 name : "No params" ,
3433 params : driver2.QueryTransactionsParams {},
35- expectedSql : "1 = 1 " ,
36- expectedArgs : []common2. Param {},
34+ expectedSql : "" ,
35+ expectedArgs : []any {},
3736 },
3837 {
3938 name : "Only confirmed" ,
4039 params : driver2.QueryTransactionsParams {
4140 Statuses : []driver2.TxStatus {driver2 .Confirmed },
4241 },
43- expectedSql : "(status = $1 )" ,
44- expectedArgs : []common2. Param {driver2 .Confirmed },
42+ expectedSql : "(status IN ($1) )" ,
43+ expectedArgs : []any {driver2 .Confirmed },
4544 },
4645 {
4746 name : "Pending or deleted" ,
4847 params : driver2.QueryTransactionsParams {
4948 Statuses : []driver2.TxStatus {driver2 .Pending , driver2 .Deleted },
5049 },
51- expectedSql : "(( status) IN (($1), ($2) ))" ,
52- expectedArgs : []common2. Param {driver2 .Pending , driver2 .Deleted },
50+ expectedSql : "(status IN ($1,$2 ))" ,
51+ expectedArgs : []any {driver2 .Pending , driver2 .Deleted },
5352 },
5453 {
5554 name : "Confirmed from any (only setting sender should return all)" ,
5655 params : driver2.QueryTransactionsParams {
5756 SenderWallet : "alice" ,
5857 Statuses : []driver2.TxStatus {driver2 .Confirmed },
5958 },
60- expectedSql : "(status = $1 )" ,
61- expectedArgs : []common2. Param {driver2 .Confirmed },
59+ expectedSql : "(status IN ($1) )" ,
60+ expectedArgs : []any {driver2 .Confirmed },
6261 },
6362 {
6463 name : "Sender OR recipient matches" ,
6564 params : driver2.QueryTransactionsParams {
6665 SenderWallet : "alice" ,
6766 RecipientWallet : "bob" ,
6867 },
69- expectedSql : "((sender_eid = $1) OR ( recipient_eid = $2))" ,
70- expectedArgs : []common2. Param {"alice" , "bob" },
68+ expectedSql : "((sender_eid = $1 OR recipient_eid = $2))" ,
69+ expectedArgs : []any {"alice" , "bob" },
7170 },
7271 {
7372 name : "Sender OR recipient matches, from last year" ,
@@ -76,17 +75,17 @@ func TestTransactionSql(t *testing.T) {
7675 RecipientWallet : "alice" ,
7776 From : & lastYear ,
7877 },
79- expectedSql : "(( tbl.stored_at >= $1)) AND (( sender_eid = $2) OR ( recipient_eid = $3))" ,
80- expectedArgs : []common2. Param {& lastYear , "alice" , "alice" },
78+ expectedSql : "(tbl.stored_at >= $1 AND (sender_eid = $2 OR recipient_eid = $3))" ,
79+ expectedArgs : []any {& lastYear , "alice" , "alice" },
8180 },
8281 {
8382 name : "From last year to now" ,
8483 params : driver2.QueryTransactionsParams {
8584 To : & now ,
8685 From : & lastYear ,
8786 },
88- expectedSql : "(( tbl.stored_at >= $1) AND ( tbl.stored_at <= $2) )" ,
89- expectedArgs : []common2. Param {& lastYear , & now },
87+ expectedSql : "(tbl.stored_at >= $1 AND tbl.stored_at <= $2)" ,
88+ expectedArgs : []any {& lastYear , & now },
9089 },
9190 {
9291 name : "Sender OR recipient matches, specific tx" ,
@@ -95,8 +94,8 @@ func TestTransactionSql(t *testing.T) {
9594 RecipientWallet : "bob" ,
9695 IDs : []string {"transactionID" },
9796 },
98- expectedSql : "(tbl.tx_id = $1) AND (( sender_eid = $2) OR ( recipient_eid = $3))" ,
99- expectedArgs : []common2. Param {"transactionID" , "alice" , "bob" },
97+ expectedSql : "(tbl.tx_id IN ( $1) AND (sender_eid = $2 OR recipient_eid = $3))" ,
98+ expectedArgs : []any {"transactionID" , "alice" , "bob" },
10099 },
101100 {
102101 name : "Sender OR recipient matches, specific tx ids" ,
@@ -105,22 +104,30 @@ func TestTransactionSql(t *testing.T) {
105104 RecipientWallet : "bob" ,
106105 IDs : []string {"transactionID1" , "transactionID2" , "transactionID3" },
107106 },
108- expectedSql : "(( tbl.tx_id) IN (($1), ($2), ( $3))) AND (( sender_eid = $4) OR ( recipient_eid = $5))" ,
109- expectedArgs : []common2. Param {"transactionID1" , "transactionID2" , "transactionID3" , "alice" , "bob" },
107+ expectedSql : "(tbl.tx_id IN ($1,$2, $3) AND (sender_eid = $4 OR recipient_eid = $5))" ,
108+ expectedArgs : []any {"transactionID1" , "transactionID2" , "transactionID3" , "alice" , "bob" },
110109 },
111110 {
112111 name : "With Token Types" ,
113112 params : driver2.QueryTransactionsParams {
114113 TokenTypes : []token.Type {"Pineapple" },
115114 },
116- expectedSql : "(token_type = $1 )" ,
117- expectedArgs : []common2. Param { "Pineapple" },
115+ expectedSql : "(token_type IN ($1) )" ,
116+ expectedArgs : []any { token . Type ( "Pineapple" ) },
118117 },
119118 }
120119
121120 for _ , tc := range testCases {
122121 t .Run (tc .name , func (t * testing.T ) {
123- actualSql , actualArgs := evalCondition (HasTransactionParams (tc .params , q .Table ("tbl" )))
122+ sqlizer := HasTransactionParams (tc .params , "tbl" )
123+ if sqlizer == nil {
124+ assert .Empty (t , tc .expectedSql )
125+ assert .Empty (t , tc .expectedArgs )
126+
127+ return
128+ }
129+ actualSql , actualArgs , err := evalSqlizer (sqlizer )
130+ assert .NoError (t , err )
124131 assert .Equal (t , tc .expectedSql , actualSql )
125132 compareArgs (t , tc .expectedArgs , actualArgs )
126133 })
@@ -131,52 +138,52 @@ func TestMovementConditions(t *testing.T) {
131138 testCases := []struct {
132139 name string
133140 params driver2.QueryMovementsParams
134- expectedArgs []common2. Param
141+ expectedArgs []any
135142 expectedSql string
136143 }{
137144 {
138145 name : "All" ,
139146 params : driver2.QueryMovementsParams {
140147 MovementDirection : driver2 .All ,
141148 },
142- expectedSql : "(status != $1)" ,
143- expectedArgs : []common2. Param { 3 },
149+ expectedSql : "(status <> $1)" ,
150+ expectedArgs : []any { driver2 . Deleted },
144151 },
145152 {
146153 name : "Max 5" ,
147154 params : driver2.QueryMovementsParams {
148155 NumRecords : 5 ,
149156 MovementDirection : driver2 .All ,
150157 },
151- expectedSql : "(status != $1)" ,
152- expectedArgs : []common2. Param { 3 },
158+ expectedSql : "(status <> $1)" ,
159+ expectedArgs : []any { driver2 . Deleted },
153160 },
154161 {
155162 name : "Only enrollment ids" ,
156163 params : driver2.QueryMovementsParams {
157164 EnrollmentIDs : []string {"eid1" , "eid2" , "eid3" },
158165 MovementDirection : driver2 .All ,
159166 },
160- expectedSql : "(( enrollment_id) IN (($1), ($2), ( $3))) AND ( status != $4)" ,
161- expectedArgs : []common2. Param {"eid1" , "eid2" , "eid3" , 3 },
167+ expectedSql : "(enrollment_id IN ($1,$2, $3) AND status <> $4)" ,
168+ expectedArgs : []any {"eid1" , "eid2" , "eid3" , driver2 . Deleted },
162169 },
163170 {
164171 name : "Only confirmed" ,
165172 params : driver2.QueryMovementsParams {
166173 TxStatuses : []driver2.TxStatus {driver2 .Confirmed },
167174 MovementDirection : driver2 .All ,
168175 },
169- expectedSql : "(status = $1 )" ,
170- expectedArgs : []common2. Param {driver2 .Confirmed },
176+ expectedSql : "(status IN ($1) )" ,
177+ expectedArgs : []any {driver2 .Confirmed },
171178 },
172179 {
173180 name : "Pending and deleted" ,
174181 params : driver2.QueryMovementsParams {
175182 TxStatuses : []driver2.TxStatus {driver2 .Pending , driver2 .Deleted },
176183 MovementDirection : driver2 .All ,
177184 },
178- expectedSql : "(( status) IN (($1), ($2) ))" ,
179- expectedArgs : []common2. Param {driver2 .Pending , driver2 .Deleted },
185+ expectedSql : "(status IN ($1,$2 ))" ,
186+ expectedArgs : []any {driver2 .Pending , driver2 .Deleted },
180187 },
181188 {
182189 name : "Confirmed from alice" ,
@@ -185,8 +192,8 @@ func TestMovementConditions(t *testing.T) {
185192 TxStatuses : []driver2.TxStatus {driver2 .Confirmed },
186193 MovementDirection : driver2 .All ,
187194 },
188- expectedSql : "(enrollment_id = $1) AND ( status = $2 )" ,
189- expectedArgs : []common2. Param {"alice" , driver2 .Confirmed },
195+ expectedSql : "(enrollment_id IN ( $1) AND status IN ($2) )" ,
196+ expectedArgs : []any {"alice" , driver2 .Confirmed },
190197 },
191198 {
192199 name : "Confirmed ABC and XYZ from alice" ,
@@ -196,8 +203,8 @@ func TestMovementConditions(t *testing.T) {
196203 TokenTypes : []token.Type {"ABC" , "XYZ" },
197204 MovementDirection : driver2 .All ,
198205 },
199- expectedSql : "(enrollment_id = $1) AND (( token_type) IN (($2), ( $3))) AND ( status = $4 )" ,
200- expectedArgs : []common2. Param {"alice" , "ABC" , "XYZ" , driver2 .Confirmed },
206+ expectedSql : "(enrollment_id IN ( $1) AND token_type IN ($2, $3) AND status IN ($4) )" ,
207+ expectedArgs : []any {"alice" , token . Type ( "ABC" ), token . Type ( "XYZ" ) , driver2 .Confirmed },
201208 },
202209 {
203210 name : "Max 5 confirmed ABC and XYZ from alice" ,
@@ -208,8 +215,8 @@ func TestMovementConditions(t *testing.T) {
208215 NumRecords : 5 ,
209216 MovementDirection : driver2 .All ,
210217 },
211- expectedSql : "(enrollment_id = $1) AND (( token_type) IN (($2), ( $3))) AND ( status = $4 )" ,
212- expectedArgs : []common2. Param {"alice" , "ABC" , "XYZ" , driver2 .Confirmed },
218+ expectedSql : "(enrollment_id IN ( $1) AND token_type IN ($2, $3) AND status IN ($4) )" ,
219+ expectedArgs : []any {"alice" , token . Type ( "ABC" ), token . Type ( "XYZ" ) , driver2 .Confirmed },
213220 },
214221 {
215222 name : "Sent XYZ from alice" ,
@@ -218,8 +225,8 @@ func TestMovementConditions(t *testing.T) {
218225 TokenTypes : []token.Type {"XYZ" },
219226 MovementDirection : driver2 .Sent ,
220227 },
221- expectedSql : "(enrollment_id = $1) AND ( token_type = $2) AND ( status != $3) AND ( amount < $4)" ,
222- expectedArgs : []common2. Param {"alice" , "XYZ" , 3 , 0 },
228+ expectedSql : "(enrollment_id IN ( $1) AND token_type IN ( $2) AND status <> $3 AND amount < $4)" ,
229+ expectedArgs : []any {"alice" , token . Type ( "XYZ" ), driver2 . Deleted , 0 },
223230 },
224231 {
225232 name : "2 last pending received" ,
@@ -229,14 +236,15 @@ func TestMovementConditions(t *testing.T) {
229236 MovementDirection : driver2 .Received ,
230237 NumRecords : 2 ,
231238 },
232- expectedSql : "(status = $1) AND ( amount > $2)" ,
233- expectedArgs : []common2. Param {driver2 .Pending , 0 },
239+ expectedSql : "(status IN ( $1) AND amount > $2)" ,
240+ expectedArgs : []any {driver2 .Pending , 0 },
234241 },
235242 }
236243
237244 for _ , tc := range testCases {
238245 t .Run (tc .name , func (t * testing.T ) {
239- actualSql , actualArgs := evalCondition (HasMovementsParams (tc .params ))
246+ actualSql , actualArgs , err := evalSqlizer (HasMovementsParams (tc .params ))
247+ assert .NoError (t , err )
240248 assert .Equal (t , tc .expectedSql , actualSql )
241249 compareArgs (t , tc .expectedArgs , actualArgs )
242250 })
@@ -334,24 +342,6 @@ func TestTokenSql(t *testing.T) {
334342 assert .Len (t , args , 6 )
335343}
336344
337- func evalCondition (condition cond.Condition ) (string , []common2.Param ) {
338- sb := common2 .NewBuilder ()
339- condition .WriteString (sqlite .NewConditionInterpreter (), sb )
340- actualSql , actualArgs := sb .Build ()
341-
342- return actualSql , actualArgs
343- }
344-
345- // evalSqlizer converts a sq.Sqlizer to (sql, args) using Dollar placeholder.
346- func evalSqlizer (s sq.Sqlizer ) (string , []any , error ) {
347- sql , args , err := s .ToSql ()
348- if err != nil {
349- return "" , nil , err
350- }
351- sql , err = sq .Dollar .ReplacePlaceholders (sql )
352- return sql , args , err
353- }
354-
355345func TestTokenSqlNoJoin (t * testing.T ) {
356346 testCases := []struct {
357347 name string
@@ -452,12 +442,36 @@ func TestIn(t *testing.T) {
452442 assert .Equal (t , []any {"eid1" , "eid2" , "eid3" }, args )
453443}
454444
445+ func evalCondition (condition cond.Condition ) (string , []common2.Param ) {
446+ sb := common2 .NewBuilder ()
447+ condition .WriteString (sqlite .NewConditionInterpreter (), sb )
448+ actualSql , actualArgs := sb .Build ()
449+
450+ return actualSql , actualArgs
451+ }
452+
453+ // evalSqlizer converts a sq.Sqlizer to (sql, args) using Dollar placeholder.
454+ func evalSqlizer (s sq.Sqlizer ) (string , []any , error ) {
455+ if s == nil {
456+ return "" , []any {}, nil
457+ }
458+ sql , args , err := s .ToSql ()
459+ if err != nil {
460+ return "" , nil , err
461+ }
462+ sql , err = sq .Dollar .ReplacePlaceholders (sql )
463+
464+ return sql , args , err
465+ }
466+
455467func compareArgs (t * testing.T , expected , actual []any ) {
456468 t .Helper ()
457469 assert .Len (t , actual , len (expected ))
458- // assert.Equal(t, tc.expectedArgs, actualArgs)
459470
460471 for i := range expected {
472+ if i >= len (actual ) {
473+ break
474+ }
461475 switch expected [i ].(type ) {
462476 case * time.Time :
463477 exp , _ := expected [i ].(* time.Time )
0 commit comments