Skip to content

Instantly share code, notes, and snippets.

@meirish
Last active March 6, 2017 18:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meirish/4997107 to your computer and use it in GitHub Desktop.
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.
<!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>
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();
}
}
@meirish
Copy link
Author

meirish commented Feb 20, 2013

@bobenglish
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment