Для начала давайте разберемся, что такое Depot и зачем он может понадобиться в приложениях для Palm WebOS.

Если ваше приложение должно хранить данные, то в таком случае есть три варианта:

  • Использование Cookies
  • Использование базы данных SQLite
  • Использование Depot

Но в каких же случаях есть смысл использовать каждый из перечисленных вариантов? Если необходимо сохранить небольшой объем данных, например настройки приложения, то лучше использовать Cookies. Если же объем данных относительно большой, то выбор должен быть сделан в пользу одного из оставшихся способов. Какой из них лучше?

Что лучше использовать – зависит от объема данных, которые нужно хранить, а также от того, где вы будете хранить эти данные. Если вы используете хранилище по умолчанию (кстати Depot переводится как “хранилище” или “склад”), то у вас объем данных будет ограничен одним мегабайтом.

Если вам необходимо хранить данные в структурированном виде, то лучше сделать выбор в пользу базы данных SQLite.

Кстати, ограничение на 1 МБ данных можно обойти, разместив хранилище на разделе с медиа. В этом случае размер хранилища будет ограничен только объемом свободной памяти на это мразделе.

В чем же отличие Depot от базы данных SQLite? Depot может хранить только объекты. Например сделать так чтобы хранилась только булевая переменная не получится, нужно обязательно сделать объект и эту булевую переменную указать в виде свойства.

{ "value" : true }

Тоесть, что получается: Depot – это неструктурированное хранилище объектов. На самом деле это просто еще один уровень абстракции над API по работе с базами данных SQLite, но он позволяет избавиться от необходимости писать SQL в коде, что довольно удобно.

Перед тем, как рассматривать пример использования Depot, давайте создадим каркас приложения и потом в него уже будем добавлять необходимый функционал:

app/views/main/main-scene.html

<div id="main" class="palm-hasheader">
  <div class="palm-header">Depot Test</div>
  <div id="AddSceneButton" x-mojo-element="Button"></div>
  <div id="info" x-mojo-element="x-body-text"></div>
</div>

app/assistants/main-assistant.js

function MainAssistant() {
}

MainAssistant.prototype.setup = function() {
  this.controller.setupWidget("AddSceneButton", {}, {label:"Add"});
  Mojo.Event.listen(this.controller.get("AddSceneButton"),
    Mojo.Event.tap,
    this.handleAddSceneButton.bind(this));
}

MainAssistant.prototype.handleAddSceneButton = function(event) {
  this.controller.stageController.pushScene("add");
}

app/views/add/add-scene.html

<div id="main" class="palm-hasheader">
  <div class="palm-header left" id="list-header">
    Add / replace data
  </div>
</div>
<div class="palm-group">
  <div class="palm-group-title"><span x-mojo-loc="">Database Info.</span></div>
    <div class="palm-list">
      <div class='palm-row first'>
        <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
          <div class="title">
            <div class="label">Key</div>
            <div id="keyField" name="keyField" x-mojo-element="TextField" ></div>
          </div>
        </div>
      </div>
      <div class='palm-row last'>
        <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
          <div class="title">
            <div class="label">Text</div>
            <div id="textField" name="textField" x-mojo-element="TextField" ></div>
          </div>
        </div>
      </div>
    </div>
</div>
</div>
<div id="depotResult" class="info-text"></div>
<div x-mojo-element="Button" id="add_button"></div>
<div x-mojo-element="Button" id="back_button"></div>

app/assistants/add-assistant.js

function AddAssistant() {
}

AddAssistant.prototype.setup = function() {
  this.controller.setupWidget('keyField',
    {
      hintText:       'Enter key here',
      modelProperty:  'originalValue',
      textCase:       Mojo.Widget.steModeLowerCase,
      focus:          true,
      maxLength:      30
    },
    {
      originalValue : ''
    });
  this.controller.setupWidget('textField',
    {
      hintText:       'and some text here',
      modelProperty:  'originalValue',
      textCase:       Mojo.Widget.steModeLowerCase,
      multiline:      false,
      focus:          false,
      maxLength:      30
    },
    {
      originalValue : ''
    });
  this.controller.setupWidget("add_button", {}, {label:"Add entry"});
  this.controller.setupWidget("back_button", {}, {label:"Back to main view"});

  Mojo.Event.listen(this.controller.get("add_button"),
    Mojo.Event.tap, this.handleAddButton.bind(this));
  Mojo.Event.listen(this.controller.get("back_button"),
    Mojo.Event.tap, this.handleBackButton.bind(this));
}

