mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 10:58:56 +00:00
refactor(MySQL) (#22619)
### What does this PR do? ### How did you verify your code works? --------- Co-authored-by: Jarred Sumner <jarred@jarredsumner.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -29,7 +29,7 @@ pub const CommandTag = union(enum) {
|
||||
|
||||
other: []const u8,
|
||||
|
||||
pub fn toJSTag(this: CommandTag, globalObject: *jsc.JSGlobalObject) JSValue {
|
||||
pub fn toJSTag(this: CommandTag, globalObject: *jsc.JSGlobalObject) bun.JSError!jsc.JSValue {
|
||||
return switch (this) {
|
||||
.INSERT => JSValue.jsNumber(1),
|
||||
.DELETE => JSValue.jsNumber(2),
|
||||
@@ -39,7 +39,7 @@ pub const CommandTag = union(enum) {
|
||||
.MOVE => JSValue.jsNumber(6),
|
||||
.FETCH => JSValue.jsNumber(7),
|
||||
.COPY => JSValue.jsNumber(8),
|
||||
.other => |tag| jsc.ZigString.init(tag).toJS(globalObject),
|
||||
.other => |tag| bun.String.createUTF8ForJS(globalObject, tag),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ pub fn onConnectionTimeout(this: *PostgresSQLConnection) bun.api.Timer.EventLoop
|
||||
this.failFmt("ERR_POSTGRES_CONNECTION_TIMEOUT", "Connection timeout after {}", .{bun.fmt.fmtDurationOneDecimal(@as(u64, this.connection_timeout_ms) *| std.time.ns_per_ms)});
|
||||
},
|
||||
.sent_startup_message => {
|
||||
this.failFmt("ERR_POSTGRES_CONNECTION_TIMEOUT", "Connection timed out after {} (sent startup message, but never received response)", .{bun.fmt.fmtDurationOneDecimal(@as(u64, this.connection_timeout_ms) *| std.time.ns_per_ms)});
|
||||
this.failFmt("ERR_POSTGRES_CONNECTION_TIMEOUT", "Connection timeout after {} (sent startup message, but never received response)", .{bun.fmt.fmtDurationOneDecimal(@as(u64, this.connection_timeout_ms) *| std.time.ns_per_ms)});
|
||||
},
|
||||
}
|
||||
return .disarm;
|
||||
@@ -311,7 +311,7 @@ pub fn failWithJSValue(this: *PostgresSQLConnection, value: JSValue) void {
|
||||
this.stopTimers();
|
||||
if (this.status == .failed) return;
|
||||
|
||||
this.setStatus(.failed);
|
||||
this.status = .failed;
|
||||
|
||||
this.ref();
|
||||
defer this.deref();
|
||||
@@ -321,12 +321,17 @@ pub fn failWithJSValue(this: *PostgresSQLConnection, value: JSValue) void {
|
||||
|
||||
const loop = this.vm.eventLoop();
|
||||
loop.enter();
|
||||
var js_error = value.toError() orelse value;
|
||||
if (js_error == .zero) {
|
||||
js_error = postgresErrorToJS(this.globalObject, "Connection closed", error.ConnectionClosed);
|
||||
}
|
||||
js_error.ensureStillAlive();
|
||||
defer loop.exit();
|
||||
_ = on_close.call(
|
||||
this.globalObject,
|
||||
this.js_value,
|
||||
.js_undefined,
|
||||
&[_]JSValue{
|
||||
value.toError() orelse value,
|
||||
js_error,
|
||||
this.getQueriesArray(),
|
||||
},
|
||||
) catch |e| this.globalObject.reportActiveExceptionAsUnhandled(e);
|
||||
@@ -1350,6 +1355,9 @@ fn advance(this: *PostgresSQLConnection) void {
|
||||
}
|
||||
|
||||
pub fn getQueriesArray(this: *const PostgresSQLConnection) JSValue {
|
||||
if (this.js_value.isEmptyOrUndefinedOrNull()) {
|
||||
return .js_undefined;
|
||||
}
|
||||
return js.queriesGetCached(this.js_value) orelse .js_undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const PostgresSQLQuery = @This();
|
||||
const RefCount = bun.ptr.ThreadSafeRefCount(@This(), "ref_count", deinit, .{});
|
||||
const RefCount = bun.ptr.RefCount(@This(), "ref_count", deinit, .{});
|
||||
statement: ?*PostgresSQLStatement = null,
|
||||
query: bun.String = bun.String.empty,
|
||||
cursor_name: bun.String = bun.String.empty,
|
||||
@@ -23,9 +23,9 @@ flags: packed struct(u8) {
|
||||
pub const ref = RefCount.ref;
|
||||
pub const deref = RefCount.deref;
|
||||
|
||||
pub fn getTarget(this: *PostgresSQLQuery, globalObject: *jsc.JSGlobalObject, clean_target: bool) jsc.JSValue {
|
||||
const thisValue = this.thisValue.tryGet() orelse return .zero;
|
||||
const target = js.targetGetCached(thisValue) orelse return .zero;
|
||||
pub fn getTarget(this: *PostgresSQLQuery, globalObject: *jsc.JSGlobalObject, clean_target: bool) ?jsc.JSValue {
|
||||
const thisValue = this.thisValue.tryGet() orelse return null;
|
||||
const target = js.targetGetCached(thisValue) orelse return null;
|
||||
if (clean_target) {
|
||||
js.targetSetCached(thisValue, globalObject, .zero);
|
||||
}
|
||||
@@ -51,12 +51,7 @@ pub const Status = enum(u8) {
|
||||
}
|
||||
};
|
||||
|
||||
pub fn hasPendingActivity(this: *@This()) bool {
|
||||
return this.ref_count.get() > 1;
|
||||
}
|
||||
|
||||
pub fn deinit(this: *@This()) void {
|
||||
this.thisValue.deinit();
|
||||
if (this.statement) |statement| {
|
||||
statement.deref();
|
||||
}
|
||||
@@ -67,11 +62,7 @@ pub fn deinit(this: *@This()) void {
|
||||
|
||||
pub fn finalize(this: *@This()) void {
|
||||
debug("PostgresSQLQuery finalize", .{});
|
||||
if (this.thisValue == .weak) {
|
||||
// clean up if is a weak reference, if is a strong reference we need to wait until the query is done
|
||||
// if we are a strong reference, here is probably a bug because GC'd should not happen
|
||||
this.thisValue.weak = .zero;
|
||||
}
|
||||
this.thisValue.finalize();
|
||||
this.deref();
|
||||
}
|
||||
|
||||
@@ -84,12 +75,9 @@ pub fn onWriteFail(
|
||||
this.ref();
|
||||
defer this.deref();
|
||||
this.status = .fail;
|
||||
const thisValue = this.thisValue.get();
|
||||
defer this.thisValue.deinit();
|
||||
const targetValue = this.getTarget(globalObject, true);
|
||||
if (thisValue == .zero or targetValue == .zero) {
|
||||
return;
|
||||
}
|
||||
const thisValue = this.thisValue.tryGet() orelse return;
|
||||
defer this.thisValue.downgrade();
|
||||
const targetValue = this.getTarget(globalObject, true) orelse return;
|
||||
|
||||
const vm = jsc.VirtualMachine.get();
|
||||
const function = vm.rareData().postgresql_context.onQueryRejectFn.get().?;
|
||||
@@ -105,12 +93,9 @@ pub fn onJSError(this: *@This(), err: jsc.JSValue, globalObject: *jsc.JSGlobalOb
|
||||
this.ref();
|
||||
defer this.deref();
|
||||
this.status = .fail;
|
||||
const thisValue = this.thisValue.get();
|
||||
defer this.thisValue.deinit();
|
||||
const targetValue = this.getTarget(globalObject, true);
|
||||
if (thisValue == .zero or targetValue == .zero) {
|
||||
return;
|
||||
}
|
||||
const thisValue = this.thisValue.tryGet() orelse return;
|
||||
defer this.thisValue.downgrade();
|
||||
const targetValue = this.getTarget(globalObject, true) orelse return;
|
||||
|
||||
var vm = jsc.VirtualMachine.get();
|
||||
const function = vm.rareData().postgresql_context.onQueryRejectFn.get().?;
|
||||
@@ -145,31 +130,30 @@ fn consumePendingValue(thisValue: jsc.JSValue, globalObject: *jsc.JSGlobalObject
|
||||
pub fn onResult(this: *@This(), command_tag_str: []const u8, globalObject: *jsc.JSGlobalObject, connection: jsc.JSValue, is_last: bool) void {
|
||||
this.ref();
|
||||
defer this.deref();
|
||||
|
||||
const thisValue = this.thisValue.get();
|
||||
const targetValue = this.getTarget(globalObject, is_last);
|
||||
if (is_last) {
|
||||
this.status = .success;
|
||||
} else {
|
||||
this.status = .partial_response;
|
||||
}
|
||||
const tag = CommandTag.init(command_tag_str);
|
||||
const js_tag = tag.toJSTag(globalObject) catch |e| return this.onJSError(globalObject.takeException(e), globalObject);
|
||||
js_tag.ensureStillAlive();
|
||||
|
||||
const thisValue = this.thisValue.tryGet() orelse return;
|
||||
defer if (is_last) {
|
||||
allowGC(thisValue, globalObject);
|
||||
this.thisValue.deinit();
|
||||
this.thisValue.downgrade();
|
||||
};
|
||||
if (thisValue == .zero or targetValue == .zero) {
|
||||
return;
|
||||
}
|
||||
const targetValue = this.getTarget(globalObject, is_last) orelse return;
|
||||
|
||||
const vm = jsc.VirtualMachine.get();
|
||||
const function = vm.rareData().postgresql_context.onQueryResolveFn.get().?;
|
||||
const event_loop = vm.eventLoop();
|
||||
const tag = CommandTag.init(command_tag_str);
|
||||
|
||||
event_loop.runCallback(function, globalObject, thisValue, &.{
|
||||
targetValue,
|
||||
consumePendingValue(thisValue, globalObject) orelse .js_undefined,
|
||||
tag.toJSTag(globalObject),
|
||||
js_tag,
|
||||
tag.toJSNumber(),
|
||||
if (connection == .zero) .js_undefined else PostgresSQLConnection.js.queriesGetCached(connection) orelse .js_undefined,
|
||||
JSValue.jsBoolean(is_last),
|
||||
@@ -257,13 +241,13 @@ pub fn doDone(this: *@This(), globalObject: *jsc.JSGlobalObject, _: *jsc.CallFra
|
||||
this.flags.is_done = true;
|
||||
return .js_undefined;
|
||||
}
|
||||
pub fn setPendingValue(this: *PostgresSQLQuery, globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {
|
||||
pub fn setPendingValueFromJS(_: *PostgresSQLQuery, globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {
|
||||
const result = callframe.argument(0);
|
||||
const thisValue = this.thisValue.tryGet() orelse return .js_undefined;
|
||||
const thisValue = callframe.this();
|
||||
js.pendingValueSetCached(thisValue, globalObject, result);
|
||||
return .js_undefined;
|
||||
}
|
||||
pub fn setMode(this: *PostgresSQLQuery, globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {
|
||||
pub fn setModeFromJS(this: *PostgresSQLQuery, globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {
|
||||
const js_mode = callframe.argument(0);
|
||||
if (js_mode.isEmptyOrUndefinedOrNull() or !js_mode.isNumber()) {
|
||||
return globalObject.throwInvalidArgumentType("setMode", "mode", "Number");
|
||||
|
||||
Reference in New Issue
Block a user