@ngageoint/geopackage
Version:
GeoPackage JavaScript Library
417 lines • 17.7 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqljsAdapter = void 0;
var rtree_sql_js_1 = __importDefault(require("rtree-sql.js"));
/**
* This adapter uses sql.js to execute queries against the GeoPackage database
* @module db/sqljsAdapter
* @see {@link http://kripken.github.io/sql.js/documentation/|sqljs}
*/
var SqljsAdapter = /** @class */ (function () {
/**
* @param {string|Buffer|Uint8Array} [filePath] string path to an existing file or a path to where a new file will be created or a url from which to download a GeoPackage or a Uint8Array containing the contents of the file, if undefined, an in memory database is created
*/
function SqljsAdapter(filePath) {
this.filePath = filePath;
}
SqljsAdapter.setSqljsWasmLocateFile = function (locateFile) {
SqljsAdapter.sqljsWasmLocateFile = locateFile;
};
/**
* Returns a Promise which, when resolved, returns a DBAdapter which has connected to the GeoPackage database file
*/
SqljsAdapter.prototype.initialize = function () {
var _this = this;
return new Promise(function (resolve, reject) {
new Promise(function (resolve) {
if (SqljsAdapter.SQL == null) {
(0, rtree_sql_js_1.default)({
locateFile: SqljsAdapter.sqljsWasmLocateFile,
}).then(function (SQL) {
SqljsAdapter.SQL = SQL;
resolve(SQL);
}).catch(function (e) {
reject(e);
});
}
else {
resolve(SqljsAdapter.SQL);
}
}).then(function (SQL) {
if (_this.filePath && typeof _this.filePath === 'string') {
if (typeof process !== 'undefined' && process.version) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
var fs = require('fs');
if (_this.filePath.indexOf('http') === 0) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
var http = require('http');
http
.get(_this.filePath, function (response) {
if (response.statusCode !== 200) {
return reject(new Error('Unable to reach url: ' + _this.filePath));
}
var body = [];
response.on('data', function (chunk) { return body.push(chunk); });
response.on('end', function () {
var t = new Uint8Array(Buffer.concat(body));
_this.db = new SQL.Database(t);
resolve(_this);
});
})
.on('error', function (e) {
return reject(e);
});
}
else {
try {
fs.statSync(_this.filePath);
}
catch (e) {
_this.db = new SQL.Database();
// var adapter = new SqljsAdapter(db);
return resolve(_this);
}
var filebuffer = fs.readFileSync(_this.filePath);
var t = new Uint8Array(filebuffer);
_this.db = new SQL.Database(t);
return resolve(_this);
}
}
else {
// eslint-disable-next-line no-undef
var xhr_1 = new XMLHttpRequest();
xhr_1.open('GET', _this.filePath, true);
xhr_1.responseType = 'arraybuffer';
xhr_1.onload = function () {
if (xhr_1.status !== 200) {
return reject(new Error('Unable to reach url: ' + _this.filePath));
}
var uInt8Array = new Uint8Array(xhr_1.response);
_this.db = new SQL.Database(uInt8Array);
return resolve(_this);
};
xhr_1.onerror = function () {
return reject(new Error('Error reaching url: ' + _this.filePath));
};
xhr_1.send();
}
}
else if (_this.filePath) {
var byteArray = _this.filePath;
_this.db = new SQL.Database(byteArray);
return resolve(_this);
}
else {
_this.db = new SQL.Database();
return resolve(_this);
}
}).catch(function (e) {
reject(e);
});
});
};
/**
* Closes the connection to the GeoPackage
*/
SqljsAdapter.prototype.close = function () {
this.db.close();
};
/**
* Get the connection to the database file
* @return {any}
*/
SqljsAdapter.prototype.getDBConnection = function () {
return this.db;
};
/**
* Returns a Uint8Array containing the contents of the database as a file
*/
SqljsAdapter.prototype.export = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.db.export()];
});
});
};
/**
* Registers the given function so that it can be used by SQL statements
* @see {@link http://kripken.github.io/sql.js/documentation/#http://kripken.github.io/sql.js/documentation/class/Database.html#create_function-dynamic|sqljs create_function}
* @param {string} name name of function to register
* @param {Function} functionDefinition function to register
* @return {module:db/sqljsAdapter~Adapter} this
*/
SqljsAdapter.prototype.registerFunction = function (name, functionDefinition) {
this.db.create_function(name, functionDefinition);
return this;
};
/**
* Gets one row of results from the statement
* @see {@link http://kripken.github.io/sql.js/documentation/#http://kripken.github.io/sql.js/documentation/class/Statement.html#get-dynamic|sqljs get}
* @see {@link http://kripken.github.io/sql.js/documentation/#http://kripken.github.io/sql.js/documentation/class/Statement.html#getAsObject-dynamic|sqljs getAsObject}
* @param {String} sql statement to run
* @param {Array|Object} [params] substitution parameters
* @return {Object}
*/
SqljsAdapter.prototype.get = function (sql, params) {
params = params || [];
var statement = this.db.prepare(sql);
statement.bind(params);
var hasResult = statement.step();
var row;
if (hasResult) {
row = statement.getAsObject();
}
statement.free();
return row;
};
/**
* Determines if a tableName exists in the database
* @param {String} tableName
* @returns {Boolean}
*/
SqljsAdapter.prototype.isTableExists = function (tableName) {
var statement = this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=:name");
statement.bind([tableName]);
var hasResult = statement.step();
var row;
if (hasResult) {
row = statement.getAsObject();
}
statement.free();
return !!row;
};
/**
* Gets all results from the statement in an array
* @param {String} sql statement to run
* @param {Array|Object} [params] bind parameters
* @return {Object[]}
*/
SqljsAdapter.prototype.all = function (sql, params) {
var e_1, _a;
var rows = [];
var iterator = this.each(sql, params);
try {
for (var iterator_1 = __values(iterator), iterator_1_1 = iterator_1.next(); !iterator_1_1.done; iterator_1_1 = iterator_1.next()) {
var row = iterator_1_1.value;
rows.push(row);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (iterator_1_1 && !iterator_1_1.done && (_a = iterator_1.return)) _a.call(iterator_1);
}
finally { if (e_1) throw e_1.error; }
}
return rows;
};
/**
* Returns an Iterable with results from the query
* @param {string} sql statement to run
* @param {Object|Array} params bind parameters
* @return {IterableIterator<Object>}
*/
SqljsAdapter.prototype.each = function (sql, params) {
var _a;
var statement = this.db.prepare(sql);
statement.bind(params);
return _a = {},
_a[Symbol.iterator] = function () {
return this;
},
_a.next = function () {
if (statement.step()) {
return {
value: statement.getAsObject(),
done: false,
};
}
else {
statement.free();
return {
value: undefined,
done: true,
};
}
},
_a;
};
/**
* Runs the statement specified, returning information about what changed
* @see {@link http://kripken.github.io/sql.js/documentation/#http://kripken.github.io/sql.js/documentation/class/Statement.html#run-dynamic|sqljs run}
* @param {string} sql statement to run
* @param {Object|Array} [params] bind parameters
* @return {Object} object containing a changes property indicating the number of rows changed and a lastInsertROWID indicating the last inserted row
*/
SqljsAdapter.prototype.run = function (sql, params) {
if (params && !(params instanceof Array)) {
for (var key in params) {
params['$' + key] = params[key];
}
}
this.db.run(sql, params);
var lastId = this.db.exec('select last_insert_rowid();');
var lastInsertedId;
if (lastId) {
lastInsertedId = lastId[0].values[0][0];
}
return {
lastInsertRowid: lastInsertedId,
changes: this.db.getRowsModified(),
};
};
/**
* Runs the specified insert statement and returns the last inserted id or undefined if no insert happened
* @param {String} sql statement to run
* @param {Object|Array} [params] bind parameters
* @return {Number} last inserted row id
*/
SqljsAdapter.prototype.insert = function (sql, params) {
if (params && !(params instanceof Array)) {
for (var key in params) {
params['$' + key] = params[key];
}
}
var statement = this.db.prepare(sql, params);
statement.step();
statement.free();
var lastId = this.db.exec('select last_insert_rowid();');
if (lastId) {
return lastId[0].values[0][0];
}
else {
return;
}
};
/**
* Prepares a SQL statement
* @param sql
*/
SqljsAdapter.prototype.prepareStatement = function (sql) {
return this.db.prepare(sql);
};
/**
* Runs an insert statement with the parameters provided
* @param {any} statement statement to run
* @param {Object|Array} [params] bind parameters
* @return {Number} last inserted row id
*/
SqljsAdapter.prototype.bindAndInsert = function (statement, params) {
if (params && !(params instanceof Array)) {
for (var key in params) {
params['$' + key] = typeof params[key] === 'undefined' ? null : params[key];
}
}
return statement.run(params).lastInsertRowid;
};
/**
* Closes a prepared statement
* @param statement
*/
SqljsAdapter.prototype.closeStatement = function (statement) {
statement.free();
};
/**
* Runs the specified delete statement and returns the number of deleted rows
* @param {String} sql statement to run
* @param {Object|Array} [params] bind parameters
* @return {Number} deleted rows
*/
SqljsAdapter.prototype.delete = function (sql, params) {
var rowsModified;
var statement = this.db.prepare(sql, params);
statement.step();
rowsModified = this.db.getRowsModified();
statement.free();
return rowsModified;
};
/**
* Drops the table
* @param {String} table table name
* @return {Boolean} indicates if the table was dropped
*/
SqljsAdapter.prototype.dropTable = function (table) {
var response = this.db.exec('DROP TABLE IF EXISTS "' + table + '"');
this.db.exec('VACUUM');
return !!response;
};
/**
* Counts rows that match the query
* @param {String} tableName table name from which to count
* @param {String} [where] where clause
* @param {Object|Array} [whereArgs] where args
* @return {Number} count
*/
SqljsAdapter.prototype.count = function (tableName, where, whereArgs) {
var sql = 'SELECT COUNT(*) as count FROM "' + tableName + '"';
if (where) {
sql += ' where ' + where;
}
return this.get(sql, whereArgs).count;
};
SqljsAdapter.prototype.transaction = function (func) {
this.db.exec('BEGIN TRANSACTION');
try {
func();
this.db.exec('COMMIT TRANSACTION');
}
catch (e) {
this.db.exec('ROLLBACK TRANSACTION');
throw e;
}
};
SqljsAdapter.sqljsWasmLocateFile = function (filename) { return filename; };
return SqljsAdapter;
}());
exports.SqljsAdapter = SqljsAdapter;
//# sourceMappingURL=sqljsAdapter.js.map