Define a Data Model in JSON or JavaScript

model = new DataStoreCatalog();
var Person = model.addClass("Person", "People");
Person.addAttribute("firstName","storage","string");
Person.addAttribute("lastName" ,"storage","string");
Person.addAttribute("name", "calculated", "string");
Person.name.onGet = function()
{
  return this.firstName + ' ' + this.lastName;
}
Person.addAttribute("company", "relatedEntity",
      "Company", "Companies");
{ name: "Company",
  className: "Company",
  collectionName: "Companies",
  scope: "public",
  attributes:[
  { name: "ID", autosequence: true,
    kind: "storage", primKey: true,
    scope: "public", type: "long",
    unique: true
  },{
    name: "name", kind: "storage", 
    scope: "public", type: "string"
  },{
    kind: "relatedEntities", name: "employees",
    reversePath: true, path: "company",
    scope: "public", type: "Person"
  }]
}

Play with WakandaDB

We created play.wakanda.org so that you can try out our SSJS database right from your browser.


Download WakandaDB

You can download wakandaDB and run it on Linux, OS X, or Windows.


Documentation

We are quite proud of our extensive Wakanda documentation.


Wakanda Studio

We also make a really cool editor/IDE that gives you a visual data modeler (creating that JSON to the left there), and access to a drag-and-drop web WYSIWYG development enviornment. Checkout Wakanda Studio.


Native API Examples

Server-Side JavaScript

SSJS Query

var country = ds.Country(1);
Result
{
  ID: 1,
  name: "France",
  code2Chars: "fr",
  companies: CompanyCollection()
}

REST

REST Request

GET /rest/Country(1)
JSON Response
{
  __entityModel: "Country",
  __KEY: "1",
  __STAMP: 1,
  ID: 1,
  name: "France",
  code2Chars: "fr",
  companies: {
    __deferred: {
      uri: "/rest/Country(1)/companies?$expand=companies"
    }
  }
}


Examples of Integrating

Generic "Ajax"

Wakanda provides a universal Ajax driver able to provide a proxy of the model in any browser. It is composed of a "data provider" and a "data source". The data provider is useful to provide data binding to any raw JavaScript application or to any existing Ajax Framework. The data source layer provides a "Publish/Subscribe" mechanism (aka Observer) for any element using them (widgets, other datasources, ...)

Ajax Query

var vcount;
var myset = ds.Person.query("ID > 100 and ID < 300", {
    // we pass a function that receives the server response
    onSuccess: function(event) 
    {
        vcount = event.entityCollection.length;
        // we retrieve the size of the entity collection
        $("#display").html("selection : "+vcount);
        // display the size of the entity collection in the container whose ID is "display"
    }
});

more information:

Angular Wakanda resource

Vojta Jina from Google went to present AngularJS at Wakanday Europe 2012. He made at this occasion a Wakanda version of its ng-todo demo application using a "wakanda-resource.js" file bound on the Wakanda REST API.

Todo Controller

var todo = angular.module('todo', ['wakandaResource']);

todo.controller('Todo', function($scope, Item) {
  $scope.items = Item.query();

  $scope.add = function() {
    var item = new Item({text: $scope.newText, done: false});
    $scope.items.push(item);
    $scope.newText = '';

    item.$save();
  };

  $scope.remaining = function() {
    return $scope.items.reduce(function(count, item) {
      return item.done ? count : count + 1;
    }, 0);
  };

  $scope.archive = function() {
    $scope.items = $scope.items.filter(function(item) {
      if (item.done) {
        item.$remove();
        return false;
      }
      return true;
    });
  };
});

todo.factory('Item', function(wakandaResource) {
  return wakandaResource('/rest/Item:id');
});
Todo HTML
<!DOCTYPE html>
<html ng-app="todo">
<head>
  <meta charset="utf-8">
  <title>Things To Do</title>
  <link href="bootstrap/css/bootstrap.css" rel="stylesheet">
  <script src="angular.js" type="text/javascript"></script>
  <script src="angular-resource.js" type="text/javascript"></script>
  <script src="wakanda-resource.js" type="text/javascript"></script>
  <script src="todo.js" type="text/javascript"></script>
  <style type="text/css">
    .done-true {
      color: gray;
      text-decoration: line-through;
    }
  </style>
</head>
<body ng-controller="Todo" class="well">

<h1>Things To Do</h1>

<p>
  Remaining <strong></strong> of <strong></strong>.
  [ <a ng-click="archive()">archive</a> ]
</p>

<ul class="unstyled">
  <li ng-repeat="item in items" class="done-">
    <input ng-model="item.done" ng-change="item.$update()" type="checkbox">
    
  </li>
</ul>

<form>
  <input ng-model="newText" type="text">
  <button ng-click="add()" ng-disabled="!newText" class="btn btn-primary">add</button>
</form>

</body>
</html>

more information:

  • ng-todo Wakanda branch: source

Sencha-Wakanda

First presented during Wakanday 2011, a Sencha Wakanda proxy was realized by the french company revolunet. This Sencha Wakanda proxy uses the built in Wakanda REST API directly.

Example

Ext.define('Employee', {
    extend: 'Ext.data.WakandaModel'
});

Ext.onReady(function() {

  var store = Ext.create('Ext.data.Store', {
    buffered: true,
    remoteSort: true,
    remoteFilter: true,
    pageSize: 200,
    model: 'Employee'
  });

  var grid = Ext.create('Ext.grid.Panel', {
    x: 20,
    y: 20,
    width: 500,
    height: 300,
    frame: true,
    floating: true,
    store: store,
    bbar: toolbar,
    renderTo: document.body,
    verticalScrollerType: 'paginggridscroller',
    loadMask: true,
    disableSelection: true,
    invalidateScrollerOnRefresh: false,
    viewConfig: {trackOver: false},
    columns: [
      {xtype: 'rownumberer', width: 40, sortable: false},
      {dataIndex: 'lastName', header: 'Last name',
        field: {xtype: 'textfield'}},
      {dataIndex: 'firstName', header: 'First name',
        field: {xtype: 'textfield'}},
      {dataIndex: 'salary', header: 'Salary',
       renderer: Ext.util.Format.usMoney,
       field: {xtype: 'textfield'}},
      {dataIndex: 'companyName', header: 'Company', flex: 1}
    ]
  });
     
  store.guaranteeRange(0, 199);

});

more information: