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

Commit 233f22c

Browse files
committed
2 parents 82d1352 + 2d0adb6 commit 233f22c

File tree

9 files changed

+535
-251
lines changed

9 files changed

+535
-251
lines changed

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

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,19 @@
44
namespace ServiceStack.OrmLite.PostgreSQL.Tests
55
{
66
public class TypeWithByteArrayFieldTests : OrmLiteTestBase
7-
{
7+
{
8+
TypeWithByteArrayField getSampleObject()
9+
{
10+
var testByteArray = new byte[256];
11+
for(int i = 0; i < 256; i++) { testByteArray[i] = (byte)i; }
12+
13+
return new TypeWithByteArrayField { Id = 1, Content = testByteArray };
14+
}
15+
816
[Test]
917
public void CanInsertAndSelectByteArray()
1018
{
11-
var orig = new TypeWithByteArrayField { Id = 1, Content = new byte[] { 0, 17, 0, 17, 0, 7 } };
19+
var orig = getSampleObject();
1220

1321
using (var db = ConnectionString.OpenDbConnection())
1422
{
@@ -21,6 +29,116 @@ public void CanInsertAndSelectByteArray()
2129
Assert.AreEqual(orig.Id, target.Id);
2230
Assert.AreEqual(orig.Content, target.Content);
2331
}
32+
}
33+
34+
[Test]
35+
public void CanInsertAndSelectByteArray__manual_insert__manual_select()
36+
{
37+
var orig = getSampleObject();
38+
39+
using(var db = ConnectionString.OpenDbConnection()) {
40+
//insert and select manually - ok
41+
db.CreateTable<TypeWithByteArrayField>(true);
42+
_insertManually(orig, db);
43+
44+
_selectAndVerifyManually(orig, db);
45+
}
46+
}
47+
48+
[Test]
49+
public void CanInsertAndSelectByteArray__InsertParam_insert__manual_select()
50+
{
51+
var orig = getSampleObject();
52+
53+
using(var db = ConnectionString.OpenDbConnection()) {
54+
//insert using InsertParam, and select manually - ok
55+
db.CreateTable<TypeWithByteArrayField>(true);
56+
db.InsertParam(orig);
57+
58+
_selectAndVerifyManually(orig, db);
59+
}
60+
}
61+
62+
[Test]
63+
public void CanInsertAndSelectByteArray__InsertParam_insert__GetById_select()
64+
{
65+
var orig = getSampleObject();
66+
67+
using(var db = ConnectionString.OpenDbConnection()) {
68+
//InsertParam + GetByID - fails
69+
db.CreateTable<TypeWithByteArrayField>(true);
70+
db.InsertParam(orig);
71+
72+
var target = db.GetById<TypeWithByteArrayField>(orig.Id);
73+
74+
Assert.AreEqual(orig.Id, target.Id);
75+
Assert.AreEqual(orig.Content, target.Content);
76+
}
77+
}
78+
79+
[Test]
80+
public void CanInsertAndSelectByteArray__Insert_insert__GetById_select()
81+
{
82+
var orig = getSampleObject();
83+
84+
using(var db = ConnectionString.OpenDbConnection()) {
85+
//InsertParam + GetByID - fails
86+
db.CreateTable<TypeWithByteArrayField>(true);
87+
db.Insert(orig);
88+
89+
var target = db.GetById<TypeWithByteArrayField>(orig.Id);
90+
91+
Assert.AreEqual(orig.Id, target.Id);
92+
Assert.AreEqual(orig.Content, target.Content);
93+
}
94+
}
95+
96+
[Test]
97+
public void CanInsertAndSelectByteArray__Insert_insert__manual_select()
98+
{
99+
var orig = getSampleObject();
100+
101+
using(var db = ConnectionString.OpenDbConnection()) {
102+
//InsertParam + GetByID - fails
103+
db.CreateTable<TypeWithByteArrayField>(true);
104+
db.Insert(orig);
105+
106+
_selectAndVerifyManually(orig, db);
107+
}
108+
}
109+
110+
private static void _selectAndVerifyManually(TypeWithByteArrayField orig, System.Data.IDbConnection db)
111+
{
112+
using(var cmd = db.CreateCommand()) {
113+
cmd.CommandText = @"select ""Content"" from ""TypeWithByteArrayField"" where ""Id"" = 1 --manual select";
114+
using(var reader = cmd.ExecuteReader()) {
115+
reader.Read();
116+
var ba = reader["Content"] as byte[];
117+
Assert.AreEqual(orig.Content.Length, ba.Length);
118+
Assert.AreEqual(orig.Content, ba);
119+
}
120+
}
121+
}
122+
123+
private static void _insertManually(TypeWithByteArrayField orig, System.Data.IDbConnection db)
124+
{
125+
using(var cmd = db.CreateCommand()) {
126+
cmd.CommandText = @"INSERT INTO ""TypeWithByteArrayField"" (""Id"",""Content"") VALUES (@Id, @Content) --manual parameterized insert";
127+
128+
var p_id = cmd.CreateParameter();
129+
p_id.ParameterName = "@Id";
130+
p_id.Value = orig.Id;
131+
132+
cmd.Parameters.Add(p_id);
133+
134+
var p_content = cmd.CreateParameter();
135+
p_content.ParameterName = "@Content";
136+
p_content.Value = orig.Content;
137+
138+
cmd.Parameters.Add(p_content);
139+
140+
cmd.ExecuteNonQuery();
141+
}
24142
}
25143
}
26144

src/ServiceStack.OrmLite.PostgreSQL/PostgreSQLDialectProvider.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,20 @@ public override string GetQuotedValue(object value, Type fieldType)
122122
var guidValue = (Guid)value;
123123
return base.GetQuotedValue(guidValue.ToString("N"), typeof(string));
124124
}
125+
if(fieldType == typeof(byte[]))
126+
{
127+
return "E'" + ToBinary(value) + "'";
128+
}
125129

126130
return base.GetQuotedValue(value, fieldType);
127131
}
128132

