Add support for nested json metadata.

This commit is contained in:
Young Hahn
2013-07-12 05:41:31 -04:00
parent f6ff8735b2
commit 46f0b33bc8
3 changed files with 34 additions and 5 deletions

View File

@@ -229,6 +229,18 @@ MBTiles.prototype.getInfo = function(callback) {
if (err && err.errno !== 1) return callback(err);
if (rows) rows.forEach(function(row) {
switch (row.name) {
// The special "json" key/value pair allows JSON to be serialized
// and merged into the metadata of an MBTiles based source. This
// enables nested properties and non-string datatypes to be
// captured by the MBTiles metadata table.
case 'json':
try { var jsondata = JSON.parse(row.value); }
catch (err) { return callback(err); }
Object.keys(jsondata).reduce(function(memo, key) {
memo[key] = memo[key] || jsondata[key];
return memo;
}, info);
break;
case 'minzoom':
case 'maxzoom':
info[row.name] = parseInt(row.value, 10);
@@ -537,11 +549,21 @@ MBTiles.prototype.putInfo = function(data, callback) {
if (!this.open) return callback(new Error('MBTiles not yet loaded'));
if (!this._isWritable) return callback(new Error('MBTiles not in write mode'));
var jsondata;
var stmt = this._db.prepare('REPLACE INTO metadata (name, value) VALUES (?, ?)');
stmt.on('error', callback);
for (var key in data) {
stmt.run(key, String(data[key]));
// If a data property is a javascript hash/object, slip it into
// the 'json' field which contains stringified JSON to be merged
// in at read time. Allows nested/deep metadata to be recorded.
if (typeof data[key] === 'object' && !Array.isArray(data[key])) {
jsondata = jsondata || {};
jsondata[key] = data[key];
} else {
stmt.run(key, String(data[key]));
}
}
if (jsondata) stmt.run('json', JSON.stringify(jsondata));
var mbtiles = this;
stmt.finalize(function(err) {

Binary file not shown.

View File

@@ -30,7 +30,8 @@ describe('info', function() {
formatter: null,
center: [ 0, 7.500000001278025, 2 ],
bounds: [ -179.9999999749438, -69.99999999526695, 179.9999999749438, 84.99999999782301 ],
// Test that json data is merged in.
level1: { level2: 'property' },
// These aren't part of TileJSON, but exist in an MBTiles file.
filesize: 561152,
type: 'baselayer',
@@ -45,6 +46,11 @@ describe('info', function() {
it('get/put metadata from empty file', function(done) {
this.timeout(10e3);
var info = {
version: '1.0.0',
level1: { level2: 'property' }
};
new MBTiles(fixtures.empty, function(err, mbtiles) {
assert.ifError(err);
@@ -58,14 +64,14 @@ describe('info', function() {
scheme: "tms"
}, data);
mbtiles.putInfo({ version: '1.0.0' }, function(err) {
mbtiles.putInfo(info, function(err) {
assert.ok(err);
assert.equal(err.message, 'MBTiles not in write mode');
mbtiles.startWriting(function(err) {
assert.ifError(err);
mbtiles.putInfo({ version: '1.0.0' }, function(err) {
mbtiles.putInfo(info, function(err) {
assert.ifError(err);
mbtiles.stopWriting(function(err) {
@@ -79,7 +85,8 @@ describe('info', function() {
filesize: 0,
id: "empty",
scheme: "tms",
version: "1.0.0"
version: "1.0.0",
level1: { level2: "property" },
}, data);
done();