I had the privilege of giving a Yahoo! Tech Talk at their HQ in Sunnyvale. I spoke on Gears, App Engine, and other technologies such as the Ajax Libraries API and Doctype.
16. What is the philosophy?
Do for offline what XMLHttpRequest did for web apps
Ajax Libraries Gears Libraries
Dojo, jQuery, Prototype, GWT Dojo Offline, GWT
XMLHttpRequest Gears
Open Web Open Web
17. Database
Embedded using SQLite
Contributed Full Text Search
var db = google.gears.factory.create('beta.database', '1.0');
db.open('database-demo');
db.execute('create table if not exists Demo (Phrase varchar(255),
Timestamp int)');
db.execute('insert into Demo values (?, ?)', [phrase, currTime]);
18. GearsDB
Abstract over the API
var bob = {id: 3, name: 'Bob', url: 'http://bob.com', description: 'whee'};
db.insertRow('person', bob);
db.insertRow('person', bob, 'name = ?', ['Bob']);
db.selectAll('select * from person', null, function(person) {
document.getElementById('selectAll').innerHTML += ' ' + person.name;
});
var person = db.selectRow('person', 'id = 1');
// update
person.name = 'Harry';
db.updateRow('person', person);
person = db.selectRow('person', 'id = 1');
// force
person.name = 'Sally';
db.forceRow('person', person);
person = db.selectRow('person', 'id = 1');
db.deleteRow('person', bob);
19. GearsORM
Are we going to get a GearsHibernate?
var Person = new GearsOrm.Model(quot;Personquot;, {
firstName: GearsOrm.Fields.String({maxLength:25}),
lastName: GearsOrm.Fields.String({maxLength:25})
});
GearsORM.Transaction(function() { “While developing transaction support for
new Person({name:quot;Johnquot;}).save(); GearsORM i had to write a test, in that test it
execute 100 inserts and 100 updates, this test take
new Person({name:quot;Doequot;}).save(); about 15 seconds for the inserts and about 10
seconds for the updates without transactions,when
}); using transactions for each set it takes about
377ms for the inserts and 200ms for the
updates that is about
Person.select(quot;firstName = 'Uriel'quot;); 39 times faster!”
Person.count(quot;lastName = ?quot;,[quot;Katzquot;])
20. GearShift
DB Migrations for Gears
Gearshift.rules[1] = {
// create the demo table
up: function() {
return this.e(quot;CREATE TABLE demo_table (
id INTEGER PRIMARY KEY
AUTOINCREMENT,
name VARCHAR(30),
movie VARCHAR(30)
)quot;).success;
},
down: function() {
return this.e(quot;DROP TABLE demo_tablequot;).success;
}
};
23. Full Text Search
• Gears added FTS2 to SQLite
• Create the database
db.execute('CREATE VIRTUAL TABLE recipe USING fts2
(dish, ingredients)');
• Search the database
db.execute('SELECT dish FROM recipe WHERE recipe
MATCH ?', ['tomatoes']);
Fun queries: dish:stew tomatoes
Find rows with 'stew' in the dish field, and 'tomatoes' in any field.
28. ManagedResourceStore
JSON Me
{
// version of the manifest file format
quot;betaManifestVersionquot;: 1,
// version of the set of resources described in this manifest file
quot;versionquot;: quot;my_version_stringquot;,
// optional
// If the store specifies a requiredCookie, when a request would hit
// an entry contained in the manifest except the requiredCookie is
// not present, the local server responds with a redirect to this URL.
quot;redirectUrlquot;: quot;login.htmlquot;,
// URLs to be cached (URLs are given relative to the manifest URL)
quot;entriesquot;: [
{ quot;urlquot;: quot;main.htmlquot;, quot;srcquot;: quot;main_offline.htmlquot; },
{ quot;urlquot;: quot;.quot;, quot;redirectquot;: quot;main.htmlquot; },
{ quot;urlquot;: quot;main.jsquot; }
{ quot;urlquot;: quot;formHandler.htmlquot;, quot;ignoreQueryquot;: true },
]
}
29.
30. HTML 5
Offline in General
<html application=”manifest-of-urls.txt”>
<html application>
“There’s a concept of an application cache. An application cache is a group
of resources, the group being identified by a URI (which typically happens
to resolve to a manifest). Resources in a cache are either top-level or
not; top-level resources are those that are HTML or XML and when parsed
with scripting disabled have with the value of
the attribute pointing to the same URI as identifies the cache.
When you visit a page you first check to see if you have that page in a
cache as a known top-level page.”
31. Future
Present
Ab
l
edg eeding
ev
of H ersion
TML
Past 5!
HTML 5 Gears
• Standards • Implementation
• Long term • Battle hardened
• All browsers • A place for innovation
• Cross browser
• No plugin • Plugin
32. Mouse Moved
Mouse Pressed
Mouse Released
Key Pressed
Operating System Key Released
Event Queue
al
enti ck
Pot lene
t
Bot
JavaScript Web Browsing
Browser
34. Worker Pool Code
function nextPrime(n) {
// TODO: New top-secret prime-finding algorithm goes here.
google.gears.workerPool.sendMessage(result);
}
var pool = google.gears.factory.create('beta.workerpool', '1.0');
pool.onmessage = function(message) {
alert('next prime is: ' + message);
}
var worker = pool.createWorker(String(nextPrime) + '; nextPrime()');
38. Notification API
Growl for the Web
var notifier = google.gears.factory.create('beta.notifier', '1.0');
notifier.notify({
application: quot;My Appquot;,
title: 'warning',
description: 'some text',
priority: 2,
sticky: 'True',
password: 'Really Secure',
});
39. Location API
Even on a laptop?
// Getting the object
var location = google.gears.factory.create( quot;beta.locationquot;, quot;1.0quot; );
// Setting up a callback to handle quot;location changedquot; events
location.onlocationstatechanged = function() {
if (this.state == COMPLETE) {
SetStatusText(quot;Location accuracy:quot;, this.accuracy);
MoveMap(this.latitude, this.longitude);
}
}
location.startLocationUpdates();
40. Audio API
Play and Record
// play
var audio = google.gears.factory.create('beta.audio');
audio.src = 'http://blahblahblob.com/sampleaudio.wav';
audio.load();
audio.play();
// record
var recorder = google.gears.factory.create('beta.audiorecorder');
recorder.destination = <http post url>
recorder.autoStream = true;
recorder.record(); //asynchronous call
41. File System API
Blob API
Resumable HTTP
Don’t you want a better File Upload?
46. Google App Engine
Running Web Apps on Google’s Infrastructure
• Fully-integrated
application environment
• Language agnostic runtime
Python for now
• Free quota of 5M
pageviews per month
code.google.com/appengine
60. Data Model
Just an object
from google.appengine.ext import db
class Story(db.Model):
title = db.StringProperty()
body = db.TextProperty(required=True)
author = db.UserProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
rating = db.RatingProperty()
# Many other types: BlobProperty, ReferenceProperty, EmailProperty, PhoneProperty, IMProperty,
PostallAddressProperty, etc.
61. GQL
Our query language
SELECT *
FROM Story
WHERE title = 'App Engine Launch'
AND author = :current_user
AND rating >= 10
ORDER BY rating, created DESC
62. Run the queries
Beyond GQL
Story.gql(GQL_FROM_BEFORE,
current_user = users.get_current_user())
query = Story.all()
query.filter('title =', 'Foo')
.order('-date')
.ancestor(key)
63. Inserts
Manipulating the data
story = Story(
title = 'Morning Glory',
body = '....',
author = users.get_current_user(),
)
story.put() # save or update
story.delete() # delete if saved
67. Users API
But you can do your own thing too of course...
from google.appengine.api import users
current_user = users.get_current_user()
if not current_user:
self.redirect(users.create_login_url('/
current_url'))
nickname = current_user.nickname()
email = current_user.email()
if users.is_current_user_admin():
...
73. Memcache API
In-memory distributed cache
from google.appengine.api import memcache
def get_data():
data = memcache.get(quot;keyquot;)
if data is not None:
return data
else:
data = self.query_for_data()
memcache.add(quot;keyquot;, data, 60)
return data
# Set several values, overwriting any existing values for these keys.
memcache.set_multi({ quot;USA_98105quot;: quot;rainingquot;,
quot;USA_94105quot;: quot;foggyquot;,
quot;USA_94043quot;: quot;sunnyquot; },
key_prefix=quot;weather_quot;, time=3600)
# Atomically increment an integer value.
memcache.set(key=quot;counterquot;, 0)
memcache.incr(quot;counterquot;)
memcache.incr(quot;counterquot;)
memcache.incr(quot;counterquot;)
74. Google App Engine
Areas of Work, Including…
• Offline Processing
• Rich Media Support
– e.g., large file upload / download
• Add’l Infrastructure Services
• What would you like to see?
74
81. What if popular JavaScript libraries
were available and shared in the browser?
1 Now hosting open source JavaScript libraries at Google
Starting with: Prototype, Script.aculo.us, jQuery, Dojo, Mootools
Accepting requests for other open source libraries
Can access directly:
ajax.googleapis.com/ajax/lib/prototype?v=1.6.0.2&packed=false
Can access via AJAX API Loader:
google.load(“prototype”, “1.6”);
2 Other features
Automatic compression
Minification of libraries
Not tied to Google Code