github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/params/dict_test.go (about)

     1  package params
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/google/uuid"
     9  	"github.com/stretchr/testify/require"
    10  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
    11  
    12  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/allocator"
    13  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/value"
    14  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xtest"
    15  )
    16  
    17  func TestDict(t *testing.T) {
    18  	type expected struct {
    19  		Type  *Ydb.Type
    20  		Value *Ydb.Value
    21  	}
    22  
    23  	tests := []struct {
    24  		method string
    25  		args   []any
    26  
    27  		expected expected
    28  	}{
    29  		{
    30  			method: "Uint64",
    31  			args:   []any{uint64(123)},
    32  
    33  			expected: expected{
    34  				Type: &Ydb.Type{
    35  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_UINT64},
    36  				},
    37  				Value: &Ydb.Value{
    38  					Value: &Ydb.Value_Uint64Value{
    39  						Uint64Value: 123,
    40  					},
    41  				},
    42  			},
    43  		},
    44  		{
    45  			method: "Int64",
    46  			args:   []any{int64(123)},
    47  
    48  			expected: expected{
    49  				Type: &Ydb.Type{
    50  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_INT64},
    51  				},
    52  				Value: &Ydb.Value{
    53  					Value: &Ydb.Value_Int64Value{
    54  						Int64Value: 123,
    55  					},
    56  				},
    57  			},
    58  		},
    59  		{
    60  			method: "Uint32",
    61  			args:   []any{uint32(123)},
    62  
    63  			expected: expected{
    64  				Type: &Ydb.Type{
    65  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_UINT32},
    66  				},
    67  				Value: &Ydb.Value{
    68  					Value: &Ydb.Value_Uint32Value{
    69  						Uint32Value: 123,
    70  					},
    71  				},
    72  			},
    73  		},
    74  		{
    75  			method: "Int32",
    76  			args:   []any{int32(123)},
    77  
    78  			expected: expected{
    79  				Type: &Ydb.Type{
    80  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_INT32},
    81  				},
    82  				Value: &Ydb.Value{
    83  					Value: &Ydb.Value_Int32Value{
    84  						Int32Value: 123,
    85  					},
    86  				},
    87  			},
    88  		},
    89  		{
    90  			method: "Uint16",
    91  			args:   []any{uint16(123)},
    92  
    93  			expected: expected{
    94  				Type: &Ydb.Type{
    95  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_UINT16},
    96  				},
    97  				Value: &Ydb.Value{
    98  					Value: &Ydb.Value_Uint32Value{
    99  						Uint32Value: 123,
   100  					},
   101  				},
   102  			},
   103  		},
   104  		{
   105  			method: "Int16",
   106  			args:   []any{int16(123)},
   107  
   108  			expected: expected{
   109  				Type: &Ydb.Type{
   110  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_INT16},
   111  				},
   112  				Value: &Ydb.Value{
   113  					Value: &Ydb.Value_Int32Value{
   114  						Int32Value: 123,
   115  					},
   116  				},
   117  			},
   118  		},
   119  		{
   120  			method: "Uint8",
   121  			args:   []any{uint8(123)},
   122  
   123  			expected: expected{
   124  				Type: &Ydb.Type{
   125  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_UINT8},
   126  				},
   127  				Value: &Ydb.Value{
   128  					Value: &Ydb.Value_Uint32Value{
   129  						Uint32Value: 123,
   130  					},
   131  				},
   132  			},
   133  		},
   134  		{
   135  			method: "Int8",
   136  			args:   []any{int8(123)},
   137  
   138  			expected: expected{
   139  				Type: &Ydb.Type{
   140  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_INT8},
   141  				},
   142  				Value: &Ydb.Value{
   143  					Value: &Ydb.Value_Int32Value{
   144  						Int32Value: 123,
   145  					},
   146  				},
   147  			},
   148  		},
   149  		{
   150  			method: "Bool",
   151  			args:   []any{true},
   152  
   153  			expected: expected{
   154  				Type: &Ydb.Type{
   155  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_BOOL},
   156  				},
   157  				Value: &Ydb.Value{
   158  					Value: &Ydb.Value_BoolValue{
   159  						BoolValue: true,
   160  					},
   161  				},
   162  			},
   163  		},
   164  		{
   165  			method: "Text",
   166  			args:   []any{"test"},
   167  
   168  			expected: expected{
   169  				Type: &Ydb.Type{
   170  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_UTF8},
   171  				},
   172  				Value: &Ydb.Value{
   173  					Value: &Ydb.Value_TextValue{
   174  						TextValue: "test",
   175  					},
   176  				},
   177  			},
   178  		},
   179  		{
   180  			method: "Bytes",
   181  			args:   []any{[]byte("test")},
   182  
   183  			expected: expected{
   184  				Type: &Ydb.Type{
   185  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_STRING},
   186  				},
   187  				Value: &Ydb.Value{
   188  					Value: &Ydb.Value_BytesValue{
   189  						BytesValue: []byte("test"),
   190  					},
   191  				},
   192  			},
   193  		},
   194  		{
   195  			method: "Float",
   196  			args:   []any{float32(123)},
   197  
   198  			expected: expected{
   199  				Type: &Ydb.Type{
   200  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_FLOAT},
   201  				},
   202  				Value: &Ydb.Value{
   203  					Value: &Ydb.Value_FloatValue{
   204  						FloatValue: float32(123),
   205  					},
   206  				},
   207  			},
   208  		},
   209  		{
   210  			method: "Double",
   211  			args:   []any{float64(123)},
   212  
   213  			expected: expected{
   214  				Type: &Ydb.Type{
   215  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_DOUBLE},
   216  				},
   217  				Value: &Ydb.Value{
   218  					Value: &Ydb.Value_DoubleValue{
   219  						DoubleValue: float64(123),
   220  					},
   221  				},
   222  			},
   223  		},
   224  		{
   225  			method: "Interval",
   226  			args:   []any{time.Second},
   227  
   228  			expected: expected{
   229  				Type: &Ydb.Type{
   230  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_INTERVAL},
   231  				},
   232  				Value: &Ydb.Value{
   233  					Value: &Ydb.Value_Int64Value{
   234  						Int64Value: 1000000,
   235  					},
   236  				},
   237  			},
   238  		},
   239  		{
   240  			method: "Datetime",
   241  			args:   []any{time.Unix(123456789, 456)},
   242  
   243  			expected: expected{
   244  				Type: &Ydb.Type{
   245  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_DATETIME},
   246  				},
   247  				Value: &Ydb.Value{
   248  					Value: &Ydb.Value_Uint32Value{
   249  						Uint32Value: 123456789,
   250  					},
   251  				},
   252  			},
   253  		},
   254  		{
   255  			method: "Date",
   256  			args:   []any{time.Unix(123456789, 456)},
   257  
   258  			expected: expected{
   259  				Type: &Ydb.Type{
   260  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_DATE},
   261  				},
   262  				Value: &Ydb.Value{
   263  					Value: &Ydb.Value_Uint32Value{
   264  						Uint32Value: 1428,
   265  					},
   266  				},
   267  			},
   268  		},
   269  		{
   270  			method: "Timestamp",
   271  			args:   []any{time.Unix(123456789, 456)},
   272  
   273  			expected: expected{
   274  				Type: &Ydb.Type{
   275  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_TIMESTAMP},
   276  				},
   277  				Value: &Ydb.Value{
   278  					Value: &Ydb.Value_Uint64Value{
   279  						Uint64Value: 123456789000000,
   280  					},
   281  				},
   282  			},
   283  		},
   284  		{
   285  			method: "Decimal",
   286  			args:   []any{[...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}, uint32(22), uint32(9)},
   287  
   288  			expected: expected{
   289  				Type: &Ydb.Type{
   290  					Type: &Ydb.Type_DecimalType{
   291  						DecimalType: &Ydb.DecimalType{
   292  							Precision: 22,
   293  							Scale:     9,
   294  						},
   295  					},
   296  				},
   297  				Value: &Ydb.Value{
   298  					High_128: 72623859790382856,
   299  					Value: &Ydb.Value_Low_128{
   300  						Low_128: 648519454493508870,
   301  					},
   302  				},
   303  			},
   304  		},
   305  		{
   306  			method: "JSON",
   307  			args:   []any{`{"a": 1,"b": "B"}`},
   308  
   309  			expected: expected{
   310  				Type: &Ydb.Type{
   311  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_JSON},
   312  				},
   313  				Value: &Ydb.Value{
   314  					Value: &Ydb.Value_TextValue{
   315  						TextValue: `{"a": 1,"b": "B"}`,
   316  					},
   317  				},
   318  			},
   319  		},
   320  		{
   321  			method: "JSONDocument",
   322  			args:   []any{`{"a": 1,"b": "B"}`},
   323  
   324  			expected: expected{
   325  				Type: &Ydb.Type{
   326  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_JSON_DOCUMENT},
   327  				},
   328  				Value: &Ydb.Value{
   329  					Value: &Ydb.Value_TextValue{
   330  						TextValue: `{"a": 1,"b": "B"}`,
   331  					},
   332  				},
   333  			},
   334  		},
   335  		{
   336  			method: "YSON",
   337  			args:   []any{[]byte(`{"a": 1,"b": "B"}`)},
   338  
   339  			expected: expected{
   340  				Type: &Ydb.Type{
   341  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_YSON},
   342  				},
   343  				Value: &Ydb.Value{
   344  					Value: &Ydb.Value_BytesValue{
   345  						BytesValue: []byte(`{"a": 1,"b": "B"}`),
   346  					},
   347  				},
   348  			},
   349  		},
   350  		{
   351  			method: "Uuid",
   352  			args:   []any{uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}},
   353  
   354  			expected: expected{
   355  				Type: &Ydb.Type{
   356  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_UUID},
   357  				},
   358  				Value: &Ydb.Value{
   359  					Value: &Ydb.Value_Low_128{
   360  						Low_128: 506660481424032516,
   361  					},
   362  					High_128: 1157159078456920585,
   363  				},
   364  			},
   365  		},
   366  		{
   367  			method: "UUIDWithIssue1501Value",
   368  			args:   []any{[...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}},
   369  
   370  			expected: expected{
   371  				Type: &Ydb.Type{
   372  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_UUID},
   373  				},
   374  				Value: &Ydb.Value{
   375  					Value: &Ydb.Value_Low_128{
   376  						Low_128: 651345242494996240,
   377  					},
   378  					High_128: 72623859790382856,
   379  				},
   380  			},
   381  		},
   382  		{
   383  			method: "TzDatetime",
   384  			args:   []any{time.Unix(123456789, 456).UTC()},
   385  
   386  			expected: expected{
   387  				Type: &Ydb.Type{
   388  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_TZ_DATETIME},
   389  				},
   390  				Value: &Ydb.Value{
   391  					Value: &Ydb.Value_TextValue{
   392  						TextValue: "1973-11-29T21:33:09Z",
   393  					},
   394  				},
   395  			},
   396  		},
   397  		{
   398  			method: "TzDate",
   399  			args:   []any{time.Unix(123456789, 456).UTC()},
   400  
   401  			expected: expected{
   402  				Type: &Ydb.Type{
   403  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_TZ_DATE},
   404  				},
   405  				Value: &Ydb.Value{
   406  					Value: &Ydb.Value_TextValue{
   407  						TextValue: "1973-11-29",
   408  					},
   409  				},
   410  			},
   411  		},
   412  		{
   413  			method: "TzTimestamp",
   414  			args:   []any{time.Unix(123456789, 456).UTC()},
   415  
   416  			expected: expected{
   417  				Type: &Ydb.Type{
   418  					Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_TZ_TIMESTAMP},
   419  				},
   420  				Value: &Ydb.Value{
   421  					Value: &Ydb.Value_TextValue{
   422  						TextValue: "1973-11-29T21:33:09.000000Z",
   423  					},
   424  				},
   425  			},
   426  		},
   427  	}
   428  
   429  	for _, key := range tests {
   430  		for _, val := range tests {
   431  			t.Run(fmt.Sprintf("%s:%s", key.method, val.method), func(t *testing.T) {
   432  				a := allocator.New()
   433  				defer a.Free()
   434  
   435  				item := Builder{}.Param("$x").BeginDict().Add()
   436  
   437  				addedKey, ok := xtest.CallMethod(item, key.method, key.args...)[0].(*dictValue)
   438  				require.True(t, ok)
   439  
   440  				d, ok := xtest.CallMethod(addedKey, val.method, val.args...)[0].(*dict)
   441  				require.True(t, ok)
   442  
   443  				params := d.EndDict().Build().ToYDB(a)
   444  				require.Equal(t, xtest.ToJSON(
   445  					map[string]*Ydb.TypedValue{
   446  						"$x": {
   447  							Type: &Ydb.Type{
   448  								Type: &Ydb.Type_DictType{
   449  									DictType: &Ydb.DictType{
   450  										Key:     key.expected.Type,
   451  										Payload: val.expected.Type,
   452  									},
   453  								},
   454  							},
   455  							Value: &Ydb.Value{
   456  								Pairs: []*Ydb.ValuePair{
   457  									{
   458  										Key:     key.expected.Value,
   459  										Payload: val.expected.Value,
   460  									},
   461  								},
   462  							},
   463  						},
   464  					}), xtest.ToJSON(params))
   465  			})
   466  		}
   467  	}
   468  }
   469  
   470  func TestDict_AddPairs(t *testing.T) {
   471  	a := allocator.New()
   472  	defer a.Free()
   473  
   474  	pairs := []value.DictValueField{
   475  		{
   476  			K: value.Int64Value(123),
   477  			V: value.BoolValue(true),
   478  		},
   479  		{
   480  			K: value.Int64Value(321),
   481  			V: value.BoolValue(false),
   482  		},
   483  	}
   484  
   485  	params := Builder{}.Param("$x").BeginDict().AddPairs(pairs...).EndDict().Build().ToYDB(a)
   486  
   487  	require.Equal(t, xtest.ToJSON(
   488  		map[string]*Ydb.TypedValue{
   489  			"$x": {
   490  				Type: &Ydb.Type{
   491  					Type: &Ydb.Type_DictType{
   492  						DictType: &Ydb.DictType{
   493  							Key: &Ydb.Type{
   494  								Type: &Ydb.Type_TypeId{
   495  									TypeId: Ydb.Type_INT64,
   496  								},
   497  							},
   498  							Payload: &Ydb.Type{
   499  								Type: &Ydb.Type_TypeId{
   500  									TypeId: Ydb.Type_BOOL,
   501  								},
   502  							},
   503  						},
   504  					},
   505  				},
   506  				Value: &Ydb.Value{
   507  					Pairs: []*Ydb.ValuePair{
   508  						{
   509  							Key: &Ydb.Value{
   510  								Value: &Ydb.Value_Int64Value{
   511  									Int64Value: 123,
   512  								},
   513  							},
   514  							Payload: &Ydb.Value{
   515  								Value: &Ydb.Value_BoolValue{
   516  									BoolValue: true,
   517  								},
   518  							},
   519  						},
   520  						{
   521  							Key: &Ydb.Value{
   522  								Value: &Ydb.Value_Int64Value{
   523  									Int64Value: 321,
   524  								},
   525  							},
   526  							Payload: &Ydb.Value{
   527  								Value: &Ydb.Value_BoolValue{
   528  									BoolValue: false,
   529  								},
   530  							},
   531  						},
   532  					},
   533  				},
   534  			},
   535  		}), xtest.ToJSON(params))
   536  }