Added type handler for jsonpath · npgsql/npgsql@048c460 · GitHub
Skip to content

Commit 048c460

Browse files
authored
Added type handler for jsonpath
Fixes #2504
1 parent fa9ef58 commit 048c460

3 files changed

Lines changed: 150 additions & 1 deletion

File tree

‎src/Npgsql/NpgsqlTypes/NpgsqlDbType.cs‎

Lines changed: 12 additions & 1 deletion
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using Npgsql.BackendMessages;
2+
using Npgsql.PostgresTypes;
3+
using Npgsql.TypeHandling;
4+
using Npgsql.TypeMapping;
5+
using NpgsqlTypes;
6+
using System;
7+
using System.IO;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
11+
namespace Npgsql.TypeHandlers
12+
{
13+
/// <summary>
14+
/// A factory for type handlers for the PostgreSQL jsonpath data type.
15+
/// </summary>
16+
/// <remarks>
17+
/// See https://www.postgresql.org/docs/current/datatype-json.html#DATATYPE-JSONPATH.
18+
///
19+
/// The type handler API allows customizing Npgsql's behavior in powerful ways. However, although it is public, it
20+
/// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases.
21+
/// Use it at your own risk.
22+
/// </remarks>
23+
[TypeMapping("jsonpath", NpgsqlDbType.JsonPath)]
24+
public class JsonPathHandlerFactory : NpgsqlTypeHandlerFactory<string>
25+
{
26+
/// <inheritdoc />
27+
public override NpgsqlTypeHandler<string> Create(PostgresType postgresType, NpgsqlConnection conn)
28+
=> new JsonPathHandler(postgresType, conn);
29+
}
30+
31+
/// <summary>
32+
/// A type handler for the PostgreSQL jsonpath data type.
33+
/// </summary>
34+
/// <remarks>
35+
/// See https://www.postgresql.org/docs/current/datatype-json.html#DATATYPE-JSONPATH.
36+
///
37+
/// The type handler API allows customizing Npgsql's behavior in powerful ways. However, although it is public, it
38+
/// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases.
39+
/// Use it at your own risk.
40+
/// </remarks>
41+
public class JsonPathHandler : NpgsqlTypeHandler<string>, ITextReaderHandler
42+
{
43+
readonly TextHandler _textHandler;
44+
45+
/// <summary>
46+
/// Prepended to the string in the wire encoding
47+
/// </summary>
48+
const byte JsonPathVersion = 1;
49+
50+
/// <inheritdoc />
51+
protected internal JsonPathHandler(PostgresType postgresType, NpgsqlConnection connection)
52+
: base(postgresType) => _textHandler = new TextHandler(postgresType, connection);
53+
54+
/// <inheritdoc />
55+
public override async ValueTask<string> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription = null, CancellationToken cancellationToken = default)
56+
{
57+
await buf.Ensure(1, async, cancellationToken);
58+
59+
var version = buf.ReadByte();
60+
if (version != JsonPathVersion)
61+
throw new NotSupportedException($"Don't know how to decode JSONPATH with wire format {version}, your connection is now broken");
62+
63+
return await _textHandler.Read(buf, len - 1, async, fieldDescription, cancellationToken);
64+
}
65+
66+
/// <inheritdoc />
67+
public override int ValidateAndGetLength(string value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter) =>
68+
1 + _textHandler.ValidateAndGetLength(value, ref lengthCache, parameter);
69+
70+
/// <inheritdoc />
71+
public override async Task Write(string value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
72+
{
73+
if (buf.WriteSpaceLeft < 1)
74+
await buf.Flush(async, cancellationToken);
75+
76+
buf.WriteByte(JsonPathVersion);
77+
78+
await _textHandler.Write(value, buf, lengthCache, parameter, async, cancellationToken);
79+
}
80+
81+
/// <inheritdoc />
82+
public TextReader GetTextReader(Stream stream)
83+
{
84+
var version = stream.ReadByte();
85+
if (version != JsonPathVersion)
86+
throw new NotSupportedException($"Don't know how to decode JSONPATH with wire format {version}, your connection is now broken");
87+
88+
return _textHandler.GetTextReader(stream);
89+
}
90+
}
91+
}
Lines changed: 47 additions & 0 deletions

0 commit comments

Comments
 (0)