|
|
|
|
@@ -0,0 +1,396 @@
|
|
|
|
|
package dbwrapper
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"strings"
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"git.ksdemosapps.com/kylesoda/go-migrate/internal/app/config"
|
|
|
|
|
"git.ksdemosapps.com/kylesoda/go-migrate/internal/app/models"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_NoJsonColumns(t *testing.T) {
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Users",
|
|
|
|
|
PrimaryKey: "ID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("Name", true, false, "VARCHAR", "varchar", "VARCHAR", true, 255, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "SELECT [ID], [Name]") {
|
|
|
|
|
t.Errorf("Expected columns in query, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "FROM [dbo].[Users]") {
|
|
|
|
|
t.Errorf("Expected FROM clause, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "ORDER BY [ID] ASC") {
|
|
|
|
|
t.Errorf("Expected ORDER BY clause, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_WithJsonColumns_ExactColumnMatch(t *testing.T) {
|
|
|
|
|
// Test that the actual column name is used as alias, not a generated one
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Events",
|
|
|
|
|
PrimaryKey: "EventID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("EventID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("EventData", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{
|
|
|
|
|
{Column: "EventData", Field: ".userId"},
|
|
|
|
|
{Column: "EventData", Field: ".timestamp"},
|
|
|
|
|
},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.HasPrefix(query, "SELECT [EventID], JSON_VALUE([EventData], '$.userId') AS [EventData], JSON_VALUE([EventData], '$.timestamp') AS [EventData]") {
|
|
|
|
|
t.Errorf("Expected JSON columns to replace EventData in-order, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if strings.Contains(query, "SELECT [EventID], [EventData]") {
|
|
|
|
|
t.Errorf("Expected EventData to be replaced by JSON extraction, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Alias should be exactly "EventData", not "EventData_userId"
|
|
|
|
|
if !strings.Contains(query, "JSON_VALUE([EventData], '$.userId') AS [EventData]") {
|
|
|
|
|
t.Errorf("Expected JSON alias to be [EventData], got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "JSON_VALUE([EventData], '$.timestamp') AS [EventData]") {
|
|
|
|
|
t.Errorf("Expected JSON alias to be [EventData], got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Should have comma separating them
|
|
|
|
|
if !strings.Contains(query, "JSON_VALUE([EventData], '$.userId') AS [EventData], JSON_VALUE([EventData], '$.timestamp') AS [EventData]") {
|
|
|
|
|
t.Errorf("Expected comma-separated JSON values, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_WithWildcardPattern(t *testing.T) {
|
|
|
|
|
// Test that wildcard pattern matching finds the correct column
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Events",
|
|
|
|
|
PrimaryKey: "ID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("NodeMetadata", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{
|
|
|
|
|
{Column: "NodeMeta*", Field: ".id"},
|
|
|
|
|
},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Should find "NodeMetadata" from pattern "NodeMeta*" and use it as alias
|
|
|
|
|
if !strings.Contains(query, "JSON_VALUE([NodeMetadata], '$.id') AS [NodeMetadata]") {
|
|
|
|
|
t.Errorf("Expected to find and use NodeMetadata column by pattern, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if strings.Contains(query, "SELECT [ID], [NodeMetadata]") {
|
|
|
|
|
t.Errorf("Expected NodeMetadata to be replaced by JSON extraction, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_ColumnNotFound_Error(t *testing.T) {
|
|
|
|
|
// Test that an error is returned when column is not found
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Events",
|
|
|
|
|
PrimaryKey: "ID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{
|
|
|
|
|
{Column: "NonExistentColumn", Field: ".id"},
|
|
|
|
|
},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("Expected error for missing column, got no error. Query: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "NonExistentColumn") {
|
|
|
|
|
t.Errorf("Expected error message to contain column name, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_WildcardPatternNotMatched_Error(t *testing.T) {
|
|
|
|
|
// Test that an error is returned when wildcard pattern doesn't match any column
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Events",
|
|
|
|
|
PrimaryKey: "ID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("EventData", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{
|
|
|
|
|
{Column: "NonMatching*", Field: ".id"},
|
|
|
|
|
},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("Expected error for non-matching wildcard pattern, got no error. Query: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "NonMatching*") {
|
|
|
|
|
t.Errorf("Expected error message to contain pattern, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_NestedJsonFields(t *testing.T) {
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Data",
|
|
|
|
|
PrimaryKey: "ID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("NodeData", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{
|
|
|
|
|
{Column: "NodeData", Field: ".user.name"},
|
|
|
|
|
{Column: "NodeData", Field: ".user.email"},
|
|
|
|
|
},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "JSON_VALUE([NodeData], '$.user.name') AS [NodeData]") {
|
|
|
|
|
t.Errorf("Expected nested JSON path for user.name, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "JSON_VALUE([NodeData], '$.user.email') AS [NodeData]") {
|
|
|
|
|
t.Errorf("Expected nested JSON path for user.email, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if strings.Contains(query, "SELECT [ID], [NodeData]") {
|
|
|
|
|
t.Errorf("Expected NodeData to be replaced by JSON extraction, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_WithRangeLimits(t *testing.T) {
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Products",
|
|
|
|
|
PrimaryKey: "ProductID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ProductID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("Details", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{
|
|
|
|
|
{Column: "Details", Field: ".price"},
|
|
|
|
|
},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: true, IsInclusive: true, Value: 100},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: true, IsInclusive: false, Value: 500},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "WHERE [ProductID] >= @min") {
|
|
|
|
|
t.Errorf("Expected WHERE clause with >=, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "[ProductID] < @max") {
|
|
|
|
|
t.Errorf("Expected upper limit with <, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(query, "JSON_VALUE([Details], '$.price') AS [Details]") {
|
|
|
|
|
t.Errorf("Expected JSON_VALUE for Details, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if strings.Contains(query, "SELECT [ProductID], [Details]") {
|
|
|
|
|
t.Errorf("Expected Details to be replaced by JSON extraction, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildJsonPathMssql(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
input string
|
|
|
|
|
expected string
|
|
|
|
|
}{
|
|
|
|
|
{".id", "$.id"},
|
|
|
|
|
{"id", "$.id"},
|
|
|
|
|
{".user.name", "$.user.name"},
|
|
|
|
|
{"user.name", "$.user.name"},
|
|
|
|
|
{".location.coordinates.lat", "$.location.coordinates.lat"},
|
|
|
|
|
{"", "$."},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
result := buildJsonPathMssql(tt.input)
|
|
|
|
|
if result != tt.expected {
|
|
|
|
|
t.Errorf("buildJsonPathMssql(%q) = %q, want %q", tt.input, result, tt.expected)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFindColumnByPattern_ExactMatch(t *testing.T) {
|
|
|
|
|
columns := []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("Metadata", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
models.NewColumnType("EventData", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result, err := findColumnByPattern(columns, "Metadata")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if result != "Metadata" {
|
|
|
|
|
t.Errorf("Expected 'Metadata', got '%s'", result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFindColumnByPattern_WildcardMatch(t *testing.T) {
|
|
|
|
|
columns := []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("NodeMetadata", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
models.NewColumnType("EventData", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result, err := findColumnByPattern(columns, "NodeMeta*")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if result != "NodeMetadata" {
|
|
|
|
|
t.Errorf("Expected 'NodeMetadata', got '%s'", result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFindColumnByPattern_NotFound(t *testing.T) {
|
|
|
|
|
columns := []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("Metadata", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result, err := findColumnByPattern(columns, "NonExistent")
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("Expected error, got no error. Result: %s", result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "NonExistent") {
|
|
|
|
|
t.Errorf("Expected error to contain column name, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFindColumnByPattern_WildcardNotFound(t *testing.T) {
|
|
|
|
|
columns := []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("Metadata", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result, err := findColumnByPattern(columns, "Event*")
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("Expected error, got no error. Result: %s", result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "Event*") {
|
|
|
|
|
t.Errorf("Expected error to contain pattern, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_OnlyJsonColumns(t *testing.T) {
|
|
|
|
|
// Test when all columns are used via JSON extraction
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Data",
|
|
|
|
|
PrimaryKey: "ID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("ID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("JsonData", true, false, "VARCHAR", "varchar", "VARCHAR", true, 500, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{
|
|
|
|
|
{Column: "JsonData", Field: ".field1"},
|
|
|
|
|
},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.HasPrefix(query, "SELECT [ID], JSON_VALUE([JsonData], '$.field1') AS [JsonData]") {
|
|
|
|
|
t.Errorf("Expected JsonData to be replaced by JSON extraction, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if strings.Contains(query, "SELECT [ID], [JsonData]") {
|
|
|
|
|
t.Errorf("Expected JsonData to be excluded from raw selection, got: %s", query)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildExtractQueryMssql_JsonColumnsReplaceInOrder(t *testing.T) {
|
|
|
|
|
q := ExtractionQuery{
|
|
|
|
|
Schema: "dbo",
|
|
|
|
|
Table: "Users",
|
|
|
|
|
PrimaryKey: "UserID",
|
|
|
|
|
Columns: []models.ColumnType{
|
|
|
|
|
models.NewColumnType("UserID", false, false, "INT", "int", "INT", false, 0, 0, 0),
|
|
|
|
|
models.NewColumnType("Name", true, false, "VARCHAR", "varchar", "VARCHAR", false, 255, 0, 0),
|
|
|
|
|
models.NewColumnType("Email", true, false, "VARCHAR", "varchar", "VARCHAR", false, 255, 0, 0),
|
|
|
|
|
models.NewColumnType("Metadata", true, false, "NVARCHAR", "nvarchar", "NVARCHAR", true, 4000, 0, 0),
|
|
|
|
|
models.NewColumnType("Profile", true, false, "NVARCHAR", "nvarchar", "NVARCHAR", true, 4000, 0, 0),
|
|
|
|
|
models.NewColumnType("Settings", true, false, "NVARCHAR", "nvarchar", "NVARCHAR", true, 4000, 0, 0),
|
|
|
|
|
},
|
|
|
|
|
FromJsonColumns: []config.FromJsonItem{
|
|
|
|
|
{Column: "Metadata", Field: ".id"},
|
|
|
|
|
{Column: "Profile", Field: ".id"},
|
|
|
|
|
{Column: "Settings", Field: ".id"},
|
|
|
|
|
},
|
|
|
|
|
LowerLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
UpperLimit: ExtractorQueryLimit{IsValid: false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query, err := buildExtractQueryMssql(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expected := "SELECT [UserID], [Name], [Email], JSON_VALUE([Metadata], '$.id') AS [Metadata], JSON_VALUE([Profile], '$.id') AS [Profile], JSON_VALUE([Settings], '$.id') AS [Settings] FROM [dbo].[Users] ORDER BY [UserID] ASC"
|
|
|
|
|
if query != expected {
|
|
|
|
|
t.Errorf("Unexpected query.\nExpected: %s\nGot: %s", expected, query)
|
|
|
|
|
}
|
|
|
|
|
}
|