mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
it compiled
This commit is contained in:
@@ -741,7 +741,7 @@ pub const MySQLConnection = struct {
|
||||
this.ref();
|
||||
const vm = this.globalObject.bunVM();
|
||||
defer {
|
||||
if (this.status == .connected and this.requests.items.len == 0 and this.write_buffer.remaining().len == 0) {
|
||||
if (this.status == .connected and this.requests.readableLength() == 0 and this.write_buffer.remaining().len == 0) {
|
||||
// Don't keep the process alive when there's nothing to do.
|
||||
this.poll_ref.unref(vm);
|
||||
} else if (this.status == .connected) {
|
||||
@@ -823,12 +823,12 @@ pub const MySQLConnection = struct {
|
||||
|
||||
// Read packet header
|
||||
const header = protocol.PacketHeader.decode(reader.peek()) orelse break;
|
||||
try reader.skip(protocol.PACKET_HEADER_SIZE);
|
||||
reader.skip(protocol.PACKET_HEADER_SIZE);
|
||||
|
||||
// Ensure we have the full packet
|
||||
reader.ensureCapacity(header.length) catch |err| {
|
||||
if (err == error.ShortRead) {
|
||||
try reader.skip(-@as(isize, @intCast(protocol.PACKET_HEADER_SIZE)));
|
||||
reader.skip(-@as(isize, @intCast(protocol.PACKET_HEADER_SIZE)));
|
||||
}
|
||||
|
||||
return err;
|
||||
@@ -848,7 +848,7 @@ pub const MySQLConnection = struct {
|
||||
},
|
||||
}
|
||||
|
||||
try reader.skip(header.length);
|
||||
reader.skip(header.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -908,7 +908,7 @@ pub const MySQLConnection = struct {
|
||||
|
||||
pub fn handleAuth(this: *MySQLConnection, comptime Context: type, reader: protocol.NewReader(Context)) !void {
|
||||
const first_byte = try reader.int(u8);
|
||||
try reader.skip(-1);
|
||||
reader.skip(-1);
|
||||
|
||||
switch (first_byte) {
|
||||
@intFromEnum(protocol.PacketType.OK) => {
|
||||
@@ -1017,7 +1017,7 @@ pub const MySQLConnection = struct {
|
||||
};
|
||||
}
|
||||
|
||||
try response.writeInternal(Writer, this.writer());
|
||||
try response.write(this.writer());
|
||||
this.flushData();
|
||||
}
|
||||
|
||||
@@ -1031,7 +1031,7 @@ pub const MySQLConnection = struct {
|
||||
.temporary = try auth_method.scramble(this.password, plugin_data, &scrambled_buf),
|
||||
};
|
||||
|
||||
try response.writeInternal(Writer, this.writer());
|
||||
try response.write(this.writer());
|
||||
this.flushData();
|
||||
}
|
||||
|
||||
@@ -1090,7 +1090,7 @@ pub const MySQLConnection = struct {
|
||||
return;
|
||||
}
|
||||
|
||||
this.connection.read_buffer.head += ucount;
|
||||
this.connection.read_buffer.head += @intCast(ucount);
|
||||
}
|
||||
|
||||
pub fn ensureCapacity(this: Reader, count: usize) bool {
|
||||
@@ -1132,7 +1132,7 @@ pub const MySQLConnection = struct {
|
||||
|
||||
pub fn handlePreparedStatement(this: *MySQLConnection, comptime Context: type, reader: protocol.NewReader(Context)) !void {
|
||||
const first_byte = try reader.int(u8);
|
||||
try reader.skip(-1);
|
||||
reader.skip(-1);
|
||||
|
||||
switch (first_byte) {
|
||||
@intFromEnum(protocol.PacketType.OK) => {
|
||||
@@ -1212,7 +1212,7 @@ pub const MySQLConnection = struct {
|
||||
|
||||
pub fn handleResultSet(this: *MySQLConnection, comptime Context: type, reader: protocol.NewReader(Context)) !void {
|
||||
const first_byte = try reader.int(u8);
|
||||
try reader.skip(-1);
|
||||
reader.skip(-1);
|
||||
|
||||
switch (first_byte) {
|
||||
@intFromEnum(protocol.PacketType.OK) => {
|
||||
@@ -1265,7 +1265,7 @@ pub const MySQLConnection = struct {
|
||||
// Start reading rows
|
||||
while (true) {
|
||||
const row_first_byte = try reader.byte();
|
||||
try reader.skip(-1);
|
||||
reader.skip(-1);
|
||||
|
||||
switch (row_first_byte) {
|
||||
@intFromEnum(protocol.PacketType.EOF) => {
|
||||
@@ -1300,12 +1300,12 @@ pub const MySQLConnection = struct {
|
||||
.binary = request.binary,
|
||||
};
|
||||
defer row.deinit(allocator);
|
||||
try row.decodeInternal(allocator, Context, reader);
|
||||
try row.decode(allocator, reader);
|
||||
|
||||
const pending_value = MySQLQuery.pendingValueGetCached(request.thisValue) orelse .zero;
|
||||
|
||||
// Process row data
|
||||
const row_value = row.toJS(request.statement.?.structure(request.thisValue, globalThis), pending_value, request.globalThis);
|
||||
const row_value = row.toJS(request.statement.?.structure(request.thisValue, globalThis), pending_value, globalThis);
|
||||
if (globalThis.hasException()) {
|
||||
request.onJSError(globalThis.tryTakeException().?, globalThis);
|
||||
return error.JSError;
|
||||
@@ -1329,7 +1329,7 @@ pub const MySQLConnection = struct {
|
||||
.statement_id = statement.statement_id,
|
||||
};
|
||||
|
||||
try close.writeInternal(Writer, this.writer());
|
||||
try close.write(this.writer());
|
||||
this.flushData();
|
||||
}
|
||||
|
||||
@@ -1338,7 +1338,7 @@ pub const MySQLConnection = struct {
|
||||
.statement_id = statement.statement_id,
|
||||
};
|
||||
|
||||
try reset.writeInternal(Writer, this.writer());
|
||||
try reset.write(this.writer());
|
||||
this.flushData();
|
||||
}
|
||||
};
|
||||
@@ -1346,7 +1346,7 @@ pub const MySQLConnection = struct {
|
||||
pub const MySQLStatement = struct {
|
||||
cached_structure: JSC.Strong = .{},
|
||||
ref_count: u32 = 1,
|
||||
statement_id: u32,
|
||||
statement_id: u32 = 0,
|
||||
params: []const types.FieldType = &[_]types.FieldType{},
|
||||
columns: []const protocol.ColumnDefinition41 = &[_]protocol.ColumnDefinition41{},
|
||||
signature: Signature,
|
||||
@@ -1508,7 +1508,7 @@ pub const MySQLQuery = struct {
|
||||
};
|
||||
defer execute.deinit();
|
||||
try this.bind(&execute, globalObject);
|
||||
try execute.writeInternal(writer);
|
||||
try execute.write(writer);
|
||||
this.status = .written;
|
||||
}
|
||||
|
||||
@@ -1535,7 +1535,7 @@ pub const MySQLQuery = struct {
|
||||
// TODO: unsigned
|
||||
false,
|
||||
);
|
||||
defer value.deinit();
|
||||
defer value.deinit(bun.default_allocator);
|
||||
params[i] = try value.toData(param);
|
||||
i += 1;
|
||||
}
|
||||
@@ -1674,6 +1674,14 @@ pub const MySQLQuery = struct {
|
||||
return .undefined;
|
||||
}
|
||||
|
||||
pub fn doCancel(this: *MySQLQuery, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSValue {
|
||||
_ = callframe;
|
||||
_ = globalObject;
|
||||
_ = this;
|
||||
|
||||
return .undefined;
|
||||
}
|
||||
|
||||
pub fn doRun(this: *MySQLQuery, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSValue {
|
||||
var arguments_ = callframe.arguments_old(2);
|
||||
const arguments = arguments_.slice();
|
||||
@@ -1739,6 +1747,7 @@ pub const MySQLQuery = struct {
|
||||
.signature = signature,
|
||||
.ref_count = 2,
|
||||
.status = .parsing,
|
||||
.statement_id = 0,
|
||||
};
|
||||
this.statement = stmt;
|
||||
entry.value_ptr.* = stmt;
|
||||
|
||||
@@ -45,7 +45,7 @@ pub const StackReader = struct {
|
||||
this.message_start.* = this.offset.*;
|
||||
}
|
||||
|
||||
pub fn ensureLength(this: @This(), length: usize) bool {
|
||||
pub fn ensureCapacity(this: @This(), length: usize) bool {
|
||||
return this.buffer.len >= (this.offset.* + length);
|
||||
}
|
||||
|
||||
@@ -83,10 +83,6 @@ pub const StackReader = struct {
|
||||
this.offset.* += ucount;
|
||||
}
|
||||
|
||||
pub fn ensureCapacity(this: StackReader, count: usize) bool {
|
||||
return this.buffer.len >= (this.offset.* + count);
|
||||
}
|
||||
|
||||
pub fn read(this: StackReader, count: usize) anyerror!Data {
|
||||
const offset = this.offset.*;
|
||||
if (!this.ensureCapacity(count)) {
|
||||
@@ -126,17 +122,19 @@ pub fn NewWriterWrap(
|
||||
const offsetFn = offsetFn_;
|
||||
pub const Ctx = Context;
|
||||
|
||||
pub const is_wrapped = true;
|
||||
|
||||
pub const WrappedWriter = @This();
|
||||
|
||||
pub inline fn write(this: @This(), data: []const u8) anyerror!void {
|
||||
pub fn write(this: @This(), data: []const u8) anyerror!void {
|
||||
try writeFn(this.wrapped, data);
|
||||
}
|
||||
|
||||
pub inline fn offset(this: @This()) usize {
|
||||
pub fn offset(this: @This()) usize {
|
||||
return offsetFn(this.wrapped);
|
||||
}
|
||||
|
||||
pub inline fn pwrite(this: @This(), data: []const u8, i: usize) anyerror!void {
|
||||
pub fn pwrite(this: @This(), data: []const u8, i: usize) anyerror!void {
|
||||
try pwriteFn(this.wrapped, data, i);
|
||||
}
|
||||
|
||||
@@ -195,24 +193,26 @@ pub fn NewReaderWrap(
|
||||
|
||||
pub const Ctx = Context;
|
||||
|
||||
pub inline fn markMessageStart(this: @This()) void {
|
||||
pub const is_wrapped = true;
|
||||
|
||||
pub fn markMessageStart(this: @This()) void {
|
||||
markMessageStartFn(this.wrapped);
|
||||
}
|
||||
|
||||
pub inline fn read(this: @This(), count: usize) anyerror!Data {
|
||||
return try readFn(this.wrapped, count);
|
||||
pub fn read(this: @This(), count: usize) anyerror!Data {
|
||||
return readFn(this.wrapped, count);
|
||||
}
|
||||
|
||||
pub fn skip(this: @This(), count: isize) anyerror!void {
|
||||
skipFn(this.wrapped, count);
|
||||
pub fn skip(this: @This(), count: anytype) void {
|
||||
skipFn(this.wrapped, @as(isize, @intCast(count)));
|
||||
}
|
||||
|
||||
pub fn peek(this: @This()) []const u8 {
|
||||
return peekFn(this.wrapped);
|
||||
}
|
||||
|
||||
pub inline fn readZ(this: @This()) anyerror!Data {
|
||||
return try readZFn(this.wrapped);
|
||||
pub fn readZ(this: @This()) anyerror!Data {
|
||||
return readZFn(this.wrapped);
|
||||
}
|
||||
|
||||
pub fn byte(this: @This()) !u8 {
|
||||
@@ -220,7 +220,7 @@ pub fn NewReaderWrap(
|
||||
return data.slice()[0];
|
||||
}
|
||||
|
||||
pub inline fn ensureCapacity(this: @This(), count: usize) anyerror!void {
|
||||
pub fn ensureCapacity(this: @This(), count: usize) anyerror!void {
|
||||
if (!ensureCapacityFn(this.wrapped, count)) {
|
||||
return error.ShortRead;
|
||||
}
|
||||
@@ -238,10 +238,18 @@ pub fn NewReaderWrap(
|
||||
}
|
||||
|
||||
pub fn NewReader(comptime Context: type) type {
|
||||
return NewReaderWrap(Context, Context.markMessageStart, Context.peek, Context.skip, Context.ensureLength, Context.read, Context.readZ);
|
||||
if (@hasDecl(Context, "is_wrapped")) {
|
||||
return Context;
|
||||
}
|
||||
|
||||
return NewReaderWrap(Context, Context.markMessageStart, Context.peek, Context.skip, Context.ensureCapacity, Context.read, Context.readZ);
|
||||
}
|
||||
|
||||
pub fn NewWriter(comptime Context: type) type {
|
||||
if (@hasDecl(Context, "is_wrapped")) {
|
||||
return Context;
|
||||
}
|
||||
|
||||
return NewWriterWrap(Context, Context.offset, Context.write, Context.pwrite);
|
||||
}
|
||||
|
||||
@@ -249,7 +257,20 @@ fn decoderWrap(comptime Container: type, comptime decodeFn: anytype) type {
|
||||
return struct {
|
||||
pub fn decode(this: *Container, context: anytype) anyerror!void {
|
||||
const Context = @TypeOf(context);
|
||||
try decodeFn(this, Context, NewReader(Context){ .wrapped = context });
|
||||
if (@hasDecl(Context, "is_wrapped")) {
|
||||
try decodeFn(this, Context, context);
|
||||
} else {
|
||||
try decodeFn(this, Context, .{ .wrapped = context });
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decodeAllocator(this: *Container, allocator: std.mem.Allocator, context: anytype) anyerror!void {
|
||||
const Context = @TypeOf(context);
|
||||
if (@hasDecl(Context, "is_wrapped")) {
|
||||
try decodeFn(this, allocator, Context, context);
|
||||
} else {
|
||||
try decodeFn(this, allocator, Context, .{ .wrapped = context });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -258,7 +279,11 @@ fn writeWrap(comptime Container: type, comptime writeFn: anytype) type {
|
||||
return struct {
|
||||
pub fn write(this: *Container, context: anytype) anyerror!void {
|
||||
const Context = @TypeOf(context);
|
||||
try writeFn(this, Context, NewWriter(Context){ .wrapped = context });
|
||||
if (@hasDecl(Context, "is_wrapped")) {
|
||||
try writeFn(this, Context, context);
|
||||
} else {
|
||||
try writeFn(this, Context, .{ .wrapped = context });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -413,7 +438,7 @@ pub const HandshakeV10 = struct {
|
||||
}
|
||||
|
||||
// Skip reserved bytes
|
||||
try reader.skip(10);
|
||||
reader.skip(10);
|
||||
|
||||
// Auth plugin data part 2
|
||||
const remaining_auth_len = @max(13, auth_plugin_data_len - 8);
|
||||
@@ -536,7 +561,7 @@ pub const OKPacket = struct {
|
||||
// Affected rows (length encoded integer)
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
this.affected_rows = result.value;
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
} else {
|
||||
return error.InvalidOKPacket;
|
||||
}
|
||||
@@ -544,7 +569,7 @@ pub const OKPacket = struct {
|
||||
// Last insert ID (length encoded integer)
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
this.last_insert_id = result.value;
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
} else {
|
||||
return error.InvalidOKPacket;
|
||||
}
|
||||
@@ -565,7 +590,7 @@ pub const OKPacket = struct {
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
const state_data = try reader.read(@intCast(result.value));
|
||||
this.session_state_changes = state_data;
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -602,7 +627,7 @@ pub const ErrorPacket = struct {
|
||||
this.sql_state = sql_state_data.slice()[0..5].*;
|
||||
} else {
|
||||
// No SQL state, rewind one byte
|
||||
try reader.skip(-1);
|
||||
reader.skip(-1);
|
||||
}
|
||||
|
||||
// Read the error message (rest of packet)
|
||||
@@ -848,32 +873,32 @@ pub const ColumnDefinition41 = struct {
|
||||
pub fn decodeInternal(this: *ColumnDefinition41, comptime Context: type, reader: NewReader(Context)) !void {
|
||||
// Length encoded strings
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
this.catalog = try reader.read(@intCast(result.value));
|
||||
} else return error.InvalidColumnDefinition;
|
||||
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
this.schema = try reader.read(@intCast(result.value));
|
||||
} else return error.InvalidColumnDefinition;
|
||||
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
this.table = try reader.read(@intCast(result.value));
|
||||
} else return error.InvalidColumnDefinition;
|
||||
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
this.org_table = try reader.read(@intCast(result.value));
|
||||
} else return error.InvalidColumnDefinition;
|
||||
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
this.name = try reader.read(@intCast(result.value));
|
||||
} else return error.InvalidColumnDefinition;
|
||||
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
this.org_name = try reader.read(@intCast(result.value));
|
||||
} else return error.InvalidColumnDefinition;
|
||||
|
||||
@@ -888,7 +913,7 @@ pub const ColumnDefinition41 = struct {
|
||||
this.decimals = try reader.int(u8);
|
||||
|
||||
// Skip filler
|
||||
try reader.skip(2);
|
||||
reader.skip(2);
|
||||
}
|
||||
|
||||
pub const decode = decoderWrap(ColumnDefinition41, decodeInternal).decode;
|
||||
@@ -898,7 +923,7 @@ fn decodeBinaryValue(field_type: types.FieldType, unsigned: bool, comptime Conte
|
||||
return switch (field_type) {
|
||||
.MYSQL_TYPE_TINY => blk: {
|
||||
const val = try reader.byte();
|
||||
break :blk Value{ .bool = val[0] != 0 };
|
||||
break :blk Value{ .bool = val != 0 };
|
||||
},
|
||||
.MYSQL_TYPE_SHORT => if (unsigned)
|
||||
Value{ .ushort = try reader.int(u16) }
|
||||
@@ -915,38 +940,42 @@ fn decodeBinaryValue(field_type: types.FieldType, unsigned: bool, comptime Conte
|
||||
.MYSQL_TYPE_FLOAT => Value{ .float = @bitCast(try reader.int(u32)) },
|
||||
.MYSQL_TYPE_DOUBLE => Value{ .double = @bitCast(try reader.int(u64)) },
|
||||
.MYSQL_TYPE_TIME => switch (try reader.byte()) {
|
||||
0 => Value{ .null = .{} },
|
||||
8, 12 => |l| Value{ .time = try Value.Time.fromBinary(reader.read(l)) },
|
||||
0 => Value{ .null = {} },
|
||||
8, 12 => |l| Value{ .time = try Value.Time.fromData(&try reader.read(l)) },
|
||||
else => return error.InvalidBinaryValue,
|
||||
},
|
||||
.MYSQL_TYPE_DATE => switch (try reader.byte()) {
|
||||
0 => Value{ .null = .{} },
|
||||
4 => Value{ .date = try Value.DateTime.fromBinary(reader.read(4)) },
|
||||
0 => Value{ .null = {} },
|
||||
4 => Value{ .date = try Value.DateTime.fromData(&try reader.read(4)) },
|
||||
else => error.InvalidBinaryValue,
|
||||
},
|
||||
.MYSQL_TYPE_DATETIME => switch (try reader.byte()) {
|
||||
0 => Value{ .null = .{} },
|
||||
11, 7, 4 => |l| Value{ .date = try Value.DateTime.fromBinary(reader.read(l)) },
|
||||
0 => Value{ .null = {} },
|
||||
11, 7, 4 => |l| Value{ .date = try Value.DateTime.fromData(&try reader.read(l)) },
|
||||
else => error.InvalidBinaryValue,
|
||||
},
|
||||
.MYSQL_TYPE_TIMESTAMP => switch (try reader.byte()) {
|
||||
0 => Value{ .null = .{} },
|
||||
4, 7 => |l| Value{ .timestamp = try Value.Timestamp.fromBinary(reader.read(l)) },
|
||||
0 => Value{ .null = {} },
|
||||
4, 7 => |l| Value{ .timestamp = try Value.Timestamp.fromData(&try reader.read(l)) },
|
||||
else => error.InvalidBinaryValue,
|
||||
},
|
||||
.MYSQL_TYPE_STRING, .MYSQL_TYPE_VARCHAR, .MYSQL_TYPE_VAR_STRING => blk: {
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
reader.skip(result.bytes_read);
|
||||
const val = try reader.read(@intCast(result.value));
|
||||
break :blk .{ .string_data = val };
|
||||
} else return error.InvalidBinaryValue;
|
||||
},
|
||||
.MYSQL_TYPE_TINY_BLOB,
|
||||
.MYSQL_TYPE_MEDIUM_BLOB,
|
||||
.MYSQL_TYPE_LONG_BLOB,
|
||||
.MYSQL_TYPE_BLOB,
|
||||
.MYSQL_TYPE_STRING,
|
||||
.MYSQL_TYPE_VARCHAR,
|
||||
.MYSQL_TYPE_VAR_STRING,
|
||||
.MYSQL_TYPE_JSON,
|
||||
=> blk: {
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
const val = try reader.read(@intCast(result.value));
|
||||
break :blk .{ .bytes = val };
|
||||
break :blk .{ .bytes_data = val };
|
||||
} else return error.InvalidBinaryValue;
|
||||
},
|
||||
else => return error.UnsupportedColumnType,
|
||||
@@ -955,14 +984,14 @@ fn decodeBinaryValue(field_type: types.FieldType, unsigned: bool, comptime Conte
|
||||
|
||||
// Result set header packet
|
||||
pub const ResultSetHeader = struct {
|
||||
field_count: u64,
|
||||
field_count: u64 = 0,
|
||||
extra: ?u64 = null,
|
||||
|
||||
pub fn decodeInternal(this: *ResultSetHeader, comptime Context: type, reader: NewReader(Context)) !void {
|
||||
// Field count (length encoded integer)
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
this.field_count = result.value;
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
} else {
|
||||
return error.InvalidResultSetHeader;
|
||||
}
|
||||
@@ -971,7 +1000,7 @@ pub const ResultSetHeader = struct {
|
||||
if (reader.peek().len > 0) {
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
this.extra = result.value;
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1268,14 +1297,14 @@ pub const Auth = struct {
|
||||
// Result set packet types
|
||||
pub const ResultSet = struct {
|
||||
pub const Header = struct {
|
||||
field_count: u64,
|
||||
field_count: u64 = 0,
|
||||
extra: ?u64 = null,
|
||||
|
||||
pub fn decodeInternal(this: *Header, comptime Context: type, reader: NewReader(Context)) !void {
|
||||
// Field count (length encoded integer)
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
this.field_count = result.value;
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
} else {
|
||||
return error.InvalidResultSetHeader;
|
||||
}
|
||||
@@ -1284,7 +1313,7 @@ pub const ResultSet = struct {
|
||||
if (reader.peek().len > 0) {
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
this.extra = result.value;
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1299,7 +1328,7 @@ pub const ResultSet = struct {
|
||||
|
||||
extern fn MySQL__toJSFromRow(*JSC.JSGlobalObject, JSC.JSValue, JSC.JSValue, *anyopaque, usize) JSC.JSValue;
|
||||
pub fn toJS(this: *Row, structure_value: JSValue, array_value: JSValue, globalObject: *JSC.JSGlobalObject) JSValue {
|
||||
return MySQL__toJSFromRow(globalObject, structure_value, array_value, this.values, this.columns.len);
|
||||
return MySQL__toJSFromRow(globalObject, structure_value, array_value, this.values.ptr, this.columns.len);
|
||||
}
|
||||
|
||||
pub fn deinit(this: *Row, allocator: std.mem.Allocator) void {
|
||||
@@ -1330,12 +1359,12 @@ pub const ResultSet = struct {
|
||||
|
||||
for (values) |*value| {
|
||||
if (decodeLengthInt(reader.peek())) |result| {
|
||||
try reader.skip(result.bytes_read);
|
||||
reader.skip(result.bytes_read);
|
||||
if (result.value == 0xfb) { // NULL value
|
||||
value.* = .{ .null = {} };
|
||||
} else {
|
||||
value.* = .{
|
||||
.string = try reader.read(@intCast(result.value)),
|
||||
.string_data = try reader.read(@intCast(result.value)),
|
||||
};
|
||||
}
|
||||
} else {
|
||||
@@ -1373,18 +1402,18 @@ pub const ResultSet = struct {
|
||||
const is_null = (null_bitmap.slice()[byte_pos] & (@as(u8, 1) << bit_pos)) != 0;
|
||||
|
||||
if (is_null) {
|
||||
value.* = .{ .empty = {} };
|
||||
value.* = .{ .null = {} };
|
||||
continue;
|
||||
}
|
||||
|
||||
const column = this.columns[i];
|
||||
value.* = try decodeBinaryValue(column.column_type, Context, reader);
|
||||
value.* = try decodeBinaryValue(column.column_type, column.flags.UNSIGNED, Context, reader);
|
||||
}
|
||||
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
pub const decode = decoderWrap(Row, decodeInternal).decode;
|
||||
pub const decode = decoderWrap(Row, decodeInternal).decodeAllocator;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1392,7 +1421,7 @@ pub const ResultSet = struct {
|
||||
pub const PreparedStatement = struct {
|
||||
pub const Prepare = struct {
|
||||
command: CommandType = .COM_STMT_PREPARE,
|
||||
query: Data,
|
||||
query: Data = .{ .empty = {} },
|
||||
|
||||
pub fn deinit(this: *Prepare) void {
|
||||
this.query.deinit();
|
||||
@@ -1441,7 +1470,7 @@ pub const PreparedStatement = struct {
|
||||
/// Whether to send parameter types. Set to true for first execution, false for subsequent executions
|
||||
new_params_bind_flag: bool = true,
|
||||
/// Parameter values to bind to the prepared statement
|
||||
params: []const Data = &[_]Data{},
|
||||
params: []Data = &[_]Data{},
|
||||
/// Types of each parameter in the prepared statement
|
||||
param_types: []const types.FieldType = &[_]types.FieldType{},
|
||||
|
||||
@@ -1504,7 +1533,7 @@ pub const PreparedStatement = struct {
|
||||
|
||||
pub const Close = struct {
|
||||
command: CommandType = .COM_STMT_CLOSE,
|
||||
statement_id: u32,
|
||||
statement_id: u32 = 0,
|
||||
|
||||
pub fn writeInternal(this: *const Close, comptime Context: type, writer: NewWriter(Context)) !void {
|
||||
try writer.int1(@intFromEnum(this.command));
|
||||
@@ -1516,7 +1545,7 @@ pub const PreparedStatement = struct {
|
||||
|
||||
pub const Reset = struct {
|
||||
command: CommandType = .COM_STMT_RESET,
|
||||
statement_id: u32,
|
||||
statement_id: u32 = 0,
|
||||
|
||||
pub fn writeInternal(this: *const Reset, comptime Context: type, writer: NewWriter(Context)) !void {
|
||||
try writer.int1(@intFromEnum(this.command));
|
||||
|
||||
@@ -183,7 +183,9 @@ pub const Value = union(enum) {
|
||||
double: f64,
|
||||
|
||||
string: JSC.ZigString.Slice,
|
||||
string_data: Data,
|
||||
bytes: JSC.ZigString.Slice,
|
||||
bytes_data: Data,
|
||||
date: DateTime,
|
||||
timestamp: Timestamp,
|
||||
time: Time,
|
||||
@@ -191,7 +193,8 @@ pub const Value = union(enum) {
|
||||
|
||||
pub fn deinit(this: *Value, allocator: std.mem.Allocator) void {
|
||||
switch (this.*) {
|
||||
inline .string, .bytes => |*slice| slice.deinit(allocator),
|
||||
inline .string, .bytes => |*slice| slice.deinit(),
|
||||
inline .string_data, .bytes_data => |*data| data.deinit(),
|
||||
.decimal => |*decimal| decimal.deinit(allocator),
|
||||
else => {},
|
||||
}
|
||||
@@ -219,6 +222,7 @@ pub const Value = union(enum) {
|
||||
stream.pos = d.toBinary(field_type, &buffer);
|
||||
},
|
||||
.decimal => |dec| return try dec.toBinary(field_type),
|
||||
.string_data, .bytes_data => |data| return data,
|
||||
.string, .bytes => |slice| return if (slice.len > 0)
|
||||
Data{ .temporary = slice.slice() }
|
||||
else
|
||||
@@ -285,6 +289,10 @@ pub const Value = union(enum) {
|
||||
seconds: u32,
|
||||
microseconds: u24,
|
||||
|
||||
pub fn fromData(data: *const Data) !Timestamp {
|
||||
return fromBinary(data.slice());
|
||||
}
|
||||
|
||||
pub fn fromBinary(val: []const u8) Timestamp {
|
||||
return .{
|
||||
// Bytes 0-3: [seconds] (32-bit little-endian unsigned integer)
|
||||
@@ -348,6 +356,10 @@ pub const Value = union(enum) {
|
||||
second: u8 = 0,
|
||||
microsecond: u32 = 0,
|
||||
|
||||
pub fn fromData(data: *const Data) !DateTime {
|
||||
return fromBinary(data.slice());
|
||||
}
|
||||
|
||||
pub fn fromBinaryDate(val: []const u8) DateTime {
|
||||
return .{
|
||||
.year = std.mem.readInt(u16, val[0..2], .little),
|
||||
@@ -532,6 +544,10 @@ pub const Value = union(enum) {
|
||||
return total_ms;
|
||||
}
|
||||
|
||||
pub fn fromData(data: *const Data) !Time {
|
||||
return fromBinary(data.slice());
|
||||
}
|
||||
|
||||
pub fn fromBinary(val: []const u8) Time {
|
||||
if (val.len == 0) {
|
||||
return Time{};
|
||||
@@ -542,14 +558,14 @@ pub const Value = union(enum) {
|
||||
|
||||
if (length >= 8) {
|
||||
time.negative = val[1] != 0;
|
||||
time.days = std.mem.readInt(.little, val[2..6]);
|
||||
time.days = std.mem.readInt(u32, val[2..6], .little);
|
||||
time.hours = val[6];
|
||||
time.minutes = val[7];
|
||||
time.seconds = val[8];
|
||||
}
|
||||
|
||||
if (length > 8) {
|
||||
time.microseconds = std.mem.readInt(.little, val[9..13]);
|
||||
time.microseconds = std.mem.readInt(u32, val[9..13], .little);
|
||||
}
|
||||
|
||||
return time;
|
||||
@@ -584,7 +600,7 @@ pub const Value = union(enum) {
|
||||
return 9;
|
||||
} else {
|
||||
buffer[0] = 12; // length
|
||||
std.mem.writeInt(u32, buffer[9..], this.microseconds, .little);
|
||||
std.mem.writeInt(u32, buffer[9..][0..4], this.microseconds, .little);
|
||||
return 12;
|
||||
}
|
||||
},
|
||||
@@ -629,17 +645,27 @@ pub const Value = union(enum) {
|
||||
_ = field_type; // autofix
|
||||
bun.todoPanic(@src(), "Decimal.toBinary not implemented", .{});
|
||||
}
|
||||
|
||||
pub fn fromData(data: *const Data) !Decimal {
|
||||
return fromBinary(data.slice());
|
||||
}
|
||||
|
||||
pub fn fromBinary(val: []const u8) Decimal {
|
||||
_ = val; // autofix
|
||||
// TODO: handle overflow
|
||||
bun.todoPanic(@src(), "Decimal.fromBinary not implemented", .{});
|
||||
}
|
||||
};
|
||||
|
||||
pub fn toJS(this: *const Value, globalObject: *JSC.JSGlobalObject) JSValue {
|
||||
return switch (this.*) {
|
||||
.null => JSValue.jsNull(),
|
||||
.bool => |b| JSValue.jsBoolean(b),
|
||||
.string => |*str| {
|
||||
inline .string, .string_data => |*str| {
|
||||
var out = bun.String.createUTF8(str.slice());
|
||||
return out.transferToJS(globalObject);
|
||||
},
|
||||
.bytes => JSC.ArrayBuffer.createBuffer(globalObject, this.bytes.slice()),
|
||||
inline .bytes, .bytes_data => |*data| JSC.ArrayBuffer.createBuffer(globalObject, data.slice()),
|
||||
inline .long, .int, .float, .double, .short, .ushort, .uint, .ulong => |t| JSValue.jsNumber(t),
|
||||
inline .timestamp, .date, .time, .decimal => |*d| d.toJS(globalObject),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user