diff --git a/package-lock.json b/package-lock.json index 35f65feb..94a4bfde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "sql.js", - "version": "1.8.0", + "name": "@gemini-testing/sql.js", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 52b499ec..4ff6aebe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "sql.js", - "version": "1.8.0", + "name": "@gemini-testing/sql.js", + "version": "2.0.0", "description": "SQLite library with support for opening and writing databases, prepared statements, and more. This SQLite library is in pure javascript (compiled with emscripten).", "keywords": [ "sql", @@ -32,13 +32,13 @@ "test-wasm-debug": "node --unhandled-rejections=strict test/all.js wasm-debug", "doc": "jsdoc -c .jsdoc.config.json" }, - "homepage": "http://github.com/sql-js/sql.js", + "homepage": "https://github.com/gemini-testing/sql.js", "repository": { "type": "git", - "url": "http://github.com/sql-js/sql.js.git" + "url": "http://github.com/gemini-testing/sql.js.git" }, "bugs": { - "url": "https://github.com/sql-js/sql.js/issues" + "url": "https://github.com/gemini-testing/sql.js/issues" }, "devDependencies": { "clean-jsdoc-theme": "^3.3.4", diff --git a/src/api.js b/src/api.js index 6a7ce924..80e4c228 100644 --- a/src/api.js +++ b/src/api.js @@ -735,6 +735,30 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { this.activeStatement = null; } + function expandFileStorage(node, newCapacity) { + var prevCapacity = node.contents ? node.contents.length : 0; + // No need to expand, the storage was already large enough. + // Don't expand strictly to the given requested limit if it's + // only a very small increase, but instead geometrically grow capacity. + if (prevCapacity >= newCapacity) return; + // For small filesizes (<1MB), perform size*2 geometric increase, but + // for large sizes, do a much more conservative size*1.125 increase to + // avoid overshooting the allocation cap by a very large margin. + var CAPACITY_DOUBLING_MAX = 1024 * 1024; + var capacityCoef = prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125; + var newAutoCapacity = prevCapacity * capacityCoef; + newCapacity = Math.max(newCapacity, newAutoCapacity | 0); + // At minimum allocate 256b for each file when expanding. + if (prevCapacity !== 0) newCapacity = Math.max(newCapacity, 256); + var oldContents = node.contents; + node.contents = new Uint8Array(newCapacity); // Allocate new storage. + + if (node.usedBytes > 0) { + // Copy old data over to the new storage. + node.contents.set(oldContents.subarray(0, node.usedBytes), 0); + } + } + /** * @typedef {{ done:true, value:undefined } | * { done:false, value:Statement}} @@ -822,7 +846,7 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { * @param {number[]} data An array of bytes representing * an SQLite database file */ - function Database(data) { + function Database(data, initialDbSize) { this.filename = "dbfile_" + (0xffffffff * Math.random() >>> 0); if (data != null) { FS.createDataFile("/", this.filename, data, true, true); @@ -830,6 +854,14 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { this.handleError(sqlite3_open(this.filename, apiTemp)); this.db = getValue(apiTemp, "i32"); registerExtensionFunctions(this.db); + + if (initialDbSize) { + this.run("VACUUM"); + var parentNode = FS.lookupPath("/").node; + var dbNode = FS.lookupNode(parentNode, this.filename); + expandFileStorage(dbNode, initialDbSize); + } + // A list of all prepared statements of the database this.statements = {}; // A list of all user function of the database