Skip to content

Instantly share code, notes, and snippets.

@nolanlawson
Created January 30, 2015 04:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nolanlawson/5066da7b4df350089e50 to your computer and use it in GitHub Desktop.
Save nolanlawson/5066da7b4df350089e50 to your computer and use it in GitHub Desktop.
WebSQL MTG full-text search demo
<html>
<body>
<h1>WebSQL MTG full-text search demo</h1>
<p>Run this in Chrome or Safari. Look in the console.</p>
<script src="index.js"></script>
</body>
</html>
var attempt = Date.now(), reminder = {};
var db = openDatabase('mtg', '1', 'mtg', 100000000);
var log = console.log.bind(console);
function search(query) {
return new Promise(function (resolve, reject) {
var docs = [];
db.readTransaction(function (tx) {
var sql = 'select json from ' +
'(' +
'select docid from lookup where name match ? ' +
'union ' +
'select docid from lookup where text match ? ' +
') l ' +
'join cards c on l.docid=c.rowid';
var sqlArgs = [query, query];
tx.executeSql(sql, sqlArgs, function (tx, res) {
for (var i = 0; i < res.rows.length; i++) {
var item = res.rows.item(i);
docs.push(JSON.parse(item.json));
}
});
}, reject, function () {
resolve(docs);
});
});
}
Promise.resolve()
.then(start('Attempt ' + attempt, 'group'))
.then(start('Destroying database'))
.then(function() {
return new Promise(function (resolve, reject) {
db.transaction(function (tx) {
tx.executeSql('drop table cards');
tx.executeSql('drop table lookup');
}, resolve, resolve);
});
})
.then(stop())
.then(start('Creating database'))
.then(function() {
return new Promise(function (resolve, reject) {
db.transaction(function (tx) {
tx.executeSql('create table cards (json text)', [], function (tx) {
tx.executeSql('create virtual table lookup using fts3(name, text, tokenize=porter)');
});
}, reject, resolve);
});
})
.then(stop())
.then(start('Downloading cards'))
.then(function(db) {
return new Promise(function(resolve, reject) {
window.mtgjsoncallback = function(cards) {
resolve({ db: db, cards: cards });
};
var script = document.createElement('script');
script.src = 'http://mtgjson.com/json/AllCards.jsonp';
script.onload = function() {
script.parentNode.removeChild(script);
};
document.body.appendChild(script);
});
})
.then(stop())
.then(start('Transforming object to array'))
.then(function(result) {
result.cards = Object.keys(result.cards).map(function(name) {
return result.cards[name];
});
return result;
})
.then(stop())
.then(start('Inserting data'))
.then(function(result) {
return new Promise(function (resolve, reject) {
db.transaction(function (tx) {
result.cards.forEach(function (card) {
var sql = 'insert into cards (json) values (?)';
var sqlArgs = [JSON.stringify(card)];
tx.executeSql(sql, sqlArgs, function (tx, res) {
var rowId = res.insertId;
var sql = 'insert into lookup (docid, name, text) values (?,?,?)';
var sqlArgs = [rowId, card.name, card.text];
tx.executeSql(sql, sqlArgs);
});
});
}, reject, resolve);
});
})
.then(stop())
.then(start('Searching for "jeskai"'))
.then(function() {
return search('jeskai').then(log);
})
.then(stop())
.then(start('Searching for "counter"'))
.then(function() {
return search('counter').then(log);
})
.then(stop())
.then(start('Searching for "target"'))
.then(function() {
return search('target').then(log);
})
.then(stop())
.catch(console.error.bind(console))
.then(console.log.bind(console, 'Done!'))
.then(stop('group'), stop('group'));
// Helpers
function start(label, type) {
return function(result) {
reminder[type] = label;
if(type !== 'group') console.log(label);
console[type || 'time'](label);
return result;
};
}
function stop(type) {
return function(result) {
console[(type || 'time') + 'End'](reminder[type]);
return result;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment