SourceForge.net Logo http://sourceforge.net/projects/dbapi/

Greendb is an embeded database with rows and columns. Instead of SQL it provides a simple and efficient API. It is written in C++ and built on top of Sleeeycat (berkeley) database. Interfaces currently exists for perl, python, and guile, using SWIG. A GUI is in the works.

Here are some example in various languages. They should help get you started. If you have any other questions, use the Forums or email. There is no other documentation yet.

Sample in c++

#include "greendb/greenenv.hh"
#include "greendb/debug.hh"
#include "greendb/table.hh"
#include "greendb/schema.hh"
#include "greendb/typemap.hh"
#include "greendb/row.hh"
#include "greendb/datum.hh"
#include "greendb/strdatum.hh"
#include "greendb/resultset.hh"
#include <malloc.h>
#include <assert.h>
void print_row(Row* row) {
    for (size_t i = 0; i < row->size(); i++) {
      //Datum* val = row->get_column(i);
      //assert(val);
      std::cout<<row->to_string(i);
      if (i+1 < row->size()) {
        std::cout<<", ";
      }
    }
    std::cout<<std::endl;
}
void print_person(Row* row) {
  IntDatum* id = (IntDatum*)row->get_column("id");
  fprintf(stdout, "id: %d", id->value());
  StrDatum* name = (StrDatum*)row->get_column("name");
  fprintf(stdout, "name: %s", name->value());
  IntDatum* age = (IntDatum*)row->get_column("age");
  fprintf(stdout, "age: %d", age->value());
}
int
main (int argc, char **argv) {
  static GreenEnv ge(".");
  g_message("greenenv: %s", ge.home());
  // open people database
  char* table_name = "people";
  ge.open ();
  Table table (table_name, ge);
  // get schema
  Schema* schema = table.get_schema();

  // testing int datatype (not connected to any table)
  IntDatum* ii = new IntDatum(99);
  g_message(ii->repr());
  g_message(ii->str());
  Datum* dd = ii;
  g_message(dd->repr());
  g_message(dd->str());

  // create and fill database if it doesn't already exist
  if (!table.exists()) {
      // create type columns
      schema->add_column("id", TYPE_INT , 1);
      schema->add_column("name", TYPE_STRING , 1);
      schema->add_column("age", TYPE_INT , 1);

      // create datums for columns -- these are reusable
      int n=1;
      {
         Row* row = table.new_row();
         row->set_int("id", n++ );
         row->set_string("name", "Luke");
         row->set_int("age", 23);
         table.save(row);
      }
      {
         // another way to create a row
         Row* row = table.new_row();
         row->set_int("id", n++ );
         row->set_string("name", "Mary");
         row->set_int("age", 18);
         table.save(row);
      }
      {
         // demonstrate datum reuse
         IntDatum id(n++);
         StrDatum name("Mathew");
         g_message("name %s", name.to_string());
         IntDatum age(18);
         {
                 // create a row
                 Row* row = table.new_row();
                 row->set("id", id );
                 row->set("name", name );
                 row->set("age", age);
                 table.save(row);
              }
              {
                 // set columns and add another row
                 Row* row = table.new_row();
                 id.set_int(n++);
                 row->set("id", id );
                 name.set_string("Thomas");
                 row->set("name", name );
                 age=23;
                 row->set("age", age);
                 table.save(row);
              }
      }

  }
  {
    g_message("fetch by primary key 2");
    IntDatum key(2);
    Row * row = table.fetch("id",key);
    fflush(stdout);
    assert(row != NULL);
    assert(strcmp(row->get_string("name"), "Mary")==0);
    print_row(row);
    // 2, Thomas, 23
    print_person(row);
    row->close();
  }
  { // fetch by name
    g_message("fetch by foreign key name Luke");
    StrDatum key("Luke");
    Row * row = table.fetch("name",key);
    assert(row != NULL);
    assert(strcmp(row->get_string("name"), "Luke")==0);
    print_row(row);
    // 4, Luke, 23
    print_person(row);
    row->close();
  }
  {
    g_message("fetch by foreign key age 18");
    IntDatum key(18);
    {
    Row * row = table.fetch("age",key);
    print_row(row);
    // 1, Mathew, 18
    print_person(row);
    row->close();
    }
  }
  {
    g_message("fetch all by foreign key");
    IntDatum key(18);
    ResultSet* rs = table.find_all("age", &key);
    while(rs->has_row()) {
      CursorRow* row = rs->row();
      print_row(row);
       // 1, Mathew, 18
       // 3, Mary, 18
      rs->next();
    }
  }
  table.close();
  ge.close();
  return 0;
}
C++PerlPythonGuile
mktable.cc mktable.pl mktable.py mktable.scm
addrow.cc addrow.pl addrow.py addrow.scm
desc.cc desc.pl desc.py desc.scm
list.cc list.pl list.py list.scm
toxml.cc

Ruby Sample

require 'greendb'

def main
  table_name ="people"
  ge = Greendb::GreenEnv.new(".")
  begin
    ge.open();
    table  = Greendb::Table.new(table_name, ge);
    begin
    schema = table.get_schema();
    if not table.exists()
      schema.add_column("id", Greendb::TYPE_INT , 1);
      schema.add_column("name", Greendb::TYPE_STRING , 1);
      schema.add_column("age", Greendb::TYPE_INT , 1);
      id = 1;
      names = ["Mathew", "Mary", "Luke", "James"]
      ages = [18,23,18,34]
      for index in (0..(names.length-1))
        row = table.new_row();
        row.set_int("id", id );
        row.set_string("name", names[index]);
        row.set_int("age", ages[index]);
        table.save(row);
        id=id+1
      end
    end
      id2 = Greendb::IntDatum.new(2)
      row= table.fetch("id", id2)
      print_row(schema, row)
      print_person(row)
    ensure
      table.close()
    end
  ensure
    ge.close()
  end
end

def each_colname(schema)
  for i in (0..(schema.size()-1))
    yield schema.get_name(i)
  end
end
def each_column(row)
  for index in (0..(row.size-1))
    yield row.get_column_n(index)
  end
end
def print_header(schema)
  ll=[]
  each_colname(schema) do |name|
    ll.push name
  end
  print ll.join(", "), "\n"
end
def print_row(schema, row)
  print "\n"
  ll=[]
  each_column(row) do |datum|
    ll.push datum.to_string
  end
  print ll.join(", "), "\n"
end
def print_person(row)
  print "id: ", row.get_column("id").to_string, "\n"
  print "name: ", row.get_column("name").to_string, "\n"
  print "age: ", row.get_column("age").to_string, "\n"
end
main

Command line Utilities

Here's an example of how these might be run.
./mktable people int id string name int age
./desc people
people
0) int	id
1) string	name
2) int	age

./addrow people 1 John 30
./addrow people 4 Eric 18
./addrow people 2 Bob 42
./addrow people 3 Steve 18
./list people
people
1, John, 30
2, Bob, 42
3, Steve, 18
4, Eric, 18