Skip to content

Commit 277062d

Browse files
authored
fix(pull): refactor select query with dialect commun sql (#267)
* fix: init branch * feat: add test push with nil value descriptor * feat: test push with nil value descriptor pass * refactor: update error message * fix: update test convert value error message * refactor: change check null position * feat(table): add test for sql server commun sql * feat: add get column names func for struct table * fix(pull): delete get column names func * fix(pull): replace create select by select selectlimit * feat: separated row reader func to test select sql generated correctly * docs: update change log * feat: add SQL query test for each dialect
1 parent 5379de6 commit 277062d

11 files changed

+293
-51
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ Types of changes
1414
- `Fixed` for any bug fixes.
1515
- `Security` in case of vulnerabilities.
1616

17+
## [2.7.1]
18+
19+
- `Fixed` panic during push on Oracle database with a `null` column value.
20+
- `Fixed` issue with SQL queries involving limit orders in SQL Server database.
21+
1722
## [2.7.0]
1823

1924
- `Added` columns information and export type using the `lino table extract` command, columns and keys organized according to the database order.

internal/infra/commonsql/dialect_sqlserver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func (sd SQLServerDialect) Placeholder(position int) string {
3131

3232
// Limit method is adjusted to be compatible with SQL Server
3333
func (sd SQLServerDialect) Limit(limit uint) string {
34-
return fmt.Sprintf(" TOP %d", limit)
34+
return fmt.Sprintf("TOP %d", limit)
3535
}
3636

3737
// From clause
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package commonsql
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestSQLServerDialect_Select(t *testing.T) {
10+
dialect := SQLServerDialect{}
11+
12+
tableName := "MyTable"
13+
schemaName := "dbo"
14+
whereClause := "column1 = 1"
15+
distinct := true
16+
columns := []string{"column1", "column2"}
17+
expectedResult := "SELECT DISTINCT column1, column2 FROM dbo.MyTable WHERE column1 = 1"
18+
19+
result := dialect.Select(tableName, schemaName, whereClause, distinct, columns...)
20+
21+
assert.Equal(t, expectedResult, result)
22+
}
23+
24+
func TestSQLServerDialect_SelectLimit(t *testing.T) {
25+
dialect := SQLServerDialect{}
26+
27+
tableName := "MyTable"
28+
schemaName := "dbo"
29+
whereClause := "column1 = 1"
30+
distinct := false
31+
limit := uint(10)
32+
expectedResult := "SELECT TOP 10 * FROM dbo.MyTable WHERE column1 = 1"
33+
34+
result := dialect.SelectLimit(tableName, schemaName, whereClause, distinct, limit)
35+
36+
assert.Equal(t, expectedResult, result)
37+
}
38+
39+
func TestSQLServerDialect_CreateSelect(t *testing.T) {
40+
dialect := SQLServerDialect{}
41+
42+
sel := "SELECT"
43+
where := "WHERE column1 = 1"
44+
limit := "TOP 10"
45+
columns := "column1, column2"
46+
from := "FROM dbo.MyTable"
47+
expectedResult := "SELECT TOP 10 column1, column2 FROM dbo.MyTable WHERE column1 = 1"
48+
49+
result := dialect.CreateSelect(sel, where, limit, columns, from)
50+
51+
assert.Equal(t, expectedResult, result)
52+
}

internal/infra/pull/datasource_db2_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
"github.com/DATA-DOG/go-sqlmock"
7+
"github.com/cgi-fr/lino/internal/infra/commonsql"
78
infra "github.com/cgi-fr/lino/internal/infra/pull"
89
"github.com/cgi-fr/lino/pkg/pull"
910

@@ -18,6 +19,13 @@ func TestCreateSelectDb2(t *testing.T) {
1819
assert.Nil(t, err)
1920
defer db.Close()
2021

22+
// Check SQL query is correctly created
23+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.Db2Dialect{})
24+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
25+
expectSQL := "SELECT * FROM CUSTOMERS WHERE 1=1 FETCH FIRST 5 ROWS ONLY"
26+
assert.Equal(t, expectSQL, sql)
27+
28+
// Check SQL query can correctly excute in DB2
2129
mock.ExpectQuery("SELECT * FROM CUSTOMERS WHERE 1=1 FETCH FIRST 5 ROWS ONLY").WillReturnRows()
2230

2331
db2Factory := infra.NewDb2DataSourceFactory()
@@ -31,3 +39,37 @@ func TestCreateSelectDb2(t *testing.T) {
3139
_, err = db2DS.RowReader(aTable, aFilter)
3240
assert.Nil(t, err)
3341
}
42+
43+
func TestCreateSelectDb2WithColumns(t *testing.T) {
44+
columns := []pull.Column{
45+
{Name: "ID"},
46+
{Name: "Name"},
47+
{Name: "Age"},
48+
}
49+
aTable := pull.Table{Name: "CUSTOMERS", Columns: columns}
50+
aFilter := pull.Filter{Limit: 5}
51+
52+
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
53+
assert.Nil(t, err)
54+
defer db.Close()
55+
56+
// Check SQL query is correctly created
57+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.Db2Dialect{})
58+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
59+
expectSQL := "SELECT ID, Name, Age FROM CUSTOMERS WHERE 1=1 FETCH FIRST 5 ROWS ONLY"
60+
assert.Equal(t, expectSQL, sql)
61+
62+
// Check SQL query can correctly excute in DB2
63+
mock.ExpectQuery(sql).WillReturnRows()
64+
65+
msFactory := infra.NewDb2DataSourceFactory()
66+
67+
msDS := msFactory.New("pg://server/name", "")
68+
69+
err = msDS.(*infra.SQLDataSource).OpenWithDB(db)
70+
71+
assert.Nil(t, err)
72+
73+
_, err = msDS.RowReader(aTable, aFilter)
74+
assert.Nil(t, err)
75+
}

internal/infra/pull/datasource_mariadb_test.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
"github.com/DATA-DOG/go-sqlmock"
7+
"github.com/cgi-fr/lino/internal/infra/commonsql"
78
infra "github.com/cgi-fr/lino/internal/infra/pull"
89
"github.com/cgi-fr/lino/pkg/pull"
910

@@ -18,7 +19,48 @@ func TestCreateSelectMariadb(t *testing.T) {
1819
assert.Nil(t, err)
1920
defer db.Close()
2021

21-
mock.ExpectQuery("SELECT * FROM CUSTOMERS WHERE 1=1 LIMIT 5").WillReturnRows()
22+
// Check SQL query is correctly created
23+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.MariadbDialect{})
24+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
25+
expectSQL := "SELECT * FROM CUSTOMERS WHERE 1=1 LIMIT 5"
26+
assert.Equal(t, expectSQL, sql)
27+
28+
// Check SQL query can correctly excute in MariaDB
29+
mock.ExpectQuery(sql).WillReturnRows()
30+
31+
pgFactory := infra.NewMariadbDataSourceFactory()
32+
33+
pgDS := pgFactory.New("pg://server/name", "")
34+
35+
err = pgDS.(*infra.SQLDataSource).OpenWithDB(db)
36+
37+
assert.Nil(t, err)
38+
39+
_, err = pgDS.RowReader(aTable, aFilter)
40+
assert.Nil(t, err)
41+
}
42+
43+
func TestCreateSelectMariadbWithColumns(t *testing.T) {
44+
columns := []pull.Column{
45+
{Name: "ID"},
46+
{Name: "Name"},
47+
{Name: "Age"},
48+
}
49+
aTable := pull.Table{Name: "CUSTOMERS", Columns: columns}
50+
aFilter := pull.Filter{Limit: 5}
51+
52+
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
53+
assert.Nil(t, err)
54+
defer db.Close()
55+
56+
// Check SQL query is correctly created
57+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.MariadbDialect{})
58+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
59+
expectSQL := "SELECT ID, Name, Age FROM CUSTOMERS WHERE 1=1 LIMIT 5"
60+
assert.Equal(t, expectSQL, sql)
61+
62+
// Check SQL query can correctly excute in MariaDB
63+
mock.ExpectQuery(sql).WillReturnRows()
2264

2365
pgFactory := infra.NewMariadbDataSourceFactory()
2466

internal/infra/pull/datasource_oracle_test.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
"github.com/DATA-DOG/go-sqlmock"
7+
"github.com/cgi-fr/lino/internal/infra/commonsql"
78
infra "github.com/cgi-fr/lino/internal/infra/pull"
89
"github.com/cgi-fr/lino/pkg/pull"
910

@@ -18,7 +19,48 @@ func TestCreateSelectOracle(t *testing.T) {
1819
assert.Nil(t, err)
1920
defer db.Close()
2021

21-
mock.ExpectQuery("SELECT * FROM CUSTOMERS WHERE 1=1 AND rownum <= 5").WillReturnRows()
22+
// Check SQL query is correctly created
23+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.OracleDialect{})
24+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
25+
expectSQL := "SELECT * FROM CUSTOMERS WHERE 1=1 AND rownum <= 5"
26+
assert.Equal(t, expectSQL, sql)
27+
28+
// Check SQL query can correctly excute in Oracle DB
29+
mock.ExpectQuery(sql).WillReturnRows()
30+
31+
pgFactory := infra.NewOracleDataSourceFactory()
32+
33+
pgDS := pgFactory.New("pg://server/name", "")
34+
35+
err = pgDS.(*infra.SQLDataSource).OpenWithDB(db)
36+
37+
assert.Nil(t, err)
38+
39+
_, err = pgDS.RowReader(aTable, aFilter)
40+
assert.Nil(t, err)
41+
}
42+
43+
func TestCreateSelectOracleWithColumns(t *testing.T) {
44+
columns := []pull.Column{
45+
{Name: "ID"},
46+
{Name: "Name"},
47+
{Name: "Age"},
48+
}
49+
aTable := pull.Table{Name: "CUSTOMERS", Columns: columns}
50+
aFilter := pull.Filter{Limit: 5}
51+
52+
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
53+
assert.Nil(t, err)
54+
defer db.Close()
55+
56+
// Check SQL query is correctly created
57+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.OracleDialect{})
58+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
59+
expectSQL := "SELECT ID, Name, Age FROM CUSTOMERS WHERE 1=1 AND rownum <= 5"
60+
assert.Equal(t, expectSQL, sql)
61+
62+
// Check SQL query can correctly excute in Oracle DB
63+
mock.ExpectQuery(sql).WillReturnRows()
2264

2365
pgFactory := infra.NewOracleDataSourceFactory()
2466

internal/infra/pull/datasource_postgres_test.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
"github.com/DATA-DOG/go-sqlmock"
7+
"github.com/cgi-fr/lino/internal/infra/commonsql"
78
infra "github.com/cgi-fr/lino/internal/infra/pull"
89
"github.com/cgi-fr/lino/pkg/pull"
910

@@ -18,7 +19,14 @@ func TestCreateSelectPostgres(t *testing.T) {
1819
assert.Nil(t, err)
1920
defer db.Close()
2021

21-
mock.ExpectQuery("SELECT * FROM CUSTOMERS WHERE 1=1 LIMIT 5").WillReturnRows()
22+
// Check SQL query is correctly created
23+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.PostgresDialect{})
24+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
25+
expectSQL := "SELECT * FROM CUSTOMERS WHERE 1=1 LIMIT 5"
26+
assert.Equal(t, expectSQL, sql)
27+
28+
// Check SQL query can correctly excute in Postgres
29+
mock.ExpectQuery(sql).WillReturnRows()
2230

2331
pgFactory := infra.NewPostgresDataSourceFactory()
2432

@@ -36,25 +44,26 @@ func TestCreateSelectPostgresWithColumns(t *testing.T) {
3644
aTable := pull.Table{Name: "CUSTOMERS", Columns: []pull.Column{{Name: "Name"}}}
3745
aFilter := pull.Filter{Limit: 5}
3846

39-
// Créer une base de données simulée avec un mock
4047
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
4148
assert.Nil(t, err)
4249
defer db.Close()
4350

44-
// Définir l'expectation de la requête SELECT avec des colonnes spécifiques
45-
mock.ExpectQuery("SELECT Name FROM CUSTOMERS WHERE 1=1 LIMIT 5").WillReturnRows()
51+
// Check SQL query is correctly created
52+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.PostgresDialect{})
53+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
54+
expectSQL := "SELECT Name FROM CUSTOMERS WHERE 1=1 LIMIT 5"
55+
assert.Equal(t, expectSQL, sql)
56+
57+
// Check SQL query can correctly excute in Postgres
58+
mock.ExpectQuery(sql).WillReturnRows()
4659

47-
// Créer une instance de la fabrique de source de données PostgreSQL
4860
pgFactory := infra.NewPostgresDataSourceFactory()
4961

50-
// Créer une source de données PostgreSQL avec une URL factice
5162
pgDS := pgFactory.New("pg://server/name", "")
5263

53-
// Ouvrir la source de données avec la base de données simulée
5464
err = pgDS.(*infra.SQLDataSource).OpenWithDB(db)
5565
assert.Nil(t, err)
5666

57-
// Appeler RowReader avec la table et le filtre
5867
_, err = pgDS.RowReader(aTable, aFilter)
5968
assert.Nil(t, err)
6069
}

internal/infra/pull/datasource_sqlserver_test.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
"github.com/DATA-DOG/go-sqlmock"
7+
"github.com/cgi-fr/lino/internal/infra/commonsql"
78
infra "github.com/cgi-fr/lino/internal/infra/pull"
89
"github.com/cgi-fr/lino/pkg/pull"
910

@@ -18,7 +19,48 @@ func TestCreateSelectSQLServer(t *testing.T) {
1819
assert.Nil(t, err)
1920
defer db.Close()
2021

21-
mock.ExpectQuery("SELECT TOP 5 * FROM CUSTOMERS WHERE 1=1").WillReturnRows()
22+
// Check SQL query is correctly created
23+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.SQLServerDialect{})
24+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
25+
expectSQL := "SELECT TOP 5 * FROM CUSTOMERS WHERE 1=1 "
26+
assert.Equal(t, expectSQL, sql)
27+
28+
// Check SQL query can correctly excute in SQL Server
29+
mock.ExpectQuery(sql).WillReturnRows()
30+
31+
msFactory := infra.NewSQLServerDataSourceFactory()
32+
33+
msDS := msFactory.New("pg://server/name", "")
34+
35+
err = msDS.(*infra.SQLDataSource).OpenWithDB(db)
36+
37+
assert.Nil(t, err)
38+
39+
_, err = msDS.RowReader(aTable, aFilter)
40+
assert.Nil(t, err)
41+
}
42+
43+
func TestCreateSelectSQLServerWithColumns(t *testing.T) {
44+
columns := []pull.Column{
45+
{Name: "ID"},
46+
{Name: "Name"},
47+
{Name: "Age"},
48+
}
49+
aTable := pull.Table{Name: "CUSTOMERS", Columns: columns}
50+
aFilter := pull.Filter{Limit: 5}
51+
52+
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
53+
assert.Nil(t, err)
54+
defer db.Close()
55+
56+
// Check SQL query is correctly created
57+
ds := infra.NewSQLDataSource("pg://server/name", "", nil, db, commonsql.SQLServerDialect{})
58+
_, sql := ds.GetSelectSQLAndValues(aTable, aFilter)
59+
expectSQL := "SELECT TOP 5 ID, Name, Age FROM CUSTOMERS WHERE 1=1 "
60+
assert.Equal(t, expectSQL, sql)
61+
62+
// Check SQL query can correctly excute in SQL Server
63+
mock.ExpectQuery(sql).WillReturnRows()
2264

2365
msFactory := infra.NewSQLServerDataSourceFactory()
2466

0 commit comments

Comments
 (0)