feat(MYSQL) Bun.SQL mysql support (#21968)

### What does this PR do?
Add MySQL support, Refactor will be in a followup PR
### How did you verify your code works?
A lot of tests

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: cirospaciari <6379399+cirospaciari@users.noreply.github.com>
This commit is contained in:
Ciro Spaciari
2025-08-21 15:28:15 -07:00
committed by GitHub
parent efdbe3b54f
commit ecbf103bf5
107 changed files with 10184 additions and 1387 deletions

View File

@@ -311,7 +311,7 @@ pub fn failWithJSValue(this: *PostgresSQLConnection, value: JSValue) void {
this.stopTimers();
if (this.status == .failed) return;
this.status = .failed;
this.setStatus(.failed);
this.ref();
defer this.deref();
@@ -584,7 +584,7 @@ comptime {
pub fn call(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!jsc.JSValue {
var vm = globalObject.bunVM();
const arguments = callframe.arguments_old(15).slice();
const arguments = callframe.arguments();
const hostname_str = try arguments[0].toBunString(globalObject);
defer hostname_str.deref();
const port = try arguments[1].coerce(i32, globalObject);
@@ -700,7 +700,7 @@ pub fn call(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JS
ptr.* = PostgresSQLConnection{
.globalObject = globalObject,
.vm = globalObject.bunVM(),
.vm = vm,
.database = database,
.user = username,
.password = password,
@@ -1157,7 +1157,9 @@ fn advance(this: *PostgresSQLConnection) void {
} else {
// deinit later
req.status = .fail;
offset += 1;
}
continue;
},
.prepared => {
@@ -1185,9 +1187,9 @@ fn advance(this: *PostgresSQLConnection) void {
} else {
// deinit later
req.status = .fail;
offset += 1;
}
debug("bind and execute failed: {s}", .{@errorName(err)});
continue;
};
@@ -1356,8 +1358,8 @@ pub fn on(this: *PostgresSQLConnection, comptime MessageType: @Type(.enum_litera
.globalObject = this.globalObject,
};
var stack_buf: [70]DataCell = undefined;
var cells: []DataCell = stack_buf[0..@min(statement.fields.len, jsc.JSObject.maxInlineCapacity())];
var stack_buf: [70]DataCell.SQLDataCell = undefined;
var cells: []DataCell.SQLDataCell = stack_buf[0..@min(statement.fields.len, jsc.JSObject.maxInlineCapacity())];
var free_cells = false;
defer {
for (cells[0..putter.count]) |*cell| {
@@ -1367,11 +1369,11 @@ pub fn on(this: *PostgresSQLConnection, comptime MessageType: @Type(.enum_litera
}
if (statement.fields.len >= jsc.JSObject.maxInlineCapacity()) {
cells = try bun.default_allocator.alloc(DataCell, statement.fields.len);
cells = try bun.default_allocator.alloc(DataCell.SQLDataCell, statement.fields.len);
free_cells = true;
}
// make sure all cells are reset if reader short breaks the fields will just be null with is better than undefined behavior
@memset(cells, DataCell{ .tag = .null, .value = .{ .null = 0 } });
@memset(cells, DataCell.SQLDataCell{ .tag = .null, .value = .{ .null = 0 } });
putter.list = cells;
if (request.flags.result_mode == .raw) {
@@ -1395,7 +1397,14 @@ pub fn on(this: *PostgresSQLConnection, comptime MessageType: @Type(.enum_litera
};
const pending_value = PostgresSQLQuery.js.pendingValueGetCached(thisValue) orelse .zero;
pending_value.ensureStillAlive();
const result = putter.toJS(this.globalObject, pending_value, structure, statement.fields_flags, request.flags.result_mode, cached_structure);
const result = putter.toJS(
this.globalObject,
pending_value,
structure,
statement.fields_flags,
request.flags.result_mode,
cached_structure,
);
if (pending_value == .zero) {
PostgresSQLQuery.js.pendingValueSetCached(thisValue, this.globalObject, result);
@@ -1814,7 +1823,8 @@ pub const fromJS = js.fromJS;
pub const fromJSDirect = js.fromJSDirect;
pub const toJS = js.toJS;
const PostgresCachedStructure = @import("./PostgresCachedStructure.zig");
const DataCell = @import("./DataCell.zig");
const PostgresCachedStructure = @import("../shared/CachedStructure.zig");
const PostgresRequest = @import("./PostgresRequest.zig");
const PostgresSQLQuery = @import("./PostgresSQLQuery.zig");
const PostgresSQLStatement = @import("./PostgresSQLStatement.zig");
@@ -1822,9 +1832,8 @@ const SocketMonitor = @import("./SocketMonitor.zig");
const protocol = @import("./PostgresProtocol.zig");
const std = @import("std");
const AuthenticationState = @import("./AuthenticationState.zig").AuthenticationState;
const ConnectionFlags = @import("./ConnectionFlags.zig").ConnectionFlags;
const Data = @import("./Data.zig").Data;
const DataCell = @import("./DataCell.zig").DataCell;
const ConnectionFlags = @import("../shared/ConnectionFlags.zig").ConnectionFlags;
const Data = @import("../shared/Data.zig").Data;
const SSLMode = @import("./SSLMode.zig").SSLMode;
const Status = @import("./Status.zig").Status;
const TLSStatus = @import("./TLSStatus.zig").TLSStatus;