Mobile applications Development - Lecture 13
Local/Session Storage
WebSQL
IndexedDB
File System Access
This presentation has been developed in the context of the Mobile Applications Development course at the Computer Science Department of the University of L’Aquila (Italy).
http://www.di.univaq.it/malavolta
Handwritten Text Recognition for manuscripts and early printed texts
Local Storage and File System Guide
1. Local Storage
Ivano Malavolta
ivano.malavolta@univaq.it
http://www.di.univaq.it/malavolta
2. Roadmap
• Introduction
• Web Storage
• WebSQL
• IndexedDB
• File System Access
• Final Considerations
3. Introduction
There are 4 ways to store data locally
• Web storage
– Local Storage
– Session Storage
• WebSQL
• Indexed DB
• File System Access
4. Web Storage
LocalStorage
stores data in key/value pairs
persists across browser sessions
SessionStorage
stores data in key/value pairs
data is erased when a browser session ends
5. Introduction
WebSQL Database
relational DB
support for tables creation, insert, update, …
transactional
persists across browser sessions
Its evolution is called IndexedDB but it is actually
IndexedDB,
not supported by most mobile browsers
6. Introduction
File System Access
you can access files locally to your app
supports main FS operations
– files creation, move, delete, rename, creation, etc.
it is not transactional
persists across browser sessions
8. Roadmap
• Introduction
• Web Storage
• WebSQL
• IndexedDB
• File System Access
• Final Considerations
9. Web Storage
It is based on a single persistent object called
localStorage
You can set values by calling
window.localStorage.setItem(“name”, “Ivano”);
You can get values back by calling
var name = window.localStorage.getItem(“name”);
10. Supported Methods
localStorage.key(0)
Returns the name of the key at the position specified
getItem(“key”)
Returns the item identified by it's key
setItem(“key”, “value”)
Saves and item at the key provided
removeItem(“hey”)
Removes the item identified by it's key
clear()
Removes all of the key value pairs
11. Complex Objects
Current implementations support only string-to-string
mappings
you can store only strings
keys can be only strings
You can use JSON serialization if you need to store
complex data structures
12. Example of JSON Serialization
// simple class declaration
function Person(name, surname) {
this.name = name;
this.surname = surname;
}
// object creation
var user = new Person(‘Ivano’, ‘Malavolta’);
// object serialization
window.localStorage.setItem(“user”, JSON.stringify(user));
// object retrieval
var current =
JSON.parse(window.localStorage.getItem(“user”));
13. Checking Existence
You can simply check if the needed element is == null
if (window.localStorage.getItem(“user”)) {
// there is an object in user
} else {
// the user key does not have any value
}
14. Selecting elements
In this case you have to manually iterate on elements
var users = [...]; // array of Person objects
window.localStorage.setItem(“users”,
JSON.stringify(users));
var allUsers =
JSON.parse(window.localStorage.getItem(“users”));
var ivanos = [];
for(var i=0; i<allUsers.length; i++) {
if(allUsers[i].name == ‘Ivano’)
ivanos.push(allUsers[i]);
}
15. Counting Elements
Also in this case, we have to do it manually
var usersNumber =
JSON.parse(window.localStorage.getItem(“users“)).length;
16. Session Storage
Session Storage provides the same interface as Local
Storage
you can call the same methods
but
Session Storage is cleared between app launches
17. Roadmap
• Introduction
• Web Storage
• WebSQL
• IndexedDB
• File System Access
• Final Considerations
18. WebSQL
It provides you a structured SQL relational database
You have to setup a DB schema
You can then perform classical SQL queries
tx.executeSql("SELECT * FROM User“, [],
function(tx, result) {
// callback code
});
19. Opening a DB
Done via a dedicated function
var db =
openDatabase(‘Test', ‘1.0', ‘Test DB', 100000);
It creates a new SQLLite DB and returns a new
Database object
The Database object will be used to manipulate the data
20. Opening a DB: syntax
openDatabase(name, version, displayname, size);
DB name
the name of the DB
DB version
the version of the DB
DB Display name
the display name of the DB
DB Size
the size of the DB in bytes
21. Database
It allows to manipulate the data via 2 methods:
changeVersion
atomically verify the version number and change it
db.changeVersion("1.0", "1.1");
transaction
performs a DB transaction
22. Transactions
It allow you to execute SQL statements against the DB
db.transaction(queries, error, success);
3 callback functions:
queries : contains the queries to be performed
error : executed if the transaction results in an error
success : executed if the transaction terminates correctly
24. executeSql
It is the method that performs a SQL statement
The user can build up a database transaction by calling
the executeSql method multiple times
function populateDB(tx) {
tx.executeSql('DROP TABLE IF EXISTS USER');
tx.executeSql('CREATE TABLE IF NOT EXISTS USER (id
unique, name, surname)');
tx.executeSql('INSERT INTO USER(id, name, surname)
VALUES (1, ?, ?)‘, [“Ivano“, “Malavolta“],
success, error);
}
25. Result Sets
When the executeSql method is called, it will invoke it's
callback with a SQLResultSet parameter
It has 3 properties:
insertId
the ID of the row that has been inserted
rowsAffected
the number of rows changed by the SQL statement
rows
the data returned from a SQL select statement
rows is an object of type SQLResultSetList
26. Results Sets Example
...
tx.executeSql('INSERT INTO USER(id, name,surname)
VALUES (1, ?, ?)‘, [“Ivano“, “Malavolta“],
success, error);
}
function success(tx, results) {
var affected = results.rowsAffected(); // 1
}
function error(err) {
// code for managing the error
}
27. Result Set Lists
It contains the data returned from a SQL Select statement
length
the number of rows returned by the SQL query
item(index)
returns the row at the specified index represented by a
JavaScript object
28. Result Set List Example
...
tx.executeSql(‘SELECT * FROM USER‘, [],
success, error);
}
function success(tx, results) {
var size = results.rows.length;
for (var i=0; i<size; i++){
console.log(results.rows.item(i).name);
}
}
29. Errors
It contains information about an occurred error
code
A predefined error code
es. UNKNOWN_ERR, DATABASE_ERR, TOO_LARGE_ERR,
QUOTA_ERR, SYNTAX_ERR, TIMEOUT_ERR
message
A description of the error
30. Error Code Example
...
tx.executeSql(‘SELECT * FROM USER‘,[],
success, error);
}
function error(err) {
console.log(err.code);
}
31. Roadmap
• Introduction
• Web Storage
• WebSQL
• IndexedDB
• File System Access
• Final Considerations
32. Indexed DB
It tries to combine Web Storage and WebSQL
You can save data as key/value pairs
key/value
You can define multiple DBs
Good Performance
data is indexed
asynchronous it does not block the UI
33. Indexed DB
An Indexed DB is a collection of object stores
You can drop objects into the stores
You can see stores as a big SQL table with only
key/value
key/value pairs
you don’t need to define a schema upfront
34. Roadmap
• Introduction
• Web Storage
• WebSQL
• IndexedDB
• File System Access
• Final Considerations
35. File System Access
It allows you to read, write and navigate file system
hierarchies
It is fundamental for managing and storing large files
client-
and binary content on the client-side
36. File System Access Workflow
1. Request file system access
– persistent or temporary file system
2. then you can perform CRUD operations for both
files and folders:
– Create
– Read
– Update
– Delete
37. Request File System
requestFileSystem(type, size, successCb, [errorCb])
type
LocalFileSystem.TEMPORARY
LocalFileSystem .PERSISTENT
size
size in bytes the app will require for storage.
successCb
success callback, its argument is a FileSystem object
ErrorCb
error callback, its argument is a FileError object
38. Temporary VS Persistent
Temporary
the files stored by the app can be deleted at the
browser’s discretion
no guarantee of persistence
Persistent
cannot be deleted by the browser without
authorization by the app
39. Local File System Example
window.requestFileSystem(
LocalFileSystem.PERSISTENT,
0,
onSuccess,
onError);
function onSuccess(fileSystem) {
console.log(fileSystem.name);
}
40. File System
The FileSystem object has 2 properties:
name
the name of the file system
it is unique across the list of exposed file systems
root
the DirectoryEntry object representing the root
folder of the file system
41. Resolving a File URI
resolveLocalFileSystemURI
retrieve a DirectoryEntry or FileEntry using a URI
window.resolveLocalFileSystemURI(
"file:///userImg.png", onSuccess, onError);
function onSuccess(fileEntry) {
console.log(fileEntry.name);
}
42. Entities
FileEntry
The real objects
DirectoryEntry
File Descriptor
FileReader
FileWriter Writing & Reading objects
DirectoryReader
43. File Entry
It represents a file on a file system
isFile (boolean)
Always true
isDirectory (boolean)
Always false
name (DOMString)
the name of the FileEntry, excluding the path
fullPath (DOMString)
the full absolute path from the root
44. File Entry Methods
getMetadata(success,
getMetadata(success, fail)
Look up metadata about a file
moveTo(parentEntry, newName, success, fail)
moveTo( parentEntry, newName,
Move a file to a different location on the file system
copyTo(parentEntry, newName, success, fail)
copyTo(parentEntry, newName,
Copy a file to a different location on the file system
toURI()
toURI()
Return a URI that can be used to locate a file
45. File Entry Methods
remove(success, fail)
Delete a file
getParent(success,
getParent(success, fail)
Look up the parent directory
createWriter(success,
createWriter(success, fail)
Creates a FileWriter object that can be used to write
to a file
file(success, fail)
Creates a File object containing file properties
46. File
It contains attributes of a single file
name (DOMString)
The name of the file
fullPath (DOMString)
The full path of the file including the file name
type (DOMString)
The mime type of the file
lastModifiedDate (Date)
The last time the file was modified
size (long)
The size of the file in bytes
48. Directory Entry Methods
getMetadata(success,
getMetadata(success, fail)
Look up metadata about a directory
moveTo(parentEntry, newName,
moveTo(parentEntry , newName, success, fail)
Move a directory to a different location on the file system
copyTo(parentEntry, newName,
copyTo(parentEntry, newName, success, fail)
Copy a directory to a different location on the file system
toURI()
toURI()
Return a URI that can be used to locate a directory
49. Directory Entry Methods
getParent(success, fail)
getParent(success,
Look up the parent directory
createReader()
createReader()
Creates a DirectoryReader object that can be used to read a
directory
getDirectory(path, options, success, fail)
getDirectory(path,
Create or look up a directory
options:
create (true | false)
exclusive (true | false)
50. Directory Entry Methods
getFile(path, options, success, fail)
getFile(path,
Create or look up a file within the directory
options:
create (true | false)
exclusive (true | false)
removeRecursively(success, fail)
removeRecursively(success,
Delete a directory and all of its contents
51. File Reader
It is used to read the contents of a file
Files can be read as text or as a base64 data encoded
string
You can also abort() e file reading activity
You can register your own event listeners to receive
the following events:
loadstart, progress, load, loadend, error, abort
52. File Reader Example
entry.file(win, fail);
function win(file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
console.log(evt.target.result);
};
reader.readAsText(file);
// reader.abort();
};
function fail(evt) {
console.log(error.code);
};
53. File Writer
It is used to write to a file
The data to be written must be UTF-8 encoded
UTF-
You can register your own event listeners to receive
the following events:
writestart, progress, write, writeend, error, abort
54. File Writer
A FileWriter is created for a single file
You can use it to write to a file multiple times
the FileWriter maintains the file's position and length
attributes, so you can seek and write anywhere in the file
By default, the FileWriter writes to the beginning of the file
(will overwrite existing data)
Set the optional append boolean to true in
the FileWriter's constructor to begin writing to the end
of the file
55. File Writer Methods
abort()
Aborts writing file
seek(byte)
Moves the file pointer to the byte specified.
truncate(length)
Shortens the file to the length specified.
write(data)
Writes data to the file
56. File Writer Example
entry.createWriter(win, fail);
function win(writer) {
writer.onwrite = function(evt) {
console.log(“ok");
};
writer.write(“Ivano Malavolta");
};
function fail(evt) {
// error management
};
57. Directory Reader
It is an object that lists files and directories in a
directory
it has only one method:
readEntries(success,
readEntries(success, fail)
Read the entries of the directory
58. Directory Reader Example
var directoryReader = dirEntry.createReader();
directoryReader.readEntries(success, fail);
function success(entries) {
var i;
for (i=0; i<entries.length; i++) {
console.log(entries[i].name);
}
}
function fail(error) {
console.log(error.code);
}
59. A Final Example:
Looking for a file and reading it
window.requestFileSystem(window.PERSISTENT, 0, initFS,
error);
function initFS(fs) {
fs.root.getFile(‘log.txt', {}, win, error);
}
function win(fileEntry) {
fileEntry.file(read, error);
}
function read(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
console.log(this.result);
};
reader.readAsText(file);
}
function error(err) { console.log(err);}
60. Roadmap
• Introduction
• Web Storage
• WebSQL
• IndexedDB
• File System Access
• Final Considerations
61. Final Considerations
You will likely use all of them in combination
Use the right API for the right job
Web Storage
• it is not transactional race conditions
• very simple API, no schema
• only String data performance issues for complex data
due to JSON serialization
• session storage will be cleared after the app is closed
• 5Mb quota
62. Final Considerations
WebSQL
• SQL-based fast and efficient
• transactional more robust
• asynchronous does not block the UI
• rigid data structure data integrity vs agility
• 5Mb quota
63. Final Considerations
IndexedDB
• simple data model easy to use
• transactional more robust
• asynchronous does not block the UI
• good search performance indexed data
• data is unstructured integrity problems
• 5Mb quota
64. Final Considerations
File System
• asynchronous does not block the UI
• not transactional
• indexing and search are not built-in
you have to implement your lookup functions
• unlimited storage
– useful for images, videos, documents, etc.