AddAssistant.prototype.cleanup = function() {
  this.controller.stopListening(
    this.controller.get('add_button'), Mojo.Event.tap,
    this.handleAddButton);
  this.controller.stopListening(
    this.controller.get('back_button'), Mojo.Event.tap,
    this.handleBackButton);
}

AddAssistant.prototype.deactivate = function(event) {
}

AddAssistant.prototype.handleAddButton = function(event) {
}

AddAssistant.prototype.handleBackButton = function(event) {
  this.controller.stageController.popScene();
}

На главной форме у нас находится кнопка Add, которая вызывает сцену, в которой можно добавить новые записи в Depot.
Форма добавления новых записей содержит заголовок, группу из двух текстовых полей и две кнопки – кнопку добавления новой записи и кнопку закрытия сцены.
WebOS Depot Test

Ну вот, GUI готово, теперь можем начинать работу с Depot.

function MainAssistant() {
  var options = {
    name: "depot_tutorial", //Название хранилища (обязательный параметр)
    version: 1, //Версия базы данных. (опционально, по умолчанию 1)
    replace: false // открывать существующее хранилище
  };
  this.depot = new Mojo.Depot(options,
    this.dbConnectionSuccess.bind(this),
    this.dbConnectionFailure.bind(this));
}

MainAssistant.prototype.dbConnectionSuccess = function() {
    this.controller.get("info").update('OK');
}

MainAssistant.prototype.dbConnectionFailure = function() {
    this.controller.get("info").update('Error');
}

При создании объекта Depot можно указать методы, которые будут отрабатывать при успешном подключении к хранилищу или же при ошибке подключения.

Если надо создать хранилище на разделе с медиа, то название хранилища будет выглядеть так:

name: "ext:depot_tutorial"

У нас есть сцена, в которой должно происходить добавление объектов в Depot. Нам надо передать в нее объект Depot в качестве параметра. Сделать это можно вот как:
app/assistants/main-assistant.js

MainAssistant.prototype.handleAddSceneButton = function(event)
{
    this.controller.stageController.pushScene("add", this.depot);
}

app/assistants/add-assistant.js

function AddAssistant(arg) {
    this.depot = arg;
}

Мы передаем объект Depot в качестве параметра pushScene() и этот объект будет получен сценой как параметр конструктора.
Теперь нам необходимо написать обработчик кнопки add_button, в котором значение из текстового поля TEXT будет добавляться в хранилище с ключем KEY.

AddAssistant.prototype.handleAddButton = function(event) {
    this.data = { "value" :this.textModel.originalValue };
    this.depot.simpleAdd(this.keyModel.originalValue,
        this.data, this.dbAddSuccess, this.dbAddFailure);
}

AddAssistant.prototype.dbAddSuccess = function(event) {
    this.depotResult.innerHTML = ("Add success!");
}

AddAssistant.prototype.dbAddFailure = function(event) {
    this.depotResult.innerHTML = ("Add failure!");
}

В обработчике кнопки Add мы создаем объект, в нем в свойстве value запоминаем введенный текст и затем записываем в Depot. Запись происходит путем вызова метода simpleAdd(), в котором мы указываем ключ, сохраняемый объект, а также два callback-метода, которые будут вызваны при удачном или неудачном завершении операции записи.

И вот, мы научились добавлять объекты в Depot. Теперь попробуем научиться их оттуда доставать.

Создадим новую сцену с названием get.

app/views/get/get-scene.html

<div id="main" class="palm-hasheader">
  <div class="palm-header left" id="list-header">
    Retrieve data
  </div>
</div>
<div class="info-text">Which data entry you want to get?</div>

<div class="palm-group">
<div class="palm-group-title">Enter key string</div>
  <div class="palm-list">
    <div class="palm-row single">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div id="entryNum" x-mojo-element="TextField" ></div>
        </div>
      </div>
    </div>
  </div>
</div>
<div id="response" class="info-text"></div>
<div x-mojo-element="Button" id="get_button"></div>
<div x-mojo-element="Button" id="back_button"></div>

app/assistants/get-assistant.js

function GetAssistant(arg) {
    this.depot = arg;
}

GetAssistant.prototype.setup = function() {
    this.controller.setupWidget("get_button", {}, {label:"Get value"});
    this.controller.setupWidget("back_button", {}, {label:"Back to main view"});
    this.controller.setupWidget('entryNum',
        {
            hintText:       'Enter key here',
            modelProperty:  'originalValue',
            textCase:       Mojo.Widget.steModeLowerCase,
            multiline:      false,
            focus:          true,
            maxLength: 30
        },
        this.keyModel =
        {
            originalValue : ''
        });

    Mojo.Event.listen(this.controller.get('get_button'),
        Mojo.Event.tap, this.handleGetButton.bind(this));
    Mojo.Event.listen(this.controller.get("back_button"),
        Mojo.Event.tap, this.handleBackButton.bind(this));
}

GetAssistant.prototype.cleanup = function(event) {
    this.controller.stopListening(
        this.controller.get('get_button'), Mojo.Event.tap,
        this.handleGetButton);
    this.controller.stopListening(
        this.controller.get('back_button'), Mojo.Event.tap,
        this.handleBackButton);
}

GetAssistant.prototype.handleGetButton = function(event) {
    this.depot.get(this.keyModel.originalValue,
        this.dbGetSuccess.bind(this),
        this.dbGetFailure.bind(this));
}

GetAssistant.prototype.dbGetSuccess = function(response) {
    var recordSize = Object.values(response).size();
    if(recordSize == 0) {
        this.controller.get("response").innerHTML = "No such record in the database";
    } else {
        this.controller.get("response").innerHTML = "Data entry is: " + response.value;
    }
}

GetAssistant.prototype.dbGetFailure = function(transaction, result) {
    this.controller.get("response").innerHTML = "Error: " + result.message;
}

GetAssistant.prototype.handleBackButton = function(event) {
    this.controller.stageController.popScene();
}

На созданной сцене у нас есть текстовое поле, в которое можно ввести ключ для поиска в хранилище, поле для отображения результатов поиска и две кнопки – кнопка поиска и кнопка закрытия сцены.

WebOS Depot Search GUI

Для получения объекта из хранилища мы используем метод get() объекта Depot. В этом методе указывается ключ и callback-методы, которые отработают при удачном или неудачном завершении транзакции.

На этом все. В этой статье мыузнали:

  • Чем отличается Depot от базы данных SQLite.
  • Как создать объект Depot в хранилище по умолчанию или на разделе с медиа
  • Как создать соединение с Depot
  • Как записать данные в Depot
  • Как получить данные из Depot
  • Как обрабатывать результаты транзакций в callback-методах.

Скачать исходный код примера.

Previous ArticleNext Article
Технический директор IT-Dimension, компании-разработчика кросс-платформенного программного обеспечения

Leave a Reply

Your email address will not be published. Required fields are marked *

З.

Завтра (24.09.2009) открывается Palm App Catalog e-commerce beta

Вот оно! Завтра открывается площадка дя продажи мобильных приложений для Palm WebOS (для устройств Palm Pre).

Желающие уже могут отправлять заявки на регистрацию. Комиссия, которую Palm будет забирать с продажи приложений, такая же как и у всех остальных – 30%. Плата с пользователей будет взыматься одноразово за загрузку приложения.

На данный момент планируется что пользоваться системой смогут только из США (что и не удивительно, у устройств привязка к оператору).

Как запостить приложение

  • Отправить письмо на адрес catalog.ecommerce.beta@palm.com с темой “Название-компании – Название-приложения”
  • В теле письма указать имя пользователя в webOSDev, какого типа приложение – платное или бесплатное, описание приложения
  • Во вложении прикрепить .ipk файл с приложением
  • Каждое приложение надо отправлять отдельным письмом

Условия приема приложений

  • Приложение должно быть интересным конечному пользователю или, как минимум, полезным
  • Дизайн приложения должен соответствовать Palm UI Guidelines
  • Приложение должно быть разработано специально для WebOS и не имет ьдоступ через браузер
  • Приложение должно использовать возможности системі и устройства (например акселерометр или сервисы)
  • Приложение должно иметь вменяемое быстродействие на устройствах

Полезные ссылки

В.

Вышел Mojo SDK v1.2 для Palm WebOS

Сегодня вышла новая версия Palm webOS™ и средств разработки для этой мобильной платформы – Mojo™ Software Development Kit.

В этой версии появилась куча всего полезного для разработчиков мобильных приложений:

  • Mojo SDK теперь поддерживает работу на Windows 7 (x86 и x64), Windows Vista x64, а также Mac OS 10.6 Snow Leopard
  • Новые и улучшенные утилиты в SDK. Теперь отлаживать приложения станет проще благодаря утилите palm-log, которая позволит выводить сообщения об ошибках в JS-коде, а также ниформацию об исключениях, возникающих в программе. webOS Resource Monitor (WORM) позволит отслеживать потребление памяти приложением.
  • Download Manager API, которое позволит загружать и выгружать файлы на сервер по HTTP.

Ссылки