Skip to content

Commit 970c259

Browse files
committed
Npgsql: Demonstrate OBJECT type mapping using JsonDocument
CrateDB's OBJECT data type can also be communicated using .NET's native `System.Text.Json.JsonDocument` type.
1 parent be0835d commit 970c259

File tree

3 files changed

+91
-4
lines changed

3 files changed

+91
-4
lines changed

by-language/csharp-npgsql/DemoProgram.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ await Parser.Default.ParseArguments<Options>(args)
2828
await DatabaseWorkloads.BasicConversationExample(conn);
2929
await DatabaseWorkloads.UnnestExample(conn);
3030
await DatabaseWorkloadsMore.AllTypesNativeExample(conn);
31+
await DatabaseWorkloadsMore.ObjectJsonDocumentExample(conn);
32+
// await DatabaseWorkloadsMore.ArrayJsonDocumentExample(conn);
3133
await DatabaseWorkloadsMore.ObjectPocoExample(conn);
3234
await DatabaseWorkloadsMore.ArrayPocoExample(conn);
3335
conn.Close();

by-language/csharp-npgsql/DemoTypes.cs

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
#nullable enable
22
using System;
3-
using System.Collections;
43
using System.Collections.Generic;
54
using System.Data;
6-
using System.Reflection;
5+
using System.Text.Json;
76
using System.Threading.Tasks;
87
using Newtonsoft.Json;
98
using Npgsql;
@@ -57,9 +56,9 @@ public class AllTypesRecord
5756
public class DatabaseWorkloadsMore
5857
{
5958

60-
public static async Task<DataTable> AllTypesNativeExample(NpgsqlConnection conn)
59+
public static async Task ProvisionAllTypes(NpgsqlConnection conn)
6160
{
62-
Console.WriteLine("Running AllTypesNativeExample");
61+
Console.WriteLine("Running ProvisionAllTypes");
6362

6463
// Submit DDL, create database schema.
6564
await using (var cmd = new NpgsqlCommand("DROP TABLE IF EXISTS testdrive.example", conn))
@@ -169,6 +168,15 @@ INSERT INTO testdrive.example (
169168
cmd.ExecuteNonQuery();
170169
}
171170

171+
}
172+
173+
public static async Task<DataTable> AllTypesNativeExample(NpgsqlConnection conn)
174+
{
175+
Console.WriteLine("Running AllTypesNativeExample");
176+
177+
// Provision data.
178+
await ProvisionAllTypes(conn);
179+
172180
// Query back data.
173181
await using (var cmd = new NpgsqlCommand("SELECT * FROM testdrive.example", conn))
174182
await using (var reader = cmd.ExecuteReader())
@@ -182,6 +190,69 @@ INSERT INTO testdrive.example (
182190

183191
}
184192

193+
public static async Task<JsonDocument> ObjectJsonDocumentExample(NpgsqlConnection conn)
194+
{
195+
Console.WriteLine("Running ObjectJsonDocumentExample");
196+
197+
// Provision data.
198+
await ProvisionAllTypes(conn);
199+
200+
// This test uses the central DDL, but a blank slate to focus on the test case at hand.
201+
await using (var cmd = new NpgsqlCommand("DELETE FROM testdrive.example", conn))
202+
{
203+
cmd.ExecuteNonQuery();
204+
}
205+
206+
await using (var cmd = new NpgsqlCommand("""
207+
INSERT INTO testdrive.example (
208+
"object"
209+
) VALUES (
210+
@object
211+
)
212+
""", conn))
213+
{
214+
cmd.Parameters.AddWithValue("object", NpgsqlDbType.Json, JsonDocument.Parse("""{"foo":"bar"}"""));
215+
cmd.ExecuteNonQuery();
216+
}
217+
218+
// Flush data.
219+
await using (var cmd = new NpgsqlCommand("REFRESH TABLE testdrive.example", conn))
220+
{
221+
cmd.ExecuteNonQuery();
222+
}
223+
224+
// Query back data.
225+
await using (var cmd = new NpgsqlCommand("SELECT * FROM testdrive.example", conn))
226+
await using (var reader = cmd.ExecuteReader())
227+
{
228+
reader.Read();
229+
var obj = reader.GetFieldValue<JsonDocument>("object");
230+
Console.WriteLine(obj);
231+
return obj;
232+
}
233+
}
234+
235+
public static async Task<List<JsonDocument>> ArrayJsonDocumentExample(NpgsqlConnection conn)
236+
{
237+
Console.WriteLine("Running ArrayJsonDocumentExample");
238+
239+
// Provision data.
240+
await ProvisionAllTypes(conn);
241+
242+
// Query back data.
243+
await using (var cmd = new NpgsqlCommand("SELECT * FROM testdrive.example", conn))
244+
await using (var reader = cmd.ExecuteReader())
245+
{
246+
reader.Read();
247+
// TODO: System.InvalidCastException: Reading as 'System.Text.Json.JsonDocument' or [1]
248+
// is not supported for fields having DataTypeName 'character varying[]'.
249+
// [1] `System.Collections.Generic.List`1[[System.Text.Json.JsonDocument]`
250+
var obj = reader.GetFieldValue<List<JsonDocument>>("array");
251+
Console.WriteLine(obj);
252+
return obj;
253+
}
254+
}
255+
185256
public static async Task ProvisionPoco(NpgsqlConnection conn)
186257
{
187258
/***

by-language/csharp-npgsql/tests/DemoProgramTest.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Data;
44
using System.Linq;
5+
using System.Text.Json;
56
using System.Threading.Tasks;
67
using Npgsql;
78
using Xunit;
@@ -168,6 +169,19 @@ public async Task TestContainerTypesExample()
168169

169170
}
170171

172+
[Fact]
173+
public async Task TestObjectJsonDocumentExample()
174+
{
175+
var conn = fixture.Db;
176+
177+
// Invoke database workload.
178+
var task = DatabaseWorkloadsMore.ObjectJsonDocumentExample(conn);
179+
var obj = await task.WaitAsync(TimeSpan.FromSeconds(0.5));
180+
181+
// Validate the outcome.
182+
Assert.Equal("""{"foo":"bar"}""", JsonSerializer.Serialize(obj));
183+
}
184+
171185
[Fact]
172186
public async Task TestObjectPocoExample()
173187
{

0 commit comments

Comments
 (0)