Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created March 25, 2014 11:21
Show Gist options
  • Save bennadel/9759762 to your computer and use it in GitHub Desktop.
Save bennadel/9759762 to your computer and use it in GitHub Desktop.
Refactoring My Safari SQLite Local Database Example
<!DOCTYPE HTML>
<html>
<head>
<title>Safari SQLite - Factory And Service Objects</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="girl_service.js"></script>
<script type="text/javascript" src="factory.js"></script>
<script type="text/javascript">
// Create the application namespace and whatever cached
// components would be necessary. In our case, the Factory
// object provides access to cached Service and DAO classes.
var app = {
factory: new Factory({
fileName: "sqlite_helloWorld",
version: "1.0",
displayName: "SQLite Hello World",
maxSize: 1024
})
};
// -------------------------------------------------- //
// -------------------------------------------------- //
// When the DOM is ready, init the scripts.
$(function(){
// Get the form.
var form = $( "form" );
// Get the girl list.
var list = $( "#girls" );
// Get the Clear Girls link.
var clearGirls = $( "#clearGirls" );
// Get service class references. This is the class that
// provides encapsulated access to the girl database.
var girlService = app.factory.get( "GirlService" );
// I refresh the girls list.
var refreshGirls = function( results ){
// Clear out the list of girls.
list.empty();
// Check to see if we have any results.
if (!results){
return;
}
// Loop over the current list of girls and add them
// to the visual list.
$.each(
results.rows,
function( rowIndex ){
var row = results.rows.item( rowIndex );
// Append the list item.
list.append( "<li>" + row.name + "</li>" );
}
);
};
// Bind the form to save the girl.
form.submit(
function( event ){
// Prevent the default submit.
event.preventDefault();
// Save the girl.
girlService.saveGirl(
{
name: form.find( "input.name" ).val()
},
function(){
// Reset the form and focus the input.
form.find( "input.name" )
.val( "" )
.focus()
;
// Refresh the girl list.
girlService.getGirls( refreshGirls );
}
);
}
);
// Bind to the clear girls link.
clearGirls.click(
function( event ){
// Prevent default click.
event.preventDefault();
// Clear the girls
girlService.deleteGirls( refreshGirls );
}
);
// Refresh the girls list - this will pull the persisted
// girl data out of the SQLite database and put it into
// the UL element.
girlService.getGirls( refreshGirls );
});
</script>
</head>
<body>
<h1>
Safari SQLite - Factory And Service Objects
</h1>
<form>
Name:
<input type="text" name="name" class="name" />
<input type="submit" value="Add Girl" />
</form>
<h2>
Girls
</h2>
<ul id="girls">
<!-- To be populated dynamically from SQLite. -->
</ul>
<p>
<a id="clearGirls" href="#">Clear Girls</a>!
</p>
</body>
</html>
// Define the Factory class. This will take care of DAO and service
// class instantiations including dependency injection (you know,
// like ColdSpring).
;window.Factory = (function( $ ){
// I am the factory.
function Factory( databaseOptions ){
// Define the database options. When we create the local
// databse, we need to define the way it is opened or
// created.
this.databaseOptions = databaseOptions;
// Open a connection to the local database. This will be
// passed into any service object that requires it.
this.databaseConnection = openDatabase(
this.databaseOptions.fileName,
this.databaseOptions.version,
this.databaseOptions.displayName,
this.databaseOptions.maxSize
);
// Initialize the databse.
this.initDatabase();
// I am a cache of Service and DAO objects. The objects
// will be cached by their class name.
this.cache = {};
// -- Create cachable class instances. -- //
this.cache[ "GirlService" ] = new GirlService(
this.databaseConnection
);
}
// Define the class methods.
Factory.prototype = {
// I provide access to the cached class instances. For this
// demo, we are going to assume that all cached services are
// singletons - no transient objects.
get: function( className ){
return( this.cache[ className ] );
},
// I initiahze the database - creating the necessary tables
// if they do not exist. Since all the database interaction
// in Safari is asynchronous, this function allows a callback
// to be passed-in for success feedback.
initDatabase: function( callback ){
// Now that we have the databse connection, let's create
// our first table if it doesn't exist.
this.databaseConnection.transaction(
function( transaction ){
// Create our girls table if it doesn't exist.
transaction.executeSql(
"CREATE TABLE IF NOT EXISTS girls (" +
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
"name TEXT NOT NULL" +
");",
[],
function(){
// Check to see if a callback was
// provided for success feedback.
if (callback){
callback();
}
}
);
}
);
}
};
// ------------------------------------------------------ //
// ------------------------------------------------------ //
// Return the Factory class definition.
return( Factory );
})( jQuery );
// Define the girl service class.
;window.GirlService = (function( $ ){
// I am the girl service class.
function Service( database ){
// Store the database connection.
this.database = database;
};
// Define the class methods.
Service.prototype = {
// I delete all the girls.
deleteGirls: function( callback ){
// Get all the girls.
this.database.transaction(
function( transaction ){
// Delete all the girls.
transaction.executeSql(
(
"DELETE FROM " +
"girls " +
";"
),
[],
function(){
// Execute the success callback.
callback();
}
);
}
);
},
// I get all the girls.
getGirls: function( callback ){
// Get all the girls.
this.database.transaction(
function( transaction ){
// Get all the girls in the table.
transaction.executeSql(
(
"SELECT " +
"* " +
"FROM " +
"girls " +
"ORDER BY " +
"name ASC" +
";"
),
[],
function( transaction, results ){
// Return the girls results set.
callback( results );
}
);
}
);
},
// I save a girl.
saveGirl: function( values, callback ){
// Check to see if we are dealing with an existing girl
// or a new girl (based on the ID).
if (values.id){
// Update an existing girl.
this.database.transaction(
function( transaction ){
// Execute UPDATE command.
transaction.executeSql(
(
"UPDATE " +
"girls " +
"SET " +
"name = ? " +
"WHERE " +
"id = ? " +
";"
),
[
values.name,
values.id
],
function( transaction, results ){
// Execute the success callback.
callback( values.id );
}
);
}
);
} else {
// Insert a new girl.
this.database.transaction(
function( transaction ){
// Execute INSERT command.
transaction.executeSql(
(
"INSERT INTO girls (" +
"name " +
") VALUES ( " +
"? " +
");"
),
[
values.name
],
function( transaction, results ){
// Execute the success callback,
// passing back the newly created ID.
callback( results.insertId );
}
);
}
);
}
}
};
// ------------------------------------------------------ //
// ------------------------------------------------------ //
// Return the GirlService class definition.
return( Service );
})( jQuery );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment