My Ubuntu Touch App Showdown app, Word Chain uses the U1DB database to store data. This is because it’s very easy to use in a QML app, much easier than SQL. Word Chain does not do any complicated data handling, it just needs to remember the state of everything. The official (in-progress) documentation for U1db in Ubuntu Touch apps is at http://developer.ubuntu.com/api/devel/ubuntu-13.10/qml/u1db-qt5/concepts.html. So here is an example of how U1DB works in Ubuntu Touch apps so other people can use it.

Pretend we have a “guess the number” game. Here is a very small silly QML game to guess a number between 1 and 100.

import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { id: main; width: units.gu(40); height: units.gu(68) property int number: 0 Page { title: "Guess the number" Column { anchors.centerIn: parent; width: parent.width * 0.75 Label { id: lbl; text: "Enter your guess" } Rectangle { color: "white"; height: units.gu(4); width: parent.width

TextInput { id: ti; anchors.fill: parent }

} Button { text: "Guess" onClicked: { var num = parseInt(ti.text, 10); if (isNaN(num)) { lbl.text = "Guessed " + ti.text + ": wrong"; } else if (num < main.number) {

lbl.text = "Guessed " + ti.text + ": too low!"; } else if (num > main.number) { lbl.text = "Guessed " + ti.text + ": too high!"; } else if (num == main.number) { lbl.text = "Correct!"; } } } } } Component.onCompleted: main.number = Math.floor(Math.random() * 100) }

Now we want to save the number so that the game can continue when reloaded. The way to do this is to store the number to guess in a database, of course. U1DB makes this easy because it’s very QML-like.

First, create a document to store the number in, and a database to store that document in!

import U1db 1.0 as U1db U1db.Database { id: db path: "guess.u1db" } U1db.Document { id: number_doc database: db docId: "save_number" create: true defaults: { "number": -1 } }

Now there’s a document. Its “id” is the QML id: that’s how you’ll refer to it everywhere. The “docId” is how U1db knows the document internally. We’ve defined this document declaratively, so it will be created if it doesn’t exist, and if it does exist it’ll be left alone (so it’ll get created the first time we run the app, and after that it’ll stay as it is). A new document is created with the values in “defaults” as its content.

What we want to do then is, when the game starts, look at that document; if it contains { number: -1 } then this must be the first time we’ve started, and so set it to a number to guess. If the document contains a number, then the user must be trying to guess that number, so use it!

All we need for that is an onCompleted handler for the document which sets the number if it’s -1:

U1db.Document { id: number_doc ... Component.onCompleted: { if (number_doc.contents.number == -1) { number_doc.contents = {number: Math.floor(Math.random() * 100)} } } }

and of course our “did you get the number right” code now needs to look at the value in the document, not a variable set on main.

var num = parseInt(ti.text, 10); if (isNaN(num)) { lbl.text = "Guessed " + ti.text + ": wrong"; } else if (num < number_doc.contents.number) { lbl.text = "Guessed " + ti.text + ": too low!"; } else if (num > number_doc.contents.number) { lbl.text = "Guessed " + ti.text + ": too high!"; } else if (num == number_doc.contents.number) { lbl.text = "Correct! Now guess the new number"; number_doc.contents = {number: Math.floor(Math.random() * 100)} }

And if you get the number right, we set a new number. That’s all there is: you’ll see that you can just read the values from some_u1db_doc.contents and they’ll be saved correctly between program runs: you don’t need to explicitly call a “save” function at all.

There is an important “caveat”, though: you have to set all of a document’s contents at once. That is, if you’ve got a document with contents {number: 5} then you can change the value of number by setting all the contents: doc.contents = {number:6} but you cannot set individual bits of the contents: doc.contents.number = 6 will not work.

U1DB does a lot of other stuff such as querying and syncing between devices (so you can play a game on two devices and they’ll both remember where you got to) but I find it really easy just to store data, and then I have the option to add syncing later.

Word Chain uses U1DB for all its data saving; we save the word that’s currently being displayed, the history of words in this game, and all the challenge words that you have so far guessed. What I like about this is that it’s very nearly as easy to save these values in U1DB as it is to save them just in a variable, and you automatically get the data persisted if your app closes and reopens. Doing that with SQL is really annoying: you have to construct a SQL statement to save things and so on. With U1DB, just create a document and use it as a place to store all your variables, and then your app automatically works when you shut down and start up again, or crash, or get closed.

Full code for this example: