Erster Docker-Stand
This commit is contained in:
1
_node_modules/@electric-sql/pglite-tools/src/index.ts
generated
Normal file
1
_node_modules/@electric-sql/pglite-tools/src/index.ts
generated
Normal file
@@ -0,0 +1 @@
|
||||
export * from './pg_dump'
|
||||
41
_node_modules/@electric-sql/pglite-tools/src/pgDumpModFactory.ts
generated
Normal file
41
_node_modules/@electric-sql/pglite-tools/src/pgDumpModFactory.ts
generated
Normal file
@@ -0,0 +1,41 @@
|
||||
import PgDumpModFactory from '../release/pg_dump'
|
||||
|
||||
type IDBFS = Emscripten.FileSystemType & {
|
||||
quit: () => void
|
||||
dbs: Record<string, IDBDatabase>
|
||||
}
|
||||
|
||||
export type FS = typeof FS & {
|
||||
filesystems: {
|
||||
MEMFS: Emscripten.FileSystemType
|
||||
NODEFS: Emscripten.FileSystemType
|
||||
IDBFS: IDBFS
|
||||
}
|
||||
quit: () => void
|
||||
}
|
||||
|
||||
export interface PgDumpMod
|
||||
extends Omit<EmscriptenModule, 'preInit' | 'preRun' | 'postRun'> {
|
||||
preInit: Array<{ (mod: PgDumpMod): void }>
|
||||
preRun: Array<{ (mod: PgDumpMod): void }>
|
||||
postRun: Array<{ (mod: PgDumpMod): void }>
|
||||
FS: FS
|
||||
WASM_PREFIX: string
|
||||
INITIAL_MEMORY: number
|
||||
_set_read_write_cbs: (read_cb: number, write_cb: number) => void
|
||||
addFunction: (
|
||||
cb: (ptr: any, length: number) => void,
|
||||
signature: string,
|
||||
) => number
|
||||
removeFunction: (f: number) => void
|
||||
_main: (args: string[]) => number
|
||||
onExit: (status: number) => void
|
||||
print: (test: string) => void
|
||||
printErr: (text: string) => void
|
||||
}
|
||||
|
||||
type PgDumpFactory<T extends PgDumpMod = PgDumpMod> = (
|
||||
moduleOverrides?: Partial<T>,
|
||||
) => Promise<T>
|
||||
|
||||
export default PgDumpModFactory as PgDumpFactory<PgDumpMod>
|
||||
157
_node_modules/@electric-sql/pglite-tools/src/pg_dump.ts
generated
Normal file
157
_node_modules/@electric-sql/pglite-tools/src/pg_dump.ts
generated
Normal file
@@ -0,0 +1,157 @@
|
||||
import { PGlite } from '@electric-sql/pglite'
|
||||
import PgDumpModFactory, { PgDumpMod } from './pgDumpModFactory'
|
||||
|
||||
const dumpFilePath = '/tmp/out.sql'
|
||||
|
||||
/**
|
||||
* Creates a new Uint8Array based on two different ArrayBuffers
|
||||
*
|
||||
* @private
|
||||
* @param {ArrayBuffers} buffer1 The first buffer.
|
||||
* @param {ArrayBuffers} buffer2 The second buffer.
|
||||
* @return {ArrayBuffers} The new ArrayBuffer created out of the two.
|
||||
*/
|
||||
function concat(buffer1: ArrayBuffer, buffer2: ArrayBuffer) {
|
||||
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)
|
||||
tmp.set(new Uint8Array(buffer1), 0)
|
||||
tmp.set(new Uint8Array(buffer2), buffer1.byteLength)
|
||||
return tmp
|
||||
}
|
||||
|
||||
interface ExecResult {
|
||||
exitCode: number
|
||||
fileContents: string
|
||||
stderr: string
|
||||
stdout: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner function to execute pg_dump
|
||||
*/
|
||||
async function execPgDump({
|
||||
pg,
|
||||
args,
|
||||
}: {
|
||||
pg: PGlite
|
||||
args: string[]
|
||||
}): Promise<ExecResult> {
|
||||
let pgdump_write, pgdump_read
|
||||
let exitStatus = 0
|
||||
let stderrOutput: string = ''
|
||||
let stdoutOutput: string = ''
|
||||
const emscriptenOpts: Partial<PgDumpMod> = {
|
||||
arguments: args,
|
||||
noExitRuntime: false,
|
||||
print: (text) => {
|
||||
stdoutOutput += text
|
||||
},
|
||||
printErr: (text) => {
|
||||
stderrOutput += text
|
||||
},
|
||||
onExit: (status: number) => {
|
||||
exitStatus = status
|
||||
},
|
||||
preRun: [
|
||||
(mod: PgDumpMod) => {
|
||||
mod.onRuntimeInitialized = () => {
|
||||
let bufferedBytes: Uint8Array = new Uint8Array()
|
||||
|
||||
pgdump_write = mod.addFunction((ptr: any, length: number) => {
|
||||
let bytes
|
||||
try {
|
||||
bytes = mod.HEAPU8.subarray(ptr, ptr + length)
|
||||
} catch (e: any) {
|
||||
console.error('error', e)
|
||||
throw e
|
||||
}
|
||||
const currentResponse = pg.execProtocolRawSync(bytes)
|
||||
bufferedBytes = concat(bufferedBytes, currentResponse)
|
||||
return length
|
||||
}, 'iii')
|
||||
|
||||
pgdump_read = mod.addFunction((ptr: any, max_length: number) => {
|
||||
let length = bufferedBytes.length
|
||||
if (length > max_length) {
|
||||
length = max_length
|
||||
}
|
||||
try {
|
||||
mod.HEAP8.set(bufferedBytes.subarray(0, length), ptr)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
bufferedBytes = bufferedBytes.subarray(length, bufferedBytes.length)
|
||||
return length
|
||||
}, 'iii')
|
||||
|
||||
mod._set_read_write_cbs(pgdump_read, pgdump_write)
|
||||
// default $HOME in emscripten is /home/web_user
|
||||
mod.FS.chmod('/home/web_user/.pgpass', 0o0600) // https://www.postgresql.org/docs/current/libpq-pgpass.html
|
||||
}
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const mod = await PgDumpModFactory(emscriptenOpts)
|
||||
let fileContents = ''
|
||||
if (!exitStatus) {
|
||||
fileContents = mod.FS.readFile(dumpFilePath, { encoding: 'utf8' })
|
||||
}
|
||||
|
||||
return {
|
||||
exitCode: exitStatus,
|
||||
fileContents,
|
||||
stderr: stderrOutput,
|
||||
stdout: stdoutOutput,
|
||||
}
|
||||
}
|
||||
|
||||
interface PgDumpOptions {
|
||||
pg: PGlite
|
||||
args?: string[]
|
||||
fileName?: string
|
||||
verbose?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute pg_dump
|
||||
*/
|
||||
export async function pgDump({
|
||||
pg,
|
||||
args,
|
||||
fileName = 'dump.sql',
|
||||
}: PgDumpOptions) {
|
||||
const getSearchPath = await pg.query<{ search_path: string }>(
|
||||
'SHOW SEARCH_PATH;',
|
||||
)
|
||||
const search_path = getSearchPath.rows[0].search_path
|
||||
|
||||
const baseArgs = [
|
||||
'-U',
|
||||
'postgres',
|
||||
'--inserts',
|
||||
'-j',
|
||||
'1',
|
||||
'-f',
|
||||
dumpFilePath,
|
||||
'postgres',
|
||||
]
|
||||
|
||||
const execResult = await execPgDump({
|
||||
pg,
|
||||
args: [...(args ?? []), ...baseArgs],
|
||||
})
|
||||
|
||||
pg.exec(`DEALLOCATE ALL; SET SEARCH_PATH = ${search_path}`)
|
||||
|
||||
if (execResult.exitCode !== 0) {
|
||||
throw new Error(
|
||||
`pg_dump failed with exit code ${execResult.exitCode}. \nError message: ${execResult.stderr}`,
|
||||
)
|
||||
}
|
||||
|
||||
const file = new File([execResult.fileContents], fileName, {
|
||||
type: 'text/plain',
|
||||
})
|
||||
|
||||
return file
|
||||
}
|
||||
Reference in New Issue
Block a user