Last active
March 6, 2017 18:40
-
-
Save meirish/4997107 to your computer and use it in GitHub Desktop.
First attempt trying to detect amount of free space in WebSQL using a temporary db that we fill with 0's. Blog post to follow.
This file contains hidden or 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
<!DOCTYPE HTML> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Yardstick Test</title> | |
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=0" /> | |
<meta name="apple-mobile-web-app-capable" content="yes" /> | |
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> | |
<script src="./yardstick.js"></script> | |
<style type="text/css" media="all"> | |
*{ | |
-moz-box-sizing: border-box; | |
-webkit-box-sizing: border-box; | |
box-sizing: border-box; | |
} | |
html, body { | |
padding: 0; | |
margin: 0; | |
font-family: 'AvenirNext-Regular', sans-serif; | |
background-color: #5F686D; | |
color: #ffeeee; | |
line-height: 1.4; | |
} | |
div{ | |
padding: .5em 2em; | |
width: 100%; | |
} | |
h2 { | |
font-size: 2em; | |
font-family: 'AvenirNext-DemiBold'; | |
margin: 0; | |
font-weight: normal; | |
line-height: 1; | |
padding: .75em 1em .5em; | |
} | |
input, button { | |
width: 100%; | |
padding: .25em .5em; | |
font-size: 1.25em; | |
} | |
label { | |
text-transform: uppercase; | |
font-size: .8em; | |
} | |
button { | |
background-color: #695F6D; | |
color: white; | |
border: 1px solid rgba(255,255,255,.4); | |
border-radius: .25em; | |
} | |
.error, .success, .pending{ | |
text-align: center; | |
color: #5F686D; | |
font-size: 1.5em; | |
} | |
.pending { | |
background-color: #C7D100; | |
} | |
.error{ | |
background-color: #FF401A; | |
} | |
.success{ | |
background-color: #22FF00; | |
} | |
hr { | |
width: 90%; | |
border: none; | |
height: 1px; | |
background-color: rgba(255,255,255,.4); | |
box-shadow: 0 1px 3px rgba(0,0,0,0.2); | |
} | |
</style> | |
</head> | |
<body> | |
<h2>Add Data to Database</h2> | |
<div id="db-console"> | |
We'll create a db and fill it with dummy data to the amount you specify. | |
</div> | |
<div class="db-create"> | |
<label for="db-size">Data Size (in MB)</label> | |
<input type="number" name="db-size" id="db-size" value="5" /> | |
<button type="button" id="create">Add to the Database</button> | |
</div> | |
<hr /> | |
<h2>Detect Free Space</h2> | |
<div id="db-measure-console"> | |
Choose an amount to add, and we'll tell you if it fits. If it doesn't we'll tell you how much will. | |
</div> | |
<div class="db-detect"> | |
<label for="size-to-add">Amount to add (in MB)</label> | |
<input type="number" name="size-to-add" id="size-to-add" value="10" /> | |
<button type="button" id="measure">Will this amount fit in the Database?</button> | |
</div> | |
<script> | |
(function () { | |
var MB = '', | |
max = 1024 * 1024, | |
createDbBtn = document.getElementById('create'), | |
size = document.getElementById('db-size'), | |
measureDbBtn = document.getElementById('measure'), | |
sizeToAdd = document.getElementById('size-to-add'), | |
dbConsole = document.getElementById('db-console'), | |
measureConsole = document.getElementById('db-measure-console'), | |
dbObj; | |
for (var i = 0; i < max; i++) { | |
MB+= '0'; | |
}; | |
function errorHandler(txn, e) { | |
console.log(txn); | |
console.log('Error: ' + e.code + ': ' + e.message); | |
} | |
function createDb() { | |
var name = 'test', | |
version = '1.0', | |
description = 'This is a Test'; | |
return openDatabase(name, version, description, 50*1024*1024); | |
} | |
createDbBtn.addEventListener('click', function (e) { | |
var dbSize = size.value, | |
dbObj = { | |
errorHandler: errorHandler, | |
db: createDb() | |
}; | |
dbConsole.className = 'pending'; | |
dbConsole.innerHTML = 'Tearing down and writing to the main database'; | |
Yardstick.prototype.reset.call(dbObj, 'dummy_data', function (){ | |
Yardstick.prototype.insert.call(dbObj, dbSize, 'dummy_data', MB, | |
function () { | |
dbConsole.className = 'success'; | |
dbConsole.innerHTML = 'Wrote ' + dbSize + 'MB to the main database'; | |
}, | |
function (e) { | |
dbConsole.className = 'error'; | |
dbConsole.innerHTML = 'There was an error: ' + e.code + ': ' + e.message; | |
} | |
); | |
}); | |
}, false); | |
measureDbBtn.addEventListener('click', function (e) { | |
var ys = new Yardstick(); | |
measureConsole.className = 'pending'; | |
measureConsole.innerHTML = 'Determining if we can save ' + sizeToAdd.value + 'MB'; | |
ys.measure(sizeToAdd.value, function (avail, e) { | |
if (!e) { | |
measureConsole.className = 'success'; | |
measureConsole.innerHTML = 'Yes, we can save ' + avail + 'MB'; | |
} else { | |
measureConsole.className = 'error'; | |
measureConsole.innerHTML = 'There is only ' + avail + 'MB of free space available'; | |
} | |
}); | |
}, false); | |
})() | |
</script> | |
</body> | |
</html> |
This file contains hidden or 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
function Yardstick () { | |
// assumes you've already asked for a bunch of space so we only | |
// create a very small db | |
this.db = openDatabase('test', '1.0', 'This is a Test', 50); | |
this.available = 0; | |
this.dummyData = ''; | |
this.MB = 1024 * 1024; | |
// setup the db | |
this.reset(); | |
} | |
Yardstick.prototype = { | |
errorHandler: function (txn, e) { | |
console.log('errored ' + e.message + ' (Code ' + e.code + ')'); | |
return true; | |
}, | |
buildMB: function (callback) { | |
// need a MB of stuff to jam into the DB, | |
// so let's create it dynamically | |
var limit = this.MB; | |
while (limit > 0){ | |
this.dummyData+= '0'; | |
-- limit; | |
} | |
callback && callback(); | |
}, | |
measure: function (targetSize, callback) { | |
console.time('measure'); | |
var self = this, | |
complete = function (e) { | |
// will probably move this to triggering an event later | |
console.log(self.available); | |
callback && callback(self.available, e); | |
self.cleanup(); | |
console.timeEnd('measure'); | |
}; | |
// reset the counter every time we measure | |
this.available = 0; | |
this.buildMB(function() { | |
// call complete on both success or error of the transation | |
// so that we'll know when YS.available is ready | |
self.insert((+targetSize), null, null, complete, complete); | |
}); | |
}, | |
insert: function (targetSize, tableName, content, success, error) { | |
var self = this, | |
table = tableName || 'ys', | |
data = content || this.dummyData, | |
successHandler = function (txn, result){ | |
// let AUTOINCREMENT count for us | |
// insertId will equal the # of records | |
self.available = result.insertId; | |
}; | |
this.db.transaction( | |
function(transaction) { | |
// inserts 1MB per loop | |
for(var i = 0; i < targetSize; i++) { | |
transaction.executeSql('INSERT INTO ' + table + ' (content) VALUES (?)', [data], successHandler, self.errorHandler); | |
}; | |
}, | |
function(e){ | |
console.log('error: ', e); | |
error && error(e); | |
}, | |
function(){ | |
console.log('insert succeeded!'); | |
success && success(); | |
} | |
); | |
}, | |
reset: function (tableName, callback) { | |
var table = tableName || 'ys'; | |
this.db.transaction( | |
function(transaction) { | |
transaction.executeSql('DROP TABLE IF EXISTS ' + table, [], function(){}, this.errorHandler); | |
transaction.executeSql('CREATE TABLE ' + table + ' (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, content TEXT);', [], function(){ | |
callback && callback(); | |
}, this.errorHandler); | |
} | |
); | |
}, | |
deleteAll: function () { | |
this.db.transaction( | |
function(transaction) { | |
transaction.executeSql('DROP TABLE IF EXISTS ys', [], function(){}, this.errorHandler); | |
} | |
); | |
}, | |
cleanup: function () { | |
this.dummyData = ''; | |
this.deleteAll(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi merish,
I'm surprised that more people haven't commented. This is the only working example I've found of a way to let people know when they are near the end of their storage space on iOS. I don't see any license on the code. Am I free to use it?
Nice job and thanks,
Bob English