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

Commit 0cb5403

Browse files
committed
Merge pull request #423 from jeffgabhart/issue/pg-text-array-functions
Support postgresql text array and execute function example
2 parents cdf8d9a + 440dd96 commit 0cb5403

File tree

5 files changed

+50
-10
lines changed

5 files changed

+50
-10
lines changed

src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteExecuteProcedureTests.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using NUnit.Framework;
22
using ServiceStack.DataAnnotations;
33
using ServiceStack.OrmLite.Tests;
4+
using ServiceStack.Text;
45

56
namespace ServiceStack.OrmLite.PostgreSQL.Tests
67
{
@@ -11,8 +12,8 @@ public OrmLiteExecuteProcedureTests() : base(Dialect.PostgreSql) { }
1112

1213
private const string Create = @"
1314
CREATE OR REPLACE FUNCTION f_service_stack(
14-
v_string_values CHARACTER VARYING[],
15-
v_integer_values INTEGER[]
15+
v_string_values text[],
16+
v_integer_values integer[]
1617
) RETURNS BOOLEAN AS
1718
$BODY$
1819
BEGIN
@@ -37,12 +38,14 @@ IF v_integer_values[3] <> 3 THEN
3738
LANGUAGE plpgsql VOLATILE COST 100;
3839
";
3940

40-
private const string Drop = "DROP FUNCTION f_service_stack(CHARACTER VARYING[], INTEGER[]);";
41+
private const string Drop = "DROP FUNCTION f_service_stack(text[], integer[]);";
4142

4243
[Alias("f_service_stack")]
4344
public class ServiceStackFunction
4445
{
46+
[CustomField("text[]")]
4547
public string[] StringValues { get; set; }
48+
[CustomField("integer[]")]
4649
public int[] IntegerValues { get; set; }
4750
}
4851

@@ -52,12 +55,14 @@ public void Can_execute_stored_procedure_with_array_arguments()
5255
using (var db = OpenDbConnection())
5356
{
5457
db.ExecuteSql(Create);
58+
db.GetLastSql().Print();
5559

5660
db.ExecuteProcedure(new ServiceStackFunction
57-
{
58-
StringValues = new[] { "ServiceStack", "Thoughtfully Architected" },
59-
IntegerValues = new[] { 1, 2, 3 }
60-
});
61+
{
62+
StringValues = new[] { "ServiceStack", "Thoughtfully Architected" },
63+
IntegerValues = new[] { 1, 2, 3 }
64+
});
65+
6166
db.ExecuteSql(Drop);
6267
}
6368
}

src/ServiceStack.OrmLite.PostgreSQL/PostgreSQLDialectProvider.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,12 @@ public override void SetParameter(FieldDefinition fieldDef, IDbDataParameter p)
334334
((NpgsqlParameter) p).NpgsqlDbType = NpgsqlDbType.Json;
335335
return;
336336
}
337+
if (fieldDef.CustomFieldDefinition == "text[]")
338+
{
339+
p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName));
340+
((NpgsqlParameter)p).NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Text;
341+
return;
342+
}
337343
if (fieldDef.CustomFieldDefinition == "integer[]")
338344
{
339345
p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName));
@@ -350,6 +356,10 @@ public override void SetParameter(FieldDefinition fieldDef, IDbDataParameter p)
350356
}
351357
protected override object GetValue<T>(FieldDefinition fieldDef, object obj)
352358
{
359+
if (fieldDef.CustomFieldDefinition == "text[]")
360+
{
361+
return fieldDef.GetValue(obj);
362+
}
353363
if (fieldDef.CustomFieldDefinition == "integer[]")
354364
{
355365
return fieldDef.GetValue(obj);
@@ -360,5 +370,23 @@ protected override object GetValue<T>(FieldDefinition fieldDef, object obj)
360370
}
361371
return base.GetValue<T>(fieldDef, obj);
362372
}
373+
374+
public override void PrepareStoredProcedureStatement<T>(IDbCommand cmd, T obj)
375+
{
376+
var tableType = obj.GetType();
377+
var modelDef = GetModel(tableType);
378+
379+
cmd.CommandText = GetQuotedTableName(modelDef);
380+
cmd.CommandType = CommandType.StoredProcedure;
381+
382+
foreach (var fieldDef in modelDef.FieldDefinitions)
383+
{
384+
var p = cmd.CreateParameter();
385+
SetParameter(fieldDef, p);
386+
cmd.Parameters.Add(p);
387+
}
388+
389+
SetParameterValues<T>(cmd, obj);
390+
}
363391
}
364392
}

src/ServiceStack.OrmLite/IOrmLiteDialectProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ string GetColumnDefinition(
8686

8787
bool PrepareParameterizedDeleteStatement<T>(IDbCommand cmd, ICollection<string> deleteFields = null);
8888

89+
void PrepareStoredProcedureStatement<T>(IDbCommand cmd, T obj);
90+
8991
void SetParameterValues<T>(IDbCommand dbCmd, object obj);
9092

9193
Dictionary<string, FieldDefinition> GetFieldDefinitionMap(ModelDefinition modelDef);

src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,12 @@ public virtual bool PrepareParameterizedDeleteStatement<T>(IDbCommand cmd, IColl
668668
return hadRowVesion;
669669
}
670670

671+
public virtual void PrepareStoredProcedureStatement<T>(IDbCommand cmd, T obj)
672+
{
673+
cmd.CommandText = ToExecuteProcedureStatement(obj);
674+
cmd.CommandType = CommandType.StoredProcedure;
675+
}
676+
671677
protected void AddParameter(IDbCommand cmd, FieldDefinition fieldDef)
672678
{
673679
var p = cmd.CreateParameter();

src/ServiceStack.OrmLite/OrmLiteWriteCommandExtensions.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -907,9 +907,8 @@ internal static void SaveReferences<T, TRef>(this IDbCommand dbCmd, T instance,
907907
internal static void ExecuteProcedure<T>(this IDbCommand dbCmd, T obj)
908908
{
909909
var dialectProvider = dbCmd.GetDialectProvider();
910-
string sql = dialectProvider.ToExecuteProcedureStatement(obj);
911-
dbCmd.CommandType = CommandType.StoredProcedure;
912-
dbCmd.ExecuteSql(sql);
910+
dialectProvider.PrepareStoredProcedureStatement(dbCmd, obj);
911+
dbCmd.ExecuteNonQuery();
913912
}
914913

915914
internal static ulong GetRowVersion(this IDbCommand dbCmd, ModelDefinition modelDef, object id)

0 commit comments

Comments
 (0)