PresentationW3C AC member
Wakanda Community
Web Architect
JS Expert
REST Lover
NoSQL Fanboy@amorgaut
NoSQL FactsMostly Schemaless
Often with REST / JSON API
Many store JSON
Many embed a JavaScript engine
Map / Reduce
events
Many propose a JavaScript Shell
JavaScript FactsCreated in 1995
Running in Netscape Server in 1996, and then in IIS
Mostly Event-Driven
Recommended in the REST definition in 2000
Integrated in CouchDB in 2007
HTML5 Datastores appeared in 2009
SpiderMonkey3 JIT Compilers: TraceMonkey, JägerMonkey, IonMonkey
V8JIT Compiler : CrankShaft
webkit JavaScriptCore: JSCSquirrelFish Extreme: SFX aka Nitro
(JIT Compiler inside)
Trident: MSHTMLChakra
-> Classic JScript, Managed JScript, & JScript.NET
TamarinJIT Compiler : NanoJIT
-> ActionScript / “ECMAScript 4”
CarakanPreviously: Linear A, Linear B, Futhark
RhinoInterpreted or Compiled execution
CC++
C++Java
?
?C++
Nashorn?
JavaScript Engines
JavaScript & Databases
Netscape Enterprise Server
Microsoft: JScript, JScript.NET, ActiveX
Mozilla Rhino
JSDB
APE Project
W3C Web SQL
Netscape Enterprise Server
SQLTable()
DbPool
start/home.html
Shared Connections
pool = new DbPool("ORACLE", addr, user, pwd, "", 5, true);connection = pool.connection("A connection");
cursor = connection.cursor("select name from customer");
if ( cursor && (connection.majorErrorCode() == 0) ) { // Get the first row cursor.next(); // Display the values write("<B>Customer Name:</B> " + cursor.name + "<BR>"); //Close the cursor cursor.close();}
Note: Netscape Enterprise Server merged with Javagator to become iPlanet
MS JScript on the server
Active Server Page
runat=”server”
Windows Script Hosting
.NET
conn = Server.CreateObject("ADODB.Connection");
conn.Open(dsn, login, password);
reccordset = conn.Execute(sqlQuery);result = [];
while (!reccordset.EOF) {
result.push({ field1: reccordset("field1"), field2: reccordset("field2") }); rsAuthor2.MoveNext; }
conn.Close();conn = null;
Note: JScript is running on Microsoft IIS since 1997
MS JScript in the Browser
ActiveXObject
only IE
var connection = new ActiveXObject("ADODB.Connection"); connection.Open(dsn, login, password);var reccordset = new ActiveXObject("ADODB.Recordset"); reccordset.Open(sqlQuery, connection);reccordset.MoveFirst;
while(!reccordset.eof) { document.write(reccordset.fields(1)); reccordset.movenext;} reccordset.close;connection.close;
Mozilla Rhino
Java environment
Access to JDBC
ex: RingoJS
importPackage(java.sql);java.lang.Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:test.db");stat = conn.createStatement();resultSet = stat.executeQuery("select * from people;");
while (resultSet.next()){ print( resultSet.getString("name") + " - " + resultSet.getString("occupation") );}
resultSet.close();stat.close();conn.close();
https://developer.mozilla.org/en-US/docs/Rhino
JSDB
SpiderMonkey
Shell
JS Server
var db = new ODBC(dsn);var result = db.query("select * from mytable");
var searcher = new Index;for (var i=1; i <= result.count; i++){ searcher.add(result.get('NAME'));}
var i = searcher.find('Mr. Smith');var r = result.getRow(i + 1);
writeln('Data for Mr. Smith');writeln(r.toString());
db.close();
http://www.jsdb.org/
APE Project
Real Time Web
Comet
Web Sockets
MySQL
var sql = new Ape.MySQL(ip + ":3306", user, password, db);
Ape.registerCmd('foo', true, function(params, cmd) {
cmd.user.sendRaw( 'bar', { hello: 'world', echo: params.ping } ); sql.query( 'INSERT INTO table(log) VALUES("' + Ape.MySQL.escape(params.ping) + '")', function(res, errorNo) { Ape.log('Inserted ' + this.getInsertId()); } );});
http://www.ape-project.org/
Note: APE means “Ajax Push Engine”
W3C Web SQL
HTML5
Safari
Chrome
Opera
Sync / Async
db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS foo (id unique, text)'); tx.executeSql('INSERT INTO foo (id, text) VALUES (1, "synergies")');});
http://html5doctor.com/introducing-web-sql-databases/
Note: standard paused because current implementations are only based on SQLite
var db = openDatabase('mydb', '1.0', 'my first db', 2 * 1024 * 1024);
result = x.executeSqlSync('SELECT * FROM foo');for (var i = 0, len = results.rows.length; i < len; i++) { alert(results.rows.item(i).text);}
tx.executeSql('SELECT * FROM foo', [], function (tx, results) { for (var i = 0, len = results.rows.length; i < len; i++) { alert(results.rows.item(i).text); }});
Key-Value: Web Storage, Riak
Document: CouchDB, MongoDB, IndexedDB
Object: JavaScriptDB, WakandaDB
Multi-Model: OrientDB & ArangoDB
Touching the DB Heart
Web Storage
W3C / WHATWG
HTML5
local
session
events
// set or get items by methodslocalStorage.setItem("storedItem", "value");var value = localStorage.getItem("storedItem");
http://www.w3.org/TR/webstorage/
// sync interface when data change, even from other windowwindow.addEventListener("storage", handle_storage, false);
// set or get items using the store as a maplocalStorage.storedItem = value;var value = localStorage.storedItem;
// accessible only for this sessionvar foo = sessionStorage.bar;sessionStorage.bar = foo;
Note: Firefox used to propose “globalStorage”, Wakanda implements “user.storage”
RiakBuckets
REST / JSON
Map / Reduce
Erlang alternative:
SpiderMonkey
// Map: compute the daily variance, key it by the monthfunction(value, keyData, arg){ var data = Riak.mapValuesJson(value)[0]; var month = value.key.split('-').slice(0,2).join('-'); var obj = {}; obj[month] = data.High - data.Low; return [ obj ];}
// Reduce: find the maximum variance per monthfunction(values, arg) { return [values.reduce(function(acc, item){ for (var month in item) { acc[month] = acc[month] ? Math.max(item[month], acc[month]) : item[month]; } return acc; })];}
{"inputs": "goog", "query": [ {"map": {"language": "javascript", "source": "function(value, keyData, arg){...}" }}, {"reduce": {"language": "javascript", "source": "function(values, arg){...}", "keep": true }} ]}
IndexedDBW3C / WHATWG
HTML5
Sync / Async
Indexes
Transactions
Cursors
request.onerror = function(event) { // Do something with request.errorCode!};request.onsuccess = function(event) { // Do something with request.result!};
http://www.w3.org/TR/IndexedDB/
var request = indexedDB.open("MyTestDatabase", 3);
request.onupgradeneeded = function(event) { // Update object stores and indices .... }
var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
objectStore.createIndex("name", "name", { unique: false });objectStore.add({ ssn: "444-44-4444", name: "Bill", age: 35});
var transaction = db.transaction(["customers"], IDBTransaction.READ_WRITE);
CouchDB
Views
JSON*
Map / Reduce
Erlang alternative:
Spidermonkey
function(doc) { if (doc.Type == "customer") { emit(doc.LastName, {FirstName: doc.FirstName, Addr: doc.Address}); emit(doc.FirstName, {LastName: doc.LastName, Addr: doc.Address}); }}
{ "total_rows":2, "offset":0, "rows": [ { "id":"64ACF01B05F53ACFEC48C062A5D01D89", "key":"Katz", "value":{"FirstName":"Damien", "Addr":"Charlotte NC"} }, { "id":"64ACF01B05F53ACFEC48C062A5D01D89", "key":"Damien", "value":{"LastName":"Katz", "Addr":"Charlotte NC"} }, ]}
http://wiki.apache.org/couchdb/HTTP_view_API
Note: CouchDB moved from XML to JSON & JS in 2007** http://jan.prima.de/~jan/plok/archives/89-CouchDb-updates.html
CouchBase
CouchDB alternative
using V8
adding memcache
meant to be more scalable
http://www.couchbase.com/
MongoDBSpidermonkey
BSON
Map / Reduce
REST / JSON
REST / JS
Shell
var map = function() { emit(this.author, {votes: this.votes});};
http://www.mongodb.org/display/DOCS/MapReduce
{ text: "lmao! great article!", author: 'kbanker', votes: 2}
// Add up all the votes for each key.var reduce = function(key, values) { var sum = 0; values.forEach(function(doc) { sum += doc.votes; }); return {votes: sum};};
var op = db.comments.mapReduce(map, reduce, {out: "mr_results"});
Persevere JavaScriptDB
Rhino
REST / JSON
JSON Schema
JSON Path
JSON Query
{"id":"generated.js","sources":[ { "name":"Data", "extends":"Object", "schema":{ "extends":{"$ref":"../Class/Object"}, hello : function() { console.log("hello hi"); }, "prototype":{ } } }]}
curl localhost:8080/Data/1
({"id":"1","test":12345})
Data.hello(); // INFO: hi there
var d = new Data();d.test = 12345;
http://www.sitepen.com/blog/2009/04/20/javascriptdb-perseveres-new-high-performance-storage-engine/
WakandaDBWebkit JavaScriptCore
REST / JSON
Data Classes
auto-updatable
accessors
events
methods
john = ds.Person.find("fistName eq John");
conferences = john.allConferences;
JohnJSConferences = conferences.filter("title eq :1", "*JavaScript*");
JSAttendeesJohnMet = JSConferences.allPeople;
http://wakanda.org/
ArangoDB
V8
events
filters
transactions
Shell
actions.defineHttp({ url : "world", context : "api", callback : function (req, res) { var collection = db._collection(req.parameter.collection); if (collection == null) { ... } else { ... } actions.resultOk(req, res, actions.HTTP_OK, result); }});
http://www.ape-project.org/
OrientDB
rhino
REST / JSON
transactions
hooks (events)
stored procedures
// create function getAllCustomerreturn db.query("select from V")
http://www.orientdb.org/
db.begin();try {" // some code" db.commit()} catch (e) {" db.rollback();"}
new com.orientechnologies.orient.core.record.impl.ODocument('Profile').field('name', 'Luca').save()
mongoose
mongodb-rhino
riak control
backbone-couchdb
dojox.data.couchDBRestStore
node-cassandra
WAF (Wakanda)
Ext.data.proxy.Wakanda
arango.client
voltdb-client-nodejs
redis-node-client
orientdb-api.js
Reaching the DB
Thank you!
@amorgaut
@wakandasoft
http://wakanda.org
@jseverywhere
http://jseverywhere.org
http://about.me/amorgaut http://w3.org/community/jseverywhere/
Client & Server JavaScript APIs
Let’s keep in touch...