diff --git a/appveyor.yml b/appveyor.yml index 55546ae..8fc6d8e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,6 +15,5 @@ install: build: OFF test: OFF -test_script: OFF deploy: OFF diff --git a/lib/zxystream.js b/lib/zxystream.js index 56b7d5f..011ef14 100644 --- a/lib/zxystream.js +++ b/lib/zxystream.js @@ -28,7 +28,17 @@ function ZXYStream(source, options) { ZXYStream.prototype._read = function() { var stream = this; - this.source._db.all('SELECT zoom_level AS z, tile_column AS x, tile_row AS y FROM tiles LIMIT ' + this.batch + ' OFFSET ' + this.offset, function(err, rows) { + + // Check for the existence of a map table that is indexed. + if (!stream.table) { + return this.source._db.get("select count(1) as count from sqlite_master where type = 'index' and tbl_name = 'map';", function(err, row) { + if (err) return stream.emit('error', err); + stream.table = row.count === 1 ? 'map' : 'tiles'; + return stream._read(); + }); + } + + this.source._db.all('SELECT zoom_level AS z, tile_column AS x, tile_row AS y FROM ' + this.table + ' LIMIT ' + this.batch + ' OFFSET ' + this.offset, function(err, rows) { if (err && err.code === 'SQLITE_ERROR' && /no such table/.test(err.message)) return stream.push(null); if (err) return stream.emit('error', err); if (!rows.length) return stream.push(null); diff --git a/test/fixtures/unindexed.mbtiles b/test/fixtures/unindexed.mbtiles new file mode 100644 index 0000000..5399389 Binary files /dev/null and b/test/fixtures/unindexed.mbtiles differ diff --git a/test/zxystream.js b/test/zxystream.js index b9c34cf..92008fc 100644 --- a/test/zxystream.js +++ b/test/zxystream.js @@ -20,6 +20,7 @@ tape('zxystream default batch', function(assert) { assert.deepEqual(stream.offset, 0, 'sets stream.offset = 0'); stream.on('data', function(lines) { + assert.equal(stream.table, 'map'); output += lines; called++; }); @@ -52,6 +53,7 @@ tape('zxystream batch = 10', function(assert) { assert.deepEqual(stream.offset, 0, 'sets stream.offset = 0'); stream.on('data', function(lines) { + assert.equal(stream.table, 'map'); output += lines; called++; }); @@ -73,6 +75,48 @@ tape('zxystream batch = 10', function(assert) { }); }); +tape('zxystream unindexed', function(assert) { + new MBTiles(__dirname + '/fixtures/unindexed.mbtiles', function(err, s) { + assert.ifError(err); + source = s; + assert.end(); + }); +}); + +tape('zxystream unindexed zxystream', function(assert) { + var stream = source.createZXYStream(); + var output = ''; + var called = 0; + + assert.deepEqual(stream.source, source, 'sets stream.source'); + assert.deepEqual(stream.batch, 1000, 'sets stream.batch = 1000'); + assert.deepEqual(stream.offset, 0, 'sets stream.offset = 0'); + + stream.on('data', function(lines) { + assert.equal(stream.table, 'tiles'); + output += lines; + called++; + }); + stream.on('end', function() { + var queue = output.toString().split('\n'); + assert.equal(queue.length, 286); + assert.equal(called, 1, 'emitted data x27 times'); + checkTile(queue); + function checkTile(queue) { + if (!queue.length) return assert.end(); + var zxy = queue.shift(); + if (!zxy) return checkTile(queue); + zxy = zxy.split('/'); + source.getTile(zxy[0], zxy[1], zxy[2], function(err, buffer, headers) { + assert.equal(!err && (buffer instanceof Buffer), true, zxy.join('/') + ' exists'); + checkTile(queue); + }); + } + }); +}); + + + tape('zxystream empty', function(assert) { new MBTiles(__dirname + '/fixtures/non_existent.mbtiles', function(err, s) { assert.ifError(err);