Skip to content

Commit 07a3802

Browse files
committed
gemini review comments fix
1 parent 76fda58 commit 07a3802

6 files changed

Lines changed: 67 additions & 22 deletions

File tree

spannerlib/wrappers/spannerlib-node/scripts/fix-extensions.cjs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@ function traverseDir(dir) {
2424
traverseDir(fullPath);
2525
} else if (fullPath.endsWith('.cjs')) {
2626
let content = fs.readFileSync(fullPath, 'utf8');
27-
// Replace require('./... .js') with require('./... .cjs')
28-
content = content.replace(/require\(['"](\.\/[^'"]+)\.js['"]\)/g, "require('$1.cjs')");
29-
// Also handle ../
30-
content = content.replace(/require\(['"](\.\.\/[^'"]+)\.js['"]\)/g, "require('$1.cjs')");
27+
// Replace require paths starting with . / or .. / and ending with .js
28+
content = content.replace(/require\(['"]((\.|\.\.)\/[^'"]+)\.js['"]\)/g, "require('$1.cjs')");
3129
// Fix import.meta.url syntax error in CommonJS
3230
content = content.replace(/import\.meta\.url/g, '""');
3331
fs.writeFileSync(fullPath, content);

spannerlib/wrappers/spannerlib-node/src/cpp/addon.cc

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,47 @@ class MetadataWorker : public Napi::AsyncWorker {
299299
Metadata_return result_;
300300
};
301301

302+
//
303+
// Worker 8: CloseRows asynchronously
304+
//
305+
class CloseRowsWorker : public Napi::AsyncWorker {
306+
public:
307+
CloseRowsWorker(Napi::Function& callback, int64_t poolId, int64_t connId, int64_t rowsId)
308+
: AsyncWorker(callback), poolId_(poolId), connId_(connId), rowsId_(rowsId), result_({0, 0, 0, 0, nullptr}) {}
309+
310+
void Execute() override {
311+
result_ = ::CloseRows(poolId_, connId_, rowsId_);
312+
}
313+
314+
void OnOK() override {
315+
Napi::Env env = Env();
316+
Napi::Object obj = Napi::Object::New(env);
317+
obj.Set("r0", Napi::Number::New(env, result_.r0));
318+
obj.Set("r1", Napi::Number::New(env, result_.r1));
319+
obj.Set("r2", Napi::Number::New(env, result_.r2));
320+
obj.Set("r3", Napi::Number::New(env, result_.r3));
321+
if (result_.r4 != nullptr && result_.r3 > 0) {
322+
obj.Set("r4", Napi::Buffer<uint8_t>::Copy(env, (uint8_t*)result_.r4, result_.r3));
323+
} else {
324+
obj.Set("r4", env.Null());
325+
}
326+
// Release the pinner ID of the response message to prevent native leak!
327+
if (result_.r0 > 0) {
328+
::Release(result_.r0);
329+
}
330+
Callback().Call({env.Null(), obj});
331+
}
332+
private:
333+
int64_t poolId_, connId_, rowsId_;
334+
CloseRows_return result_;
335+
};
336+
302337
Napi::Value MetadataWrapper(const Napi::CallbackInfo& info) {
303338
Napi::Env env = info.Env();
339+
if (info.Length() < 4) {
340+
Napi::Error::New(env, "MetadataWrapper requires 4 arguments").ThrowAsJavaScriptException();
341+
return env.Null();
342+
}
304343
int64_t pid = info[0].As<Napi::Number>().Int64Value();
305344
int64_t cid = info[1].As<Napi::Number>().Int64Value();
306345
int64_t rid = info[2].As<Napi::Number>().Int64Value();
@@ -323,21 +362,17 @@ Napi::Value NativeRelease(const Napi::CallbackInfo& info) {
323362
// CloseRows dummy/missing implementation for POC length if needed, or we just rely on GC.
324363
Napi::Value CloseRowsWrapper(const Napi::CallbackInfo& info) {
325364
Napi::Env env = info.Env();
326-
if (info.Length() < 3) return env.Null();
365+
if (info.Length() < 4) {
366+
Napi::Error::New(env, "CloseRowsWrapper requires 4 arguments").ThrowAsJavaScriptException();
367+
return env.Null();
368+
}
327369
int64_t pid = info[0].As<Napi::Number>().Int64Value();
328370
int64_t cid = info[1].As<Napi::Number>().Int64Value();
329371
int64_t rid = info[2].As<Napi::Number>().Int64Value();
372+
Napi::Function cb = info[3].As<Napi::Function>();
330373

331-
// N-API sync close implementation
332-
CloseRows(pid, cid, rid);
333-
334-
// invokeAsync appends a callback at the end of properties
335-
if (info.Length() >= 4 && info[3].IsFunction()) {
336-
Napi::Object obj = Napi::Object::New(env);
337-
obj.Set("r1", Napi::Number::New(env, 0));
338-
Napi::Function cb = info[3].As<Napi::Function>();
339-
cb.Call({env.Null(), obj}); // Mock empty GoReturnTuple callback
340-
}
374+
CloseRowsWorker* worker = new CloseRowsWorker(cb, pid, cid, rid);
375+
worker->Queue();
341376
return env.Undefined();
342377
}
343378

spannerlib/wrappers/spannerlib-node/src/lib/connection.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export class Connection {
5454

5555
c.oid = handled.objectId;
5656
c.pinnerId = handled.pinnerId;
57+
spannerLib.register(c, handled.pinnerId);
5758
return c;
5859
}
5960

@@ -89,8 +90,9 @@ export class Connection {
8990
serializedPb
9091
);
9192
const rowsId = rowsResult.objectId;
93+
const rowsPinnerId = rowsResult.pinnerId;
9294

93-
return new Rows(this, rowsId);
95+
return new Rows(this, rowsId, rowsPinnerId);
9496
}
9597

9698
/**

spannerlib/wrappers/spannerlib-node/src/lib/pool.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export class Pool {
5252

5353
p.oid = handled.objectId;
5454
p.pinnerId = handled.pinnerId;
55+
spannerLib.register(p, handled.pinnerId);
5556
return p;
5657
}
5758

spannerlib/wrappers/spannerlib-node/src/lib/rows.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ export class Rows {
3333
public oid: number;
3434
public pinnerId: number | null;
3535
public closed: boolean;
36-
constructor(connection: Connection, oid: number) {
36+
constructor(connection: Connection, oid: number, pinnerId: number) {
3737
this.connection = connection;
3838
this.oid = oid;
39-
this.pinnerId = null;
39+
this.pinnerId = pinnerId;
4040
this.closed = false;
41+
spannerLib.register(this, pinnerId);
4142
}
4243

4344
/**
@@ -50,11 +51,15 @@ export class Rows {
5051
async next(): Promise<unknown> {
5152
if (this.closed) throw new Error('Rows are already closed');
5253

54+
if (!this.connection.pool) {
55+
throw new Error('Connection must be bound to a Pool to fetch rows');
56+
}
57+
5358
const handled = await ffi.invokeAsync(
5459
'Next',
5560
null,
5661
null,
57-
this.connection.pool!.oid,
62+
this.connection.pool.oid,
5863
this.connection.oid,
5964
this.oid,
6065
1,
@@ -65,7 +70,11 @@ export class Rows {
6570
return null;
6671
}
6772

68-
return ListValue.decode(handled.protobufBytes);
73+
const row = ListValue.decode(handled.protobufBytes);
74+
if (handled.pinnerId && handled.pinnerId > 0) {
75+
ffi.Release(handled.pinnerId);
76+
}
77+
return row;
6978
}
7079

7180
/**

spannerlib/wrappers/spannerlib-node/test/rows.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe('Rows', () => {
4848
connection.pool = pool;
4949
connection.oid = 2;
5050

51-
const rows = new Rows(connection, 3);
51+
const rows = new Rows(connection, 3, 4);
5252

5353
// Create a dummy ListValue
5454
const listValue = ListValue.create({
@@ -88,7 +88,7 @@ describe('Rows', () => {
8888
connection.pool = pool;
8989
connection.oid = 2;
9090

91-
const rows = new Rows(connection, 3);
91+
const rows = new Rows(connection, 3, 4);
9292

9393
stub
9494
.onFirstCall()

0 commit comments

Comments
 (0)