Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 230a7a2

Browse files
committed
Merge pull request #395 from BruceCowan-AI/FixTestFailures
Fix Oracle dialect provider problems with paging, expressions, nullable ...
2 parents e3abfd1 + 96c898b commit 230a7a2

File tree

9 files changed

+88
-56
lines changed

9 files changed

+88
-56
lines changed

src/ServiceStack.OrmLite.Oracle.Tests/ServiceStack.OrmLite.Oracle.Tests.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@
123123
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\Expression\SelectExpressionTests.cs">
124124
<Link>Expression\SelectExpressionTests.cs</Link>
125125
</Compile>
126+
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\Expression\SqlExpressionTests.cs">
127+
<Link>Expression\SqlExpressionTests.cs</Link>
128+
</Compile>
126129
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\Expression\StringFunctionTests.cs">
127130
<Link>Expression\StringFunctionTests.cs</Link>
128131
</Compile>
@@ -135,6 +138,9 @@
135138
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\JoinSqlBuilderTests.cs">
136139
<Link>JoinSqlBuilderTests.cs</Link>
137140
</Compile>
141+
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\LoadReferencesJoinTests.cs">
142+
<Link>LoadReferencesJoinTests.cs</Link>
143+
</Compile>
138144
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\LoadReferencesTests.cs">
139145
<Link>LoadReferencesTests.cs</Link>
140146
</Compile>
@@ -318,6 +324,9 @@
318324
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\UseCase\CustomerOrdersUseCase.cs">
319325
<Link>UseCase\CustomerOrdersUseCase.cs</Link>
320326
</Compile>
327+
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\UseCase\FieldFromInterfaceImplementationUseCase.cs">
328+
<Link>UseCase\FieldFromInterfaceImplementationUseCase.cs</Link>
329+
</Compile>
321330
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\UseCase\ImageBlobDto.cs">
322331
<Link>UseCase\ImageBlobDto.cs</Link>
323332
</Compile>

src/ServiceStack.OrmLite.Oracle/OracleOrmLiteDialectProvider.cs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,13 @@ public override string ToSelectStatement(Type tableType, string sqlFilter, param
268268
var sql = new StringBuilder();
269269
const string selectStatement = "SELECT ";
270270
var modelDef = GetModel(tableType);
271-
var isFullSelectStatement =
272-
!string.IsNullOrEmpty(sqlFilter)
273-
&& sqlFilter.Trim().Length > selectStatement.Length
274-
&& sqlFilter.Trim().Substring(0, selectStatement.Length).ToUpper().Equals(selectStatement);
271+
var isFullSelectStatement = false;
272+
if (!string.IsNullOrEmpty(sqlFilter))
273+
{
274+
var cleanFilter = sqlFilter.Trim().Replace('\r', ' ').Replace('\n', ' ').ToUpperInvariant();
275+
isFullSelectStatement = cleanFilter.Length > selectStatement.Length
276+
&& cleanFilter.Substring(0, selectStatement.Length).Equals(selectStatement);
277+
}
275278

276279
if (isFullSelectStatement)
277280
{
@@ -369,11 +372,11 @@ public override void SetParameterValues<T>(IDbCommand dbCmd, object obj)
369372
pi.GetValue(obj, new object[] { }), isInsert);
370373
if (pi.PropertyType == typeof(String))
371374
pi.SetProperty(obj, result.ToString());
372-
else if (pi.PropertyType == typeof(Int16))
375+
else if (pi.PropertyType == typeof(Int16) || pi.PropertyType == typeof(Int16?))
373376
pi.SetProperty(obj, Convert.ToInt16(result));
374-
else if (pi.PropertyType == typeof(Int32))
377+
else if (pi.PropertyType == typeof(Int32) || pi.PropertyType == typeof(Int32?))
375378
pi.SetProperty(obj, Convert.ToInt32(result));
376-
else if (pi.PropertyType == typeof(Guid))
379+
else if (pi.PropertyType == typeof(Guid) || pi.PropertyType == typeof(Guid?))
377380
pi.SetProperty(obj, result);
378381
else
379382
pi.SetProperty(obj, Convert.ToInt64(result));
@@ -1122,13 +1125,11 @@ public override string ToSelectStatement(ModelDefinition modelDef,
11221125
var sbInner = new StringBuilder(selectExpression);
11231126
sbInner.Append(bodyExpression);
11241127

1125-
if (!rows.HasValue)
1126-
return sbInner + orderByExpression;
1128+
if (!rows.HasValue && !offset.HasValue)
1129+
return sbInner + " " + orderByExpression;
11271130

11281131
if (!offset.HasValue)
1129-
{
11301132
offset = 0;
1131-
}
11321133

11331134
if (string.IsNullOrEmpty(orderByExpression))
11341135
{
@@ -1138,7 +1139,7 @@ public override string ToSelectStatement(ModelDefinition modelDef,
11381139
orderByExpression = string.Format("ORDER BY {0}",
11391140
OrmLiteConfig.DialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName));
11401141
}
1141-
sbInner.Append(orderByExpression);
1142+
sbInner.Append(" " + orderByExpression);
11421143

11431144
var sql = sbInner.ToString();
11441145

@@ -1147,7 +1148,10 @@ public override string ToSelectStatement(ModelDefinition modelDef,
11471148
sb.AppendLine("SELECT \"_ss_ormlite_1_\".*, ROWNUM RNUM FROM (");
11481149
sb.Append(sql);
11491150
sb.AppendLine(") \"_ss_ormlite_1_\"");
1150-
sb.AppendFormat("WHERE ROWNUM <= {0} + {1}) \"_ss_ormlite_2_\" ", offset.Value, rows.Value);
1151+
if (rows.HasValue)
1152+
sb.AppendFormat("WHERE ROWNUM <= {0} + {1}) \"_ss_ormlite_2_\" ", offset.Value, rows.Value);
1153+
else
1154+
sb.Append(") \"_ss_ormlite_2_\" ");
11511155
sb.AppendFormat("WHERE \"_ss_ormlite_2_\".RNUM > {0}", offset.Value);
11521156

11531157
return sb.ToString();

tests/ServiceStack.OrmLite.Tests/JoinSqlBuilderTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,9 @@ public void Can_execute_SqlBuilder_templates_as_SqlExpression()
123123
var tmpl = sb.AddTemplate("SELECT * FROM {0} u INNER JOIN {1} a on a.{2} = u.Id /**where**/"
124124
.Fmt("User".SqlTable(), "Addresses".SqlTable(), "UserId".SqlColumn()));
125125

126-
sb.Where("Age > @age", new { age = 18 });
127-
sb.Where("Countryalias = @country", new { country = "Italy" });
126+
var paramString = OrmLiteConfig.DialectProvider.ParamString;
127+
sb.Where("Age > " + paramString + "age", new { age = 18 });
128+
sb.Where("Countryalias = " + paramString + "country", new { country = "Italy" });
128129

129130
var userId = db.Insert(new User { Age = 27, Name = "Foo" }, selectIdentity: true);
130131
db.Insert(new WithAliasAddress { City = "Rome", Country = "Italy", UserId = (int)userId });

tests/ServiceStack.OrmLite.Tests/LoadReferencesJoinTests.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Data;
1+
using System.Collections.Generic;
2+
using System.Data;
23
using System.Linq;
34
using NUnit.Framework;
45
using ServiceStack.OrmLite.Tests.UseCase;
@@ -194,7 +195,8 @@ public void Can_do_joins_with_complex_wheres_using_SqlExpression()
194195
var costs = results.ConvertAll(x => x.Cost);
195196
Assert.That(costs, Is.EquivalentTo(new[] { 1.99m, 1.49m, 9.99m }));
196197
var orderIds = results.ConvertAll(x => x.OrderId);
197-
Assert.That(orderIds, Is.EquivalentTo(new[] { 1, 3, 5 }));
198+
var expectedOrderIds = new []{customers[0].Orders[0].Id, customers[0].Orders[2].Id, customers[0].Orders[4].Id};
199+
Assert.That(orderIds, Is.EquivalentTo(expectedOrderIds));
198200

199201
//Same as above using using db.From<Customer>()
200202
results = db.Select<FullCustomerInfo>(db.From<Customer>()
@@ -375,17 +377,19 @@ public void Does_populate_custom_columns_based_on_property_convention()
375377
db.DropAndCreateTable<CustomerAddress>();
376378
db.DropAndCreateTable<Customer>();
377379

378-
AddCustomerWithOrders();
380+
var customer = AddCustomerWithOrders();
379381

380382
var results = db.Select<FullCustomerInfo, Customer>(q => q
381383
.Join<Customer, CustomerAddress>()
382384
.Join<Customer, Order>());
383385

384386
var addressIds = results.ConvertAll(x => x.CustomerAddressId);
385-
Assert.That(addressIds, Is.EquivalentTo(new[] { 1, 1 }));
387+
var expectedAddressIds = new[] { customer.PrimaryAddress.Id, customer.PrimaryAddress.Id };
388+
Assert.That(addressIds, Is.EquivalentTo(expectedAddressIds));
386389

387390
var orderIds = results.ConvertAll(x => x.OrderId);
388-
Assert.That(orderIds, Is.EquivalentTo(new[] { 1, 2 }));
391+
var expectedOrderIds = new[] {customer.Orders[0].Id, customer.Orders[1].Id};
392+
Assert.That(orderIds, Is.EquivalentTo(expectedOrderIds));
389393

390394
var customerNames = results.ConvertAll(x => x.CustomerName);
391395
Assert.That(customerNames, Is.EquivalentTo(new[] { "Customer 1", "Customer 1" }));
@@ -401,10 +405,10 @@ public void Does_populate_custom_columns_based_on_property_convention()
401405
results = db.Select<FullCustomerInfo>(expr);
402406

403407
addressIds = results.ConvertAll(x => x.CustomerAddressId);
404-
Assert.That(addressIds, Is.EquivalentTo(new[] { 1 }));
408+
Assert.That(addressIds, Is.EquivalentTo(new[] { customer.PrimaryAddress.Id }));
405409

406410
orderIds = results.ConvertAll(x => x.OrderId);
407-
Assert.That(orderIds, Is.EquivalentTo(new[] { 2 }));
411+
Assert.That(orderIds, Is.EquivalentTo(new[] { customer.Orders[1].Id }));
408412

409413
customerNames = results.ConvertAll(x => x.CustomerName);
410414
Assert.That(customerNames, Is.EquivalentTo(new[] { "Customer 1" }));

tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithIndexesTests.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,17 @@ public void Can_create_ModelWithIndexFields_table()
1818

1919
var sql = OrmLiteConfig.DialectProvider.ToCreateIndexStatements(typeof(ModelWithIndexFields)).Join();
2020

21-
SuppressIfOracle("Assert comparisons don't work with Oracle provider because it had to squash names to satisfy length restrictions");
21+
var indexName = "idx_modelwithindexfields_name";
22+
var uniqueName = "uidx_modelwithindexfields_uniquename";
2223

23-
Assert.IsTrue(sql.Contains("idx_modelwithindexfields_name"));
24-
Assert.IsTrue(sql.Contains("uidx_modelwithindexfields_uniquename"));
24+
if (Dialect == Dialect.Oracle)
25+
{
26+
indexName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName);
27+
uniqueName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(uniqueName);
28+
}
29+
30+
Assert.IsTrue(sql.Contains(indexName));
31+
Assert.IsTrue(sql.Contains(uniqueName));
2532
}
2633
}
2734

@@ -36,10 +43,17 @@ public void Can_create_ModelWithCompositeIndexFields_table()
3643

3744
var sql = OrmLiteConfig.DialectProvider.ToCreateIndexStatements(typeof(ModelWithCompositeIndexFields)).Join();
3845

39-
SuppressIfOracle("Assert comparisons don't work with Oracle provider because it had to squash names to satisfy length restrictions");
46+
var indexName = "idx_modelwithcompositeindexfields_name";
47+
var compositeName = "idx_modelwithcompositeindexfields_composite1_composite2";
48+
49+
if (Dialect == Dialect.Oracle)
50+
{
51+
indexName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName);
52+
compositeName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(compositeName);
53+
}
4054

41-
Assert.IsTrue(sql.Contains("idx_modelwithcompositeindexfields_name"));
42-
Assert.IsTrue(sql.Contains("idx_modelwithcompositeindexfields_composite1_composite2"));
55+
Assert.IsTrue(sql.Contains(indexName));
56+
Assert.IsTrue(sql.Contains(compositeName));
4357
}
4458
}
4559

@@ -54,11 +68,18 @@ public void Can_create_ModelWithNamedCompositeIndex_table()
5468

5569
var sql = OrmLiteConfig.DialectProvider.ToCreateIndexStatements(typeof(ModelWithNamedCompositeIndex)).Join();
5670

57-
SuppressIfOracle("Assert comparisons don't work with Oracle provider because it had to squash names to satisfy length restrictions");
71+
var indexName = "idx_modelwithnamedcompositeindex_name";
72+
var compositeName = "uidx_modelwithnamedcompositeindexfields_composite1_composite2";
73+
74+
if (Dialect == Dialect.Oracle)
75+
{
76+
indexName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName);
77+
compositeName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(compositeName);
78+
}
5879

59-
Assert.IsTrue(sql.Contains("idx_modelwithnamedcompositeindex_name"));
80+
Assert.IsTrue(sql.Contains(indexName));
6081
Assert.IsTrue(sql.Contains("custom_index_name"));
61-
Assert.IsFalse(sql.Contains("uidx_modelwithnamedcompositeindexfields_composite1_composite2"));
82+
Assert.IsFalse(sql.Contains(compositeName));
6283
}
6384
}
6485

tests/ServiceStack.OrmLite.Tests/OrmLiteQueryTests.cs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,9 @@ public void Can_select_with_filter_from_ModelWithOnlyStringFields_table()
7878
Assert.That(dbRowIds, Has.Count.EqualTo(1));
7979
Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id));
8080

81-
SuppressIfOracle("Oracle provider is not smart enough to substitute ':' for '@' parameter delimiter.");
82-
8381
rows = db.Select<ModelWithOnlyStringFields>(
84-
"SELECT * FROM {0} WHERE {1} = @AlbumName"
85-
.Fmt("ModelWithOnlyStringFields".SqlTable(), "AlbumName".SqlColumn()),
82+
"SELECT * FROM {0} WHERE {1} = {2}AlbumName"
83+
.Fmt("ModelWithOnlyStringFields".SqlTable(), "AlbumName".SqlColumn(), OrmLiteConfig.DialectProvider.ParamString),
8684
new { filterRow.AlbumName });
8785
dbRowIds = rows.ConvertAll(x => x.Id);
8886
Assert.That(dbRowIds, Has.Count.EqualTo(1));
@@ -180,13 +178,11 @@ public void Can_query_where_and_select_Notes()
180178
Assert.That(notes[0].Id, Is.EqualTo(note.Id));
181179
Assert.That(notes[0].NoteText, Is.EqualTo(note.NoteText));
182180

183-
SuppressIfOracle("Oracle provider is not smart enough to substitute ':' for '@' parameter delimiter.");
184-
185-
notes = db.Select<Note>("SELECT * FROM Note WHERE {0}=@schemaUri".Fmt("SchemaUri".SqlColumn()), new { schemaUri = "tcm:0-0-0" });
181+
notes = db.Select<Note>("SELECT * FROM Note WHERE {0}={1}schemaUri".Fmt("SchemaUri".SqlColumn(), OrmLiteConfig.DialectProvider.ParamString), new { schemaUri = "tcm:0-0-0" });
186182
Assert.That(notes[0].Id, Is.EqualTo(note.Id));
187183
Assert.That(notes[0].NoteText, Is.EqualTo(note.NoteText));
188184

189-
notes = db.Select<Note>("SchemaUri".SqlColumn() + "=@schemaUri", new { schemaUri = "tcm:0-0-0" });
185+
notes = db.Select<Note>("SchemaUri".SqlColumn() + "={0}schemaUri".Fmt(OrmLiteConfig.DialectProvider.ParamString), new { schemaUri = "tcm:0-0-0" });
190186
Assert.That(notes[0].Id, Is.EqualTo(note.Id));
191187
Assert.That(notes[0].NoteText, Is.EqualTo(note.NoteText));
192188
}
@@ -206,25 +202,23 @@ public void Can_select_NotesDto_with_pretty_sql()
206202
{
207203
db.DropAndCreateTable<Note>();
208204

209-
db.Insert(new Note
205+
var id = db.Insert(new Note
210206
{
211207
SchemaUri = "tcm:0-0-0",
212208
NoteText = "Hello world 5",
213209
LastUpdated = new DateTime(2013, 1, 5),
214210
UpdatedBy = "RC"
215-
});
216-
217-
SuppressIfOracle("Oracle provider is not smart enough to substitute ':' for '@' parameter delimiter.");
211+
}, selectIdentity: true);
218212

219213
var sql = @"
220214
SELECT
221215
Id, {0}, {1}
222216
FROM {2}
223-
WHERE {0}=@schemaUri
224-
".Fmt("SchemaUri".SqlColumn(), "NoteText".SqlColumn(), "Note".SqlTable());
217+
WHERE {0}={3}schemaUri
218+
".Fmt("SchemaUri".SqlColumn(), "NoteText".SqlColumn(), "Note".SqlTable(), OrmLiteConfig.DialectProvider.ParamString);
225219

226220
var notes = db.Select<NoteDto>(sql, new { schemaUri = "tcm:0-0-0" });
227-
Assert.That(notes[0].Id, Is.EqualTo(1));
221+
Assert.That(notes[0].Id, Is.EqualTo(id));
228222
Assert.That(notes[0].NoteText, Is.EqualTo("Hello world 5"));
229223
}
230224
}

tests/ServiceStack.OrmLite.Tests/SqlBuilderTests.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,8 @@ public void BuilderSelectClause()
6464
[Test]
6565
public void BuilderTemplateWOComposition()
6666
{
67-
SuppressIfOracle("Oracle provider is not smart enough to replace '@' parameter delimiter with ':'");
68-
6967
var builder = new SqlBuilder();
70-
var template = builder.AddTemplate("SELECT COUNT(*) FROM Users WHERE Age = @age", new { age = 5 });
68+
var template = builder.AddTemplate("SELECT COUNT(*) FROM Users WHERE Age = {0}age".Fmt(OrmLiteConfig.DialectProvider.ParamString), new { age = 5 });
7169

7270
if (template.RawSql == null) throw new Exception("RawSql null");
7371
if (template.Parameters == null) throw new Exception("Parameters null");

tests/ServiceStack.OrmLite.Tests/TestHelpers.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ public static string NormalizeSql(this string sql)
1919
.Replace("`", "")
2020
.Replace("_", "")
2121
.Replace(":", "@") //postgresql
22-
.Replace("\n", " ");
22+
.Replace("\n", " ")
23+
.TrimEnd();
2324
}
2425
}
2526
}

tests/ServiceStack.OrmLite.Tests/TypeWithByteArrayFieldTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void Can_add_attachment()
5555
[Test, Explicit]
5656
public void Can_upload_attachment_via_sp()
5757
{
58-
SuppressIfOracle("Oracle provider is not smart enough to replace parameter delimiter '@' with ':'");
58+
SuppressIfOracle("Oracle does not like this procedure definition");
5959

6060
using (var db = OpenDbConnection())
6161
{
@@ -75,8 +75,8 @@ @filecontent varbinary(MAX))
7575
AS
7676
begin
7777
INSERT INTO [Attachment]([FileName], [Type], [Data], [Description])
78-
VALUES (@filename, @filetype, @filecontent, @filename)
79-
end");
78+
VALUES ({0}filename, {0}filetype, {0}filecontent, {0}filename)
79+
end".Fmt(OrmLiteConfig.DialectProvider.ParamString));
8080
var bytes = "https://www.google.com/images/srpr/logo11w.png".GetBytesFromUrl();
8181

8282
db.ExecuteNonQuery("EXEC SP_upload_file @filename, @filetype, @filecontent",
@@ -95,7 +95,7 @@ INSERT INTO [Attachment]([FileName], [Type], [Data], [Description])
9595
[Test, Explicit]
9696
public void Can_upload_attachment_via_sp_with_ADONET()
9797
{
98-
SuppressIfOracle("Oracle provider is not smart enough to replace parameter delimiter '@' with ':'");
98+
SuppressIfOracle("Oracle does not like this procedure definition");
9999

100100
using (var db = OpenDbConnection())
101101
{
@@ -115,8 +115,8 @@ @filecontent varbinary(MAX))
115115
AS
116116
begin
117117
INSERT INTO [Attachment]([FileName], [Type], [Data], [Description])
118-
VALUES (@filename, @filetype, @filecontent, @filename)
119-
end");
118+
VALUES ({0}filename, {0}filetype, {0}filecontent, {0}filename)
119+
end".Fmt(OrmLiteConfig.DialectProvider.ParamString));
120120
var bytes = "https://www.google.com/images/srpr/logo11w.png".GetBytesFromUrl();
121121

122122
using (var dbCmd = db.CreateCommand())

0 commit comments

Comments
 (0)