#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2006
    Posts
    3
    Rep Power
    0

    Open source ORM frameworks for C++??


    Hi

    Can anyone recommend a free/low-cost/open-source ORM framework for C++, something along the lines of Hibernate?

    I've done some asking and searching around and there doesnt seem to be one. Just want to confirm if this is the case?

    Thanks
    Andrew
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2006
    Posts
    245
    Rep Power
    20
    I googled it and couldn't find anything.
    Welcome! to the forums.
  4. #3
  5. Google Relay Server
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Oct 2003
    Location
    Oh christ I don't even know any more.
    Posts
    1,812
    Rep Power
    439
    Here is somebody with the same problem; perhaps a good answer is there? Or this?
    Last edited by peenie; July 22nd, 2006 at 11:52 AM.
    OMG RAVER CHICKS!!
    On a related note: C/C++ Programming Tutorials


    "Science is based on reality staying the same, and Nature ignores what humans vote upon." -- Bill Beaty
    "Three litres of sherry up the butt can only be described as astounding." -- Darwin Awards
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2006
    Posts
    3
    Rep Power
    0
    Thanks. OpenORM and DTL look interesting, I'll investigate them further.

    Thanks for the welcome, nice to know its a friendly communiy :)
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2006
    Posts
    245
    Rep Power
    20
    It is! But the mods at least don't like new people if they don't read the how to post a question. So make sure you read that!

    Edit:I know I didn't say it was a bad title at all... I just meant thats what they don't like just for a warning.

    Comments on this post

    • peenie disagrees : (0) i thought the OP was very well-stated.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2006
    Posts
    3
    Rep Power
    0
    I did read it actually and i dont see whats wrong with the title.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2010
    Posts
    1
    Rep Power
    0
    I know it is an old thread, but I thought I would add this in case someone else has the same question.

    There is a new, open-source, compiler-based ORM system for C++ called ODB. The big difference between ODB and the other libraries mentioned above is that ODB allows you to persist C++ objects to a relational database without manually writing any mapping code.

    The C++ code that performs the conversion between persistent classes and their database representation is automatically generated by the ODB compiler. The ODB compiler is a real C++ compiler except that instead of producing assembly or machine code, it generates portable C++ which can in turn be compiled by any C++ compiler.

    Here is an example of a persistent class declaration in a C++ header:

    Code:
      #pragma db object
      class person
      {
        ...
    
      private:
        friend class odb::access;
        person ();
    
        #pragma db id auto
        unsigned long id_;
    
        string first_;
        string last_;
        unsigned short age_;
      };
    Given this class, we can perform various database operations with its objects:

    Code:
    person john ("John", "Doe", 31);
      person jane ("Jane", "Doe", 29);
    
      transaction t (db.begin ());
    
      db.persist (john);
      db.persist (jane);
    
      result r (db.query (query::last == "Doe" && query::age  (cout, "\n"));
    
      jane.age (jane.age () + 1);
      db.update (jane);
    
      t.commit ();
    ODB is cross-platform and cross-database. Check it out.

    Comments on this post

    • peenie agrees : Thanks!
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Location
    Moscow
    Posts
    1
    Rep Power
    0

    Another option: YB.ORM for C++


    One more post to this old thread :)
    If you feel the need for ORM in your C++ app, here is an option: YB.ORM library. It is highly portable and supports a variety of SQL engines. Below is an example of usage. Let's consider an example schema with two entities: Client and Order. There is an one-to-many relationship between them: one Client may have zero or more Orders, each Order belongs to a Client. Clients are stored in table client_tbl, while their Orders are stored in table order_tbl.
    At the SQL level the relationship can be expressed as a foreign key constraint on column client_id in the child table order_tbl referencing primary key column id in the parent table client_tbl. From the ORM perspective such relationship is usually represented by the objects' properties. An instance of class Order has an object-reference property, referencing single parent object of class Client. From the other side of the relationship, an instance of a class Client may have a collection-of-objects property (also known as "backref"), which can be used to iterate all over its children Orders.
    Let's define the mapping schema along with two classes Client and Order.
    Code:
    #include "orm/domain_object.h"
    #include "orm/domain_factory.h"
    #include "orm/schema_decl.h"
    class Order;
    class Client: public Yb::DomainObject {
    YB_DECLARE(Client, "client_tbl", "client_seq", "client",
        YB_COL_PK(id, "id")
        YB_COL_DATA(dt, "dt", DATETIME)
        YB_COL_STR(name, "name", 100)
        YB_COL_STR(email, "email", 100)
        YB_COL_DATA(budget, "budget", DECIMAL)
        YB_REL_ONE(Client, owner, Order, orders, Yb::Relation::Restrict, "client_id", 1, 1)
        YB_COL_END)
    public:
        int get_info() const { return 42; }
    };
    class Order: public Yb::DomainObject {
    YB_DECLARE(Order, "order_tbl", "order_seq", "order",
        YB_COL_PK(id, "id")
        YB_COL_FK(client_id, "client_id", "client_tbl", "id")
        YB_COL(dt, "dt", DATETIME, 0, 0, Yb::Value("sysdate"), "", "", "", "")
        YB_COL_STR(memo, "memo", 100)
        YB_COL_DATA(total_sum, "total_sum", DECIMAL)
        YB_COL_DATA(receipt_sum, "receipt_sum", DECIMAL)
        YB_COL_DATA(receipt_dt, "receipt_dt", DATETIME)
        YB_REL_MANY(Client, owner, Order, orders, Yb::Relation::Restrict, "client_id", 1, 1)
        YB_COL_END)
    public:
        const Yb::Decimal to_be_paid() {
            return total_sum - receipt_sum.value(0);
        }
    };
    These class declarations can be placed in a header or in a .cpp file. Two more sentence are expected in your .cpp file for the magic to work:
    Code:
    YB_DEFINE(Client)
    YB_DEFINE(Order)
    Classes Client and Order are automatically given a few new data members and methods. There are now mapped properties (id, dt, name, ) at each object of the class. The properties can be used to access the column data in read and write modes, as well as to check for absent value (IS NULL).
    To control the instances of mapped classes it's necessary to have an instance of class Yb::Session, which takes care of loading/saving the objects, keeps track of changes, controls the relationships, etc. On creation of Session pass a database scheme to it.
    Code:
    int main() {
        Yb::init_schema();  // gather all declarations in one schema
        Yb::Session session(Yb::theSchema(), "sqlite+sqlite://./tut1.db");
        session.create_schema(true);  // create schema if necessary
    Now you can instantly use the domain classes just like that:
    Code:
        Order order;
        order.total_sum = Yb::Decimal("3.14");
        order.receipt_sum = Yb::Decimal(0);
        order.save(session);
        Client client;
        client.name = "Some Name";
        client.email = "some@email";
        client.dt = Yb::now();
        client.save(session);
        order.owner = Client::Holder(client);
        session.commit();
        return 0;
    }
    You can compile the example, link in the libraries ybutil and yborm, and it's ready to run. If you like you might turn on logging to see what's going on under the hood here:
    Code:
    #include "util/nlogger.h"
    #include <iostream>
    ...
        Yb::LogAppender appender(std::cerr);
        Yb::init_schema();  // gather all declarations in one schema
        Yb::Session session(Yb::theSchema(), "sqlite+sqlite://./tut1.db");
        session.set_logger(Yb::ILogger::Ptr(new Yb::Logger(&appender)));
    Here is the log messages, specific for SQLite DB engine:
    Code:
    14-10-27 14:19:38.489 21962/21962 DEBG sql: exec_direct: CREATE TABLE client_tbl (
            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
            dt TIMESTAMP,
            name VARCHAR(100),
            email VARCHAR(100),
            budget NUMERIC
    )
    14-10-27 14:19:38.818 21962/21962 DEBG sql: exec_direct: CREATE TABLE order_tbl (
            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
            client_id INTEGER NOT NULL,
            dt TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
            memo VARCHAR(100),
            total_sum NUMERIC,
            receipt_sum NUMERIC,
            receipt_dt TIMESTAMP
            , FOREIGN KEY (client_id) REFERENCES client_tbl(id)
    )
    14-10-27 14:19:38.842 21962/21962 DEBG orm: flush started
    14-10-27 14:19:38.843 21962/21962 DEBG sql: begin transaction
    14-10-27 14:19:38.843 21962/21962 DEBG sql: prepare: INSERT INTO client_tbl (dt, name, email, budget) VALUES (?, ?, ?, ?)
    14-10-27 14:19:38.843 21962/21962 DEBG sql: bind: (DateTime, String, String, Decimal)
    14-10-27 14:19:38.843 21962/21962 DEBG sql: exec prepared: p1="'2014-10-27 14:19:38'" p2="'Some Name'" p3="'some@email'" p4="NULL"
    14-10-27 14:19:38.844 21962/21962 DEBG sql: prepare: SELECT SEQ LID FROM SQLITE_SEQUENCE WHERE NAME = 'client_tbl'
    14-10-27 14:19:38.844 21962/21962 DEBG sql: exec prepared:
    14-10-27 14:19:38.844 21962/21962 DEBG sql: fetch: LID='1' 
    14-10-27 14:19:38.844 21962/21962 DEBG sql: fetch: no more rows
    14-10-27 14:19:38.845 21962/21962 DEBG sql: prepare: INSERT INTO order_tbl (client_id, dt, memo, total_sum, receipt_sum, receipt_dt) VALUES (?, ?, ?, ?, ?, ?)
    14-10-27 14:19:38.845 21962/21962 DEBG sql: bind: (LongInt, DateTime, String, Decimal, Decimal, DateTime)
    14-10-27 14:19:38.845 21962/21962 DEBG sql: exec prepared: p1="1" p2="'2014-10-27 14:19:38'" p3="NULL" p4="3.14" p5="0" p6="NULL"
    14-10-27 14:19:38.845 21962/21962 DEBG sql: prepare: SELECT SEQ LID FROM SQLITE_SEQUENCE WHERE NAME = 'order_tbl'
    14-10-27 14:19:38.846 21962/21962 DEBG sql: exec prepared:
    14-10-27 14:19:38.846 21962/21962 DEBG sql: fetch: LID='1' 
    14-10-27 14:19:38.846 21962/21962 DEBG sql: fetch: no more rows
    14-10-27 14:19:38.846 21962/21962 DEBG orm: flush finished OK
    14-10-27 14:19:38.846 21962/21962 DEBG sql: commit
    Note the correct order of insertion (first parent, second child). This is achieved by doing the topological sort on the graph of objects. The value of foreign key is assigned automatically, as well as the values of primary keys.
    The same effect can be achieved if we manipulate the link between objects from the other side:
    Code:
        //order.owner = Client::Holder(client);
        client.orders.insert(order);
    The domain classes are particularly useful for constructing queries. For example we need a pager over orders of certain client, let's fetch items from 30 till 39 inclusive:
    Code:
    #include <boost/foreach.hpp>
    ...
        Yb::DomainResultSet<Order> rs = Yb::query<Order>(session)
            .filter_by(Order::c.client_id == 32738)
            .order_by(Order::c.dt)
            .range(30, 40).all();
        BOOST_FOREACH(Order order, rs) {
            std::cout << order.id << ",";
        }
    For further information please visit project home page: https://sourceforge.net/projects/yborm/

IMN logo majestic logo threadwatch logo seochat tools logo