Created
January 30, 2015 04:30
-
-
Save nolanlawson/5066da7b4df350089e50 to your computer and use it in GitHub Desktop.
WebSQL MTG full-text search demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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