Skip to content

Commit

Permalink
Merge pull request #707 from Curlack/feature/oracle-support
Browse files Browse the repository at this point in the history
Fix some more failing integration tests

Fixes #691 
Fixes #255
  • Loading branch information
Ste1io authored Oct 23, 2023
2 parents 7975531 + b36c22b commit 719731a
Show file tree
Hide file tree
Showing 10 changed files with 499 additions and 60 deletions.
133 changes: 124 additions & 9 deletions PetaPoco.Tests.Integration/Databases/OracleTests/OracleQueryTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PetaPoco.Core;
using PetaPoco.Tests.Integration.Models;
using PetaPoco.Tests.Integration.Providers;
Expand All @@ -17,6 +18,107 @@ public OracleQueryTests()
{
}

[Fact]
public override async Task FetchAsyncWithPaging_ForDynamicTypeGivenSql_ShouldReturnValidDynamicTypeCollection()
{
AddOrders(12);
var pd = PocoData.ForType(typeof(Order), DB.DefaultMapper);

var sql = new Sql(
$"SELECT t.* FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} t " +
$"WHERE t.{DB.Provider.EscapeSqlIdentifier(pd.Columns.Values.First(c => c.PropertyInfo.Name == "Status").ColumnName)} = @0", OrderStatus.Pending);

var results = await DB.FetchAsync<dynamic>(2, 1, sql);
results.Count.ShouldBe(1);
}

[Fact]
public override async Task FetchAsyncWithPaging_ForDynamicTypeGivenSqlStringAndParameters_ShouldReturnValidDynamicTypeCollection()
{
AddOrders(12);
var pd = PocoData.ForType(typeof(Order), DB.DefaultMapper);
var sql = $"SELECT t.* FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} t " +
$"WHERE t.{DB.Provider.EscapeSqlIdentifier(pd.Columns.Values.First(c => c.PropertyInfo.Name == "Status").ColumnName)} = @0";

var results = await DB.FetchAsync<dynamic>(2, 1, sql, OrderStatus.Pending);
results.Count.ShouldBe(1);
}

[Fact]
public override void FetchWithPaging_ForDynamicTypeGivenSql_ShouldReturnValidDynamicTypeCollection()
{
AddOrders(12);
var pd = PocoData.ForType(typeof(Order), DB.DefaultMapper);
var sql = new Sql(
$"SELECT t.* FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} t " +
$"WHERE t.{DB.Provider.EscapeSqlIdentifier(pd.Columns.Values.First(c => c.PropertyInfo.Name == "Status").ColumnName)} = @0", OrderStatus.Pending);

var results = DB.Fetch<dynamic>(2, 1, sql);
results.Count.ShouldBe(1);
}

[Fact]
public override void FetchWithPaging_ForDynamicTypeGivenSqlStringAndParameters_ShouldReturnValidDynamicTypeCollection()
{
AddOrders(12);
var pd = PocoData.ForType(typeof(Order), DB.DefaultMapper);
var sql = $"SELECT t.* FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} t " +
$"WHERE t.{DB.Provider.EscapeSqlIdentifier(pd.Columns.Values.First(c => c.PropertyInfo.Name == "Status").ColumnName)} = @0";

var results = DB.Fetch<dynamic>(2, 1, sql, OrderStatus.Pending);
results.Count.ShouldBe(1);
}

[Fact]
public override void SkipAndTake_ForDynamicTypeGivenSql_ShouldReturnValidDynamicTypeCollection()
{
AddOrders(12);
var pd = PocoData.ForType(typeof(Order), DB.DefaultMapper);
var sql = new Sql(
$"SELECT t.* FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} t " +
$"WHERE t.{DB.Provider.EscapeSqlIdentifier(pd.Columns.Values.First(c => c.PropertyInfo.Name == "Status").ColumnName)} = @0", OrderStatus.Pending);

var results = DB.SkipTake<dynamic>(2, 1, sql);
results.Count.ShouldBe(1);
}

[Fact]
public override void SkipAndTake_ForDynamicTypeGivenSqlStringAndParameters_ShouldReturnValidDynamicTypeCollection()
{
AddOrders(12);
var pd = PocoData.ForType(typeof(Order), DB.DefaultMapper);
var sql = $"SELECT t.* FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} t " +
$"WHERE t.{DB.Provider.EscapeSqlIdentifier(pd.Columns.Values.First(c => c.PropertyInfo.Name == "Status").ColumnName)} = @0";

var results = DB.SkipTake<dynamic>(2, 1, sql, OrderStatus.Pending);
results.Count.ShouldBe(1);
}

[Fact]
public override async Task SkipAndTakeAsync_ForDynamicTypeGivenSql_ShouldReturnValidDynamicTypeCollection()
{
AddOrders(12);
var pd = PocoData.ForType(typeof(Order), DB.DefaultMapper);
var sql = new Sql(
$"SELECT t.* FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} t " +
$"WHERE t.{DB.Provider.EscapeSqlIdentifier(pd.Columns.Values.First(c => c.PropertyInfo.Name == "Status").ColumnName)} = @0", OrderStatus.Pending);

var results = await DB.SkipTakeAsync<dynamic>(2, 1, sql);
results.Count.ShouldBe(1);
}

[Fact]
public override async Task SkipAndTakeAsync_ForDynamicTypeGivenSqlStringAndParameters_ShouldReturnValidDynamicTypeCollection()
{
AddOrders(12);
var pd = PocoData.ForType(typeof(Order), DB.DefaultMapper);
var sql = $"SELECT t.* FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} t " +
$"WHERE t.{DB.Provider.EscapeSqlIdentifier(pd.Columns.Values.First(c => c.PropertyInfo.Name == "Status").ColumnName)} = @0";

var results = await DB.SkipTakeAsync<dynamic>(2, 1, sql, OrderStatus.Pending);
results.Count.ShouldBe(1);
}

[Fact]
public override void QueryMultiple_ForSingleResultsSetWithSinglePoco_ShouldReturnValidPocoCollection()
{
Expand All @@ -26,8 +128,8 @@ public override void QueryMultiple_ForSingleResultsSetWithSinglePoco_ShouldRetur
var pdName = pd.Columns.Values.First(c => c.PropertyInfo.Name == "Name").ColumnName;

var sql = $@"SELECT *
FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)}
WHERE {DB.Provider.EscapeSqlIdentifier(pdName)} LIKE @0 || '%';";
FROM {DB.Provider.EscapeTableName(pd.TableInfo.TableName)}
WHERE {DB.Provider.EscapeSqlIdentifier(pdName)} LIKE @0 || '%'";

List<Person> result;
using (var multi = DB.QueryMultiple(sql, "Peta"))
Expand All @@ -54,11 +156,22 @@ public override void QueryMultiple_ForSingleResultsSetWithMultiPoco_ShouldReturn
var pdName = pd.Columns.Values.First(c => c.PropertyInfo.Name == "Name").ColumnName;
var odPersonId = od.Columns.Values.First(c => c.PropertyInfo.Name == "PersonId").ColumnName;

var sql = $@"SELECT * FROM {DB.Provider.EscapeTableName(od.TableInfo.TableName)} o
INNER JOIN {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} p ON p.{DB.Provider.EscapeSqlIdentifier(pdId)} = o.{DB.Provider.EscapeSqlIdentifier(odPersonId)}
WHERE p.{DB.Provider.EscapeSqlIdentifier(pdName)} = @0
ORDER BY 1 DESC
LIMIT 1;";
//Oracle 12c and above only
// var sql = $@"SELECT *
//FROM {DB.Provider.EscapeTableName(od.TableInfo.TableName)} o
// INNER JOIN {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} p ON p.{DB.Provider.EscapeSqlIdentifier(pdId)} = o.{DB.Provider.EscapeSqlIdentifier(odPersonId)}
//WHERE p.{DB.Provider.EscapeSqlIdentifier(pdName)} = @0
//ORDER BY 1 DESC
//FETCH FIRST 1 ROWS ONLY";

var sql = $@"SELECT *
FROM (SELECT *
FROM {DB.Provider.EscapeTableName(od.TableInfo.TableName)} o
INNER JOIN {DB.Provider.EscapeTableName(pd.TableInfo.TableName)} p
ON p.{DB.Provider.EscapeSqlIdentifier(pdId)} = o.{DB.Provider.EscapeSqlIdentifier(odPersonId)}
WHERE p.{DB.Provider.EscapeSqlIdentifier(pdName)} = @0
ORDER BY 1 DESC)
WHERE ROWNUM <= 1";

List<Order> result;
using (var multi = DB.QueryMultiple(sql, "Peta0"))
Expand Down Expand Up @@ -86,7 +199,8 @@ ORDER BY 1 DESC
order.Person.Age.ShouldBe(18);
}

[Fact]
// FIXME: Oracle.ManagedDataAccess.Client.OracleException : ORA-03048: SQL reserved word ';' is not syntactically valid following '...ORDER BY o.Id ASC'
[Fact(Skip = "Limited support for QueryMultiple by provider due to need for multiple statements in a single command.")]
public override void QueryMultiple_ForMultiResultsSetWithSinglePoco_ShouldReturnValidPocoCollection()
{
AddOrders(1);
Expand Down Expand Up @@ -120,7 +234,8 @@ public override void QueryMultiple_ForMultiResultsSetWithSinglePoco_ShouldReturn
order.Person.Age.ShouldBe(18);
}

[Fact]
// FIXME: Oracle.ManagedDataAccess.Client.OracleException : ORA-03048: SQL reserved word ';' is not syntactically valid following '...ORDER BY o.Id ASC'
[Fact(Skip = "Limited support for QueryMultiple by provider due to need for multiple statements in a single command.")]
public override void QueryMultiple_ForMultiResultsSetWithMultiPoco_ShouldReturnValidPocoCollection()
{
AddOrders(12);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using Oracle.ManagedDataAccess.Client;
using PetaPoco.Tests.Integration.Models;
using PetaPoco.Tests.Integration.Providers;
using Shouldly;
using Xunit;

namespace PetaPoco.Tests.Integration.Databases.Oracle
Expand All @@ -14,5 +20,193 @@ public OracleStoredProcTests()
: base(new OracleTestProvider())
{
}

private IDataParameter GetOutputParameter() => new OracleParameter("p_out_cursor", OracleDbType.RefCursor, ParameterDirection.Output);

[Fact]
public override void QueryProc_NoParam_ShouldReturnAll()
{
var results = DB.QueryProc<Person>("SelectPeople", GetOutputParameter()).ToArray();
results.Length.ShouldBe(6);
}

[Fact]
public override void QueryProc_WithParam_ShouldReturnSome()
{
var results = DB.QueryProc<Person>("SelectPeopleWithParam", new { age = 20 }, GetOutputParameter()).ToArray();
results.Length.ShouldBe(3);
}

[Fact]
public override void QueryProc_WithDbParam_ShouldReturnSome()
{
var results = DB.QueryProc<Person>("SelectPeopleWithParam", GetDataParameter(), GetOutputParameter()).ToArray();
results.Length.ShouldBe(3);
}

[Fact]
public override void FetchProc_NoParam_ShouldReturnAll()
{
var results = DB.FetchProc<Person>("SelectPeople", GetOutputParameter());
results.Count.ShouldBe(6);
}

[Fact]
public override void FetchProc_WithParam_ShouldReturnSome()
{
var results = DB.FetchProc<Person>("SelectPeopleWithParam", new { age = 20 }, GetOutputParameter());
results.Count.ShouldBe(3);
}

[Fact]
public override void FetchProc_WithDbParam_ShouldReturnSome()
{
var results = DB.FetchProc<Person>("SelectPeopleWithParam", GetDataParameter(), GetOutputParameter());
results.Count.ShouldBe(3);
}

[Fact]
public override void ScalarProc_NoParam_ShouldReturnAll()
{
var count = DB.ExecuteScalarProc<int>("CountPeople", GetOutputParameter());
count.ShouldBe(6);
}

[Fact]
public override void ScalarProc_WithParam_ShouldReturnSome()
{
var count = DB.ExecuteScalarProc<int>("CountPeopleWithParam", new { age = 20 }, GetOutputParameter());
count.ShouldBe(3);
}

[Fact]
public override void ScalarProc_WithDbParam_ShouldReturnSome()
{
var count = DB.ExecuteScalarProc<int>("CountPeopleWithParam", GetDataParameter(), GetOutputParameter());
count.ShouldBe(3);
}

[Fact]
public override void NonQueryProc_NoParam_ShouldUpdateAll()
{
DB.ExecuteNonQueryProc("UpdatePeople");
DB.Query<Person>($"WHERE {DB.Provider.EscapeSqlIdentifier("FullName")}='Updated'").Count().ShouldBe(6);
}

[Fact]
public override void NonQueryProc_WithParam_ShouldUpdateSome()
{
DB.ExecuteNonQueryProc("UpdatePeopleWithParam", new { age = 20 });
DB.Query<Person>($"WHERE {DB.Provider.EscapeSqlIdentifier("FullName")}='Updated'").Count().ShouldBe(3);
}

[Fact]
public override void NonQueryProc_WithDbParam_ShouldUpdateSome()
{
DB.ExecuteNonQueryProc("UpdatePeopleWithParam", GetDataParameter());
DB.Query<Person>($"WHERE {DB.Provider.EscapeSqlIdentifier("FullName")}='Updated'").Count().ShouldBe(3);
}

[Fact]
public override async Task QueryProcAsync_NoParam_ShouldReturnAll()
{
var results = new List<Person>();
await DB.QueryProcAsync<Person>(p => results.Add(p), "SelectPeople", GetOutputParameter());
results.Count.ShouldBe(6);
}

[Fact]
public override async Task QueryProcAsync_WithParam_ShouldReturnSome()
{
var results = new List<Person>();
await DB.QueryProcAsync<Person>(p => results.Add(p), "SelectPeopleWithParam", new { age = 20 }, GetOutputParameter());
results.Count.ShouldBe(3);
}

[Fact]
public override async Task QueryProcAsync_WithDbParam_ShouldReturnSome()
{
var results = new List<Person>();
await DB.QueryProcAsync<Person>(p => results.Add(p), "SelectPeopleWithParam", GetDataParameter(), GetOutputParameter());
results.Count.ShouldBe(3);
}

[Fact]
public override async Task QueryProcAsyncReader_NoParam_ShouldReturnAll()
{
var results = new List<Person>();
using (var reader = await DB.QueryProcAsync<Person>("SelectPeople", GetOutputParameter()))
{
while (await reader.ReadAsync())
results.Add(reader.Poco);
}
results.Count.ShouldBe(6);
}

[Fact]
public override async Task QueryProcAsyncReader_WithParam_ShouldReturnSome()
{
var results = new List<Person>();
using (var reader = await DB.QueryProcAsync<Person>("SelectPeopleWithParam", new { age = 20 }, GetOutputParameter()))
{
while (await reader.ReadAsync())
results.Add(reader.Poco);
}
results.Count.ShouldBe(3);
}

[Fact]
public override async Task QueryProcAsyncReader_WithDbParam_ShouldReturnSome()
{
var results = new List<Person>();
using (var reader = await DB.QueryProcAsync<Person>("SelectPeopleWithParam", GetDataParameter(), GetOutputParameter()))
{
while (await reader.ReadAsync())
results.Add(reader.Poco);
}
results.Count.ShouldBe(3);
}

[Fact]
public override async Task FetchProcAsync_NoParam_ShouldReturnAll()
{
var results = await DB.FetchProcAsync<Person>("SelectPeople", GetOutputParameter());
results.Count.ShouldBe(6);
}

[Fact]
public override async Task FetchProcAsync_WithParam_ShouldReturnSome()
{
var results = await DB.FetchProcAsync<Person>("SelectPeopleWithParam", new { age = 20 }, GetOutputParameter());
results.Count.ShouldBe(3);
}

[Fact]
public override async Task FetchProcAsync_WithDbParam_ShouldReturnSome()
{
var results = await DB.FetchProcAsync<Person>("SelectPeopleWithParam", GetDataParameter(), GetOutputParameter());
results.Count.ShouldBe(3);
}

[Fact]
public override async Task ScalarProcAsync_NoParam_ShouldReturnAll()
{
var count = await DB.ExecuteScalarProcAsync<int>("CountPeople", GetOutputParameter());
count.ShouldBe(6);
}

[Fact]
public override async Task ScalarProcAsync_WithParam_ShouldReturnSome()
{
var count = await DB.ExecuteScalarProcAsync<int>("CountPeopleWithParam", new { age = 20 }, GetOutputParameter());
count.ShouldBe(3);
}

[Fact]
public override async Task ScalarProcAsync_WithDbParam_ShouldReturnSome()
{
var count = await DB.ExecuteScalarProcAsync<int>("CountPeopleWithParam", GetDataParameter(), GetOutputParameter());
count.ShouldBe(3);
}
}
}
Loading

0 comments on commit 719731a

Please sign in to comment.