Skip to content

Commit f94d591

Browse files
tdrztudor
andauthored
Simple clone impl only on PGlite (#526)
* simple clone impl on PGlite --------- Co-authored-by: tudor <tudor@swisstch.com>
1 parent ea110d1 commit f94d591

File tree

4 files changed

+57
-0
lines changed

4 files changed

+57
-0
lines changed

.changeset/mighty-grapes-refuse.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@electric-sql/pglite': patch
3+
---
4+
5+
added clone() method to pglite API. clones an instance such that it can be reused (for example running tests on existing data without readding all data)

docs/docs/api.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ await pg.describeQuery('SELECT * FROM test WHERE name = $1', ['test'])
361361
}
362362
```
363363

364+
### clone
365+
`.clone(): Promise<PGlite>`
366+
367+
Clones the current instance. This is useful when a series of operations, like unit or integration test, need to be run on the same database without having to recreate the database each time, or for each test.
368+
364369
## Properties
365370

366371
### ready

packages/pglite/src/pglite.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,4 +794,9 @@ export class PGlite
794794
_runExclusiveTransaction<T>(fn: () => Promise<T>): Promise<T> {
795795
return this.#transactionMutex.runExclusive(fn)
796796
}
797+
798+
async clone(): Promise<PGliteInterface> {
799+
const dump = await this.dumpDataDir('none')
800+
return new PGlite({ loadDataDir: dump })
801+
}
797802
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { describe, it, expect } from 'vitest'
2+
import { PGlite } from '../dist/index.js'
3+
4+
describe('clone', () => {
5+
it('clone pglite instance', async () => {
6+
const pg1 = new PGlite()
7+
await pg1.exec(`
8+
CREATE TABLE IF NOT EXISTS test (
9+
id SERIAL PRIMARY KEY,
10+
name TEXT
11+
);
12+
`)
13+
await pg1.exec("INSERT INTO test (name) VALUES ('test');")
14+
15+
const pg2 = await pg1.clone()
16+
17+
const ret1 = await pg1.query('SELECT * FROM test;')
18+
const ret2 = await pg2.query('SELECT * FROM test;')
19+
20+
expect(ret1).toEqual(ret2)
21+
})
22+
23+
it('clone pglite instance - insert into pg2', async () => {
24+
const pg1 = new PGlite()
25+
await pg1.exec(`
26+
CREATE TABLE IF NOT EXISTS test (
27+
id SERIAL PRIMARY KEY,
28+
name TEXT
29+
);
30+
`)
31+
await pg1.exec("INSERT INTO test (name) VALUES ('test');")
32+
33+
const pg2 = await pg1.clone()
34+
await pg2.exec("INSERT INTO test (name) VALUES ('2-test');")
35+
36+
const ret1 = await pg1.query('SELECT * FROM test;')
37+
const ret2 = await pg2.query('SELECT * FROM test;')
38+
39+
expect(ret1.rows.length).toBe(1)
40+
expect(ret2.rows.length).toBe(2)
41+
})
42+
})

0 commit comments

Comments
 (0)