129133
public override object ConvertDbValue(object value, Type type)
130134
{
131135
if (value == null || value is DBNull) return null;
132-
136+
137+
if(type == typeof(byte[])) { return value; }
138+
133139
return base.ConvertDbValue(value, type);
134140
}
135141

@@ -196,5 +202,27 @@ public override string GetQuotedTableName(ModelDefinition modelDef)
196202
string escapedSchema = modelDef.Schema.Replace(".", "\".\"");
197203
return string.Format("\"{0}\".\"{1}\"", escapedSchema, base.NamingStrategy.GetTableName(modelDef.ModelName));
198204
}
205+
206+
/// <summary>
207+
/// based on Npgsql2's source: Npgsql2\src\NpgsqlTypes\NpgsqlTypeConverters.cs
208+
/// </summary>
209+
/// <param name="TypeInfo"></param>
210+
/// <param name="NativeData"></param>
211+
/// <param name="ForExtendedQuery"></param>
212+
/// <returns></returns>
213+
internal static String ToBinary(Object NativeData)
214+
{
215+
Byte[] byteArray = (Byte[])NativeData;
216+
StringBuilder res = new StringBuilder(byteArray.Length * 5);
217+
foreach(byte b in byteArray)
218+
if(b >= 0x20 && b < 0x7F && b != 0x27 && b != 0x5C)
219+
res.Append((char)b);
220+
else
221+
res.Append("\\\\")
222+
.Append((char)('0' + (7 & (b >> 6))))
223+
.Append((char)('0' + (7 & (b >> 3))))
224+
.Append((char)('0' + (7 & b)));
225+
return res.ToString();
226+
}
199227
}
200228
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Data;
6+
7+
namespace ServiceStack.OrmLite
8+
{
9+
public class OrmLiteSPStatement
10+
{
11+
private IDbCommand command { get; set; }
12+
13+
public OrmLiteSPStatement(IDbCommand cmd)
14+
{
15+
command = cmd;
16+
}
17+
18+
public List<T> ConvertToList<T>() where T : new()
19+
{
20+
if ((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))
21+
throw new Exception("Type " + typeof(T).Name + " is a primitive type. Use ConvertScalarToList function.");
22+
23+
IDataReader reader = null;
24+
try
25+
{
26+
reader = command.ExecuteReader();
27+
return reader.ConvertToList<T>();
28+
}
29+
finally
30+
{
31+
if (reader != null)
32+
reader.Close();
33+
}
34+
}
35+
36+
public List<T> ConvertToScalarList<T>()
37+
{
38+
if (!((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String))))
39+
throw new Exception("Type " + typeof(T).Name + " is a non primitive type. Use ConvertToList function.");
40+
41+
IDataReader reader = null;
42+
try
43+
{
44+
reader = command.ExecuteReader();
45+
#pragma warning disable 618
46+
return reader.GetFirstColumn<T>();
47+
#pragma warning restore 618
48+
}
49+
finally
50+
{
51+
if (reader != null)
52+
reader.Close();
53+
}
54+
}
55+
56+
public T ConvertTo<T>() where T : new()
57+
{
58+
if ((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))
59+
throw new Exception("Type " + typeof(T).Name + " is a primitive type. Use ConvertScalarTo function.");
60+
61+
IDataReader reader = null;
62+
try
63+
{
64+
reader = command.ExecuteReader();
65+
return reader.ConvertTo<T>();
66+
}
67+
finally
68+
{
69+
if (reader != null)
70+
reader.Close();
71+
}
72+
}
73+
74+
public T ConvertToScalar<T>()
75+
{
76+
if (!((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String))))
77+
throw new Exception("Type " + typeof(T).Name + " is a non primitive type. Use ConvertTo function.");
78+
79+
IDataReader reader = null;
80+
try
81+
{
82+
reader = command.ExecuteReader();
83+
#pragma warning disable 618
84+
return reader.GetScalar<T>();
85+
#pragma warning restore 618
86+
}
87+
finally
88+
{
89+
if (reader != null)
90+
reader.Close();
91+
}
92+
}
93+
94+
public List<T> ConvertFirstColumnToList<T>()
95+
{
96+
if (!((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String))))
97+
throw new Exception("Type " + typeof(T).Name + " is a non primitive type. Only primitive type can be used.");
98+
99+
IDataReader reader = null;
100+
try
101+
{
102+
reader = command.ExecuteReader();
103+
#pragma warning disable 618
104+
return reader.GetFirstColumn<T>();
105+
#pragma warning restore 618
106+
}
107+
finally
108+
{
109+
if (reader != null)
110+
reader.Close();
111+
}
112+
}
113+
114+
public HashSet<T> ConvertFirstColumnToListDistinct<T>() where T : new()
115+
{
116+
if (!((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String))))
117+
throw new Exception("Type " + typeof(T).Name + " is a non primitive type. Only primitive type can be used.");
118+
119+
IDataReader reader = null;
120+
try
121+
{
122+
reader = command.ExecuteReader();
123+
#pragma warning disable 618
124+
return reader.GetFirstColumnDistinct<T>();
125+
#pragma warning restore 618
126+
}
127+
finally
128+
{
129+
if (reader != null)
130+
reader.Close();
131+
}
132+
}
133+
134+
public int ExecuteNonQuery()
135+
{
136+
return command.ExecuteNonQuery();
137+
}
138+
139+
public bool HasResult()
140+
{
141+
IDataReader reader = null;
142+
try
143+
{
144+
reader = command.ExecuteReader();
145+
if (reader.Read())
146+
return true;
147+
else
148+
return false;
149+
}
150+
finally
151+
{
152+
if (reader != null)
153+
reader.Close();
154+
}
155+
}
156+
}
157+
}

src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
<Compile Include="ForeignKeyAttribute.cs" />
103103
<Compile Include="JoinSqlBuilder.cs" />
104104
<Compile Include="OrmLiteReadConnectionExtensions.cs" />
105+
<Compile Include="OrmLiteSPStatement.cs" />
105106
<Compile Include="OrmLiteTransaction.cs" />
106107
<Compile Include="OrmLiteWriteConnectionExtensions.cs" />
107108
<Compile Include="DbTypes.cs" />

0 commit comments

Comments
 (0)