aboutsummaryrefslogtreecommitdiff
path: root/src/error_response.zig
diff options
context:
space:
mode:
authorMartin Ashby <martin@ashbysoft.com>2023-09-26 06:51:06 +0100
committerMartin Ashby <martin@ashbysoft.com>2023-09-26 06:51:06 +0100
commit183d60a6e87230cc767c56900b94c9c694596de1 (patch)
treec08b473a293dc465989a09c5d681191898cf2c2f /src/error_response.zig
parent02f9e99bfccad8837d327880f756ec7bab711783 (diff)
downloadpgz-183d60a6e87230cc767c56900b94c9c694596de1.tar.gz
pgz-183d60a6e87230cc767c56900b94c9c694596de1.tar.bz2
pgz-183d60a6e87230cc767c56900b94c9c694596de1.tar.xz
pgz-183d60a6e87230cc767c56900b94c9c694596de1.zip
Move protocol definitions into a subfolder
Diffstat (limited to 'src/error_response.zig')
-rw-r--r--src/error_response.zig170
1 files changed, 0 insertions, 170 deletions
diff --git a/src/error_response.zig b/src/error_response.zig
deleted file mode 100644
index 3b66c15..0000000
--- a/src/error_response.zig
+++ /dev/null
@@ -1,170 +0,0 @@
-const std = @import("std");
-const HMByteString = std.AutoHashMap(u8, []const u8);
-const ByteArrayList = std.ArrayList(u8);
-const ProtocolError = @import("main.zig").ProtocolError;
-
-const ErrorResponse = @This();
-pub const Tag: u8 = 'E';
-
-buf: ?[]const u8 = null, // owned
-severity: []const u8,
-severity_unlocalized: ?[]const u8 = null,
-code: []const u8,
-message: []const u8,
-detail: ?[]const u8 = null,
-hint: ?[]const u8 = null,
-position: ?u32 = null,
-internal_position: ?u32 = null,
-internal_query: ?[]const u8 = null,
-where: ?[]const u8 = null,
-schema_name: ?[]const u8 = null,
-table_name: ?[]const u8 = null,
-column_name: ?[]const u8 = null,
-data_type_name: ?[]const u8 = null,
-constraint_name: ?[]const u8 = null,
-file_name: ?[]const u8 = null,
-line: ?u32 = null,
-routine: ?[]const u8 = null,
-unknown_fields: HMByteString,
-
-pub fn read(allocator: std.mem.Allocator, b: []const u8) !ErrorResponse {
- var res: ErrorResponse = undefined;
- res.unknown_fields = HMByteString.init(allocator);
- res.buf = try allocator.dupe(u8, b);
- errdefer allocator.free(res.buf.?);
- var it = std.mem.splitScalar(u8, res.buf.?, 0);
- var setSev = false; var setCode = false; var setMsg = false;
- while (it.next()) |next| {
- if (next.len < 1) break;
- switch (next[0]) {
- 0 => break,
- 'S' => {
- res.severity = next[1..];
- setSev = true;
- },
- 'V' => {
- res.severity_unlocalized = next[1..];
- },
- 'C' => {
- res.code = next[1..];
- setCode = true;
- },
- 'M' => {
- res.message = next[1..];
- setMsg = true;
- },
- 'D' => {
- res.detail = next[1..];
- },
- 'H' => {
- res.hint = next[1..];
- },
- 'P' => {
- res.position = try std.fmt.parseInt(u32, next[1..], 10);
- },
- 'p' => {
- res.internal_position = try std.fmt.parseInt(u32, next[1..], 10);
- },
- 'q' => {
- res.internal_query = next[1..];
- },
- 'W' => {
- res.where = next[1..];
- },
- 's' => {
- res.schema_name = next[1..];
- },
- 't' => {
- res.table_name = next[1..];
- },
- 'c' => {
- res.column_name = next[1..];
- },
- 'd' => {
- res.data_type_name = next[1..];
- },
- 'n' => {
- res.constraint_name = next[1..];
- },
- 'F' => {
- res.file_name = next[1..];
- },
- 'L' => {
- res.line = try std.fmt.parseInt(u32, next[1..], 10);
- },
- 'R' => {
- res.routine = next[1..];
- },
- else => {
- try res.unknown_fields.put(next[0], next[1..]);
- }
- }
- }
- if (!(setSev and setCode and setMsg)) return ProtocolError.MissingField;
- return res;
-}
-pub fn write(self: ErrorResponse, allocator: std.mem.Allocator, stream_writer: anytype) !void {
- try stream_writer.writeByte(Tag);
- var al = ByteArrayList.init(allocator);
- defer al.deinit();
- var cw = std.io.countingWriter(al.writer());
- var writer = cw.writer();
- try writer.writeIntBig(u32, 0); // Length placeholder.
-
- try write_field_nt('S', self, "severity", writer);
- if (self.severity_unlocalized) |severity_unlocalized| {
- try write_nt('V', severity_unlocalized, writer);
- }
- try write_field_nt('C', self, "code", writer);
- try write_field_nt('M', self, "message", writer);
- // TODO rest of the fields
-
- // replace the length and write it to the actual stream
- std.mem.writeIntBig(u32, al.items[0..4], @as(u32, @intCast(cw.bytes_written)));
- try stream_writer.writeAll(al.items);
-}
-fn write_field_nt(comptime tag: u8, self: ErrorResponse, comptime field: []const u8, writer: anytype) !void {
- try write_nt(tag, @field(self, field), writer);
-}
-fn write_nt(comptime tag: u8, value: []const u8, writer: anytype) !void {
- try writer.writeByte(tag);
- try writer.writeAll(value);
- try writer.writeByte(0);
-}
-
-pub fn deinit(self: *ErrorResponse, allocator: std.mem.Allocator) void {
- self.unknown_fields.deinit();
- if (self.buf != null) allocator.free(self.buf.?);
-}
-
-test "round trip" {
- const allocator = std.testing.allocator;
- var sm = ErrorResponse{
- .severity = "foo",
- .severity_unlocalized = "foo_unlocal",
- .code = "bar",
- .message = "baz",
- .unknown_fields = HMByteString.init(allocator),
- };
- defer sm.deinit(allocator);
-
- var bal = ByteArrayList.init(allocator);
- defer bal.deinit();
- try sm.write(allocator, bal.writer());
-
- var fbs = std.io.fixedBufferStream(bal.items);
- var reader = fbs.reader();
- const tag = try reader.readByte();
- try std.testing.expectEqual(Tag, tag);
- const len = try reader.readIntBig(u32);
- const buf = try allocator.alloc(u8, len - 4);
- defer allocator.free(buf);
- try reader.readNoEof(buf);
- var sm2 = try ErrorResponse.read(allocator, buf);
- defer sm2.deinit(allocator);
-
- try std.testing.expectEqualStrings("foo", sm2.severity);
- try std.testing.expectEqualStrings("foo_unlocal", sm2.severity_unlocalized.?);
- try std.testing.expectEqualStrings("bar", sm2.code);
- try std.testing.expectEqualStrings("baz", sm2.message);
-}