Helma Logo
main list history
previous version  overview  next version

Version 5 by hannes on 05. September 2008, 23:15

helma.filestore is a simple, file based storage engine. It uses JSON as object serialization format and offers basic storage, retrieval and querying support for plain JavaScript objects.

A simple demo app for helma.filestore is <a href="https://dev.helma.org/trac/helma/browser/helma-ng/trunk/apps/storage?rev=9205">included in Helma NG</a>.

To use helma.filestore you need to import the module and create a Store instance, passing it the root directory of the data store:

  importModule('helma.filestore', 'db');
  
  // init store instance if doesn't already exist.
  db.store = db.store || new db.Store("db");

Next you define a JavaScript constructor for your persistent model class. There are two extra methods need to call. One is the <code>registerType()</code> method in your Store instance, which adds static retrieval methods such as <code>get(id)</code> or <code>all()</code> to the constructor, allows the store to use the constructor when retrieving objects. The other is the <code>makeStorable()</code> method which you call in the constructor to add instance methods like <code>save()</code> and <code>remove()</code> as well as getters and setters for the persistent properties.

  function Book(props) {
      // add instance methods and property accessors
      db.makeStorable(this, props);
  }
  
  // add static retrieval methods to the Book constructor
  db.store.registerType(Book);

Note that the persistent properties are kept in a separate object which is here called <code>props</code>. The accessors installed by db.makeStorable() allow to access these properties in the model object itself. Any properties you set in the persistent property object will be stored.

Of course you can add methods to your model object any way you like it, either in the constructor or through the constructor's prototype property. Thus, the full code now looks like this:

  importModule('helma.filestore', 'db');
    
  // init store instance if doesn't already exist.
  db.store = db.store || new db.Store("db");
  
  function Book(props) {
      // Define any instance methods you like, accessing persistent
      // properties using the this prefix.
      this.getFullTitle = function() {
          return this.author + ": " + this.title;
      }
      
      this.toString = function() {
          return "Book[" + this.getFullTitle() + "]";
      }
      
      // add instance methods and property accessors
      db.makeStorable(this, props);
  }
    
  // add static retrieval methods to the Book constructor
  db.store.registerType(Book);

That's it, your first persistent JavaScript class. Store the code above to a file called book.js so we can play with it using the Helma NG shell:

  $ java -jar run.jar -i book.js
  helma> var b = new Book({ title: "Die kleine Hexe", author: "Erich KästnerOtfried Preußler" });
  helma> b
  Book[Erich Kästner: Book[Otfried Preußler: Die kleine Hexe]
  helma>

Voila, your first persistent object. Let's store it and see how the data retrieval objects work:

  helma> b.save()
  helma> b._id
  1
  helma> Book.get("1");
  Book[Erich Kästner: Book[Otfried Preußler: Die kleine Hexe]
  helma> new Book({ title: "Der kleine Walfisch", author: "Erwin Moser" }).save()
  helma> Book.all()
  Book[Erich Kästner: Book[Otfried Preußler: Die kleine Hexe],Book[Erwin Moser: Der kleine Walfisch]
  helma>

One very powerful method is the <code>list()</code> method in the model's constructor. It allows you to get a filtered, ordered, and sliced view of the stored objects. For example, the following will give you a list of up to 10 books with the word "klein" in the title, ordered by author name and starting with the first book:

  helma> Book.list({
      >  orderBy: "author",
      >  order: "asc",
      >  filter: function(book) { return /klein/.test(book.title); },
      >  start: 0,
      >  max: 10
      > });
  Book[Erich Kästner: Book[Otfried Preußler: Die kleine Hexe],Book[Erwin Moser: Der kleine Walfisch]
  helma>

If you're done, use a book's <code>remove()</code> method to delete it from the data store.

     removed
     added