Skip to content

Repository files navigation

cpp-ORM

Current build status : Build Status

An ORM project.

You can simply create persistent objects using databases.

The object representation: Each object have to be in a separate table with a pk column named 'id' as auto increment. each attr is a column in this table.

Table ares created automaticly.

Tested on

  • Windows x64 (sqlite3 only) + Mingw 4.9 [v 0.4+]
  • Ubuntu + Gcc 4.8+ [v 0.1+]
  • Ubuntu + clang 3.3+ [v 0.1+]

functions

  • Persistent Object
  • print as json
  • save / update / load
  • polymorphic object [0.4.2]
  • Foreign key
  • save / update / load
  • ManyToMany
  • save / update / load / add / remove
  • filters (and, or, not)
  • WHERE statement
  • and, or, not
  • order by
  • limit
  • caching
  • debug output (set ORM_DEBUG to ORM_DEBUG_XXX in debug.hpp)
  • multi connection for a single object (select/save) [v 0.3]
  • Table creation, clearing and drop

Data bases supported

  • MySql
  • Sqlite3

Requirement

  • mysql-connector-c (if Mysql support is needed). Can be find here : https://dev.mysql.com/downloads/connector/c/ or libmysql++-dev (ubuntu)
  • lib Sqlite3 [included since v 0.4]
  • pthread (for linux only) [v 0.4+]
  • doxygen (for user doc only)

Installation

You just have to use cmake:

mkdir build
cd build
cmake ..
make
make install

You can customise the backends supported using

  • ORM_BUILD_SUPPORT_SQLITE3
  • ORM_BUILD_SUPPORT_MYSQL

Exemple

You can see complet exemple in main.cpp

To build the exemple (the database is include)

set the BUILD_EXAMPLES to True with cmake
//#include <ORM/backends/MySql.hpp>//create your default database
orm::MySqlDB def("root","root","test");
//#include <ORM/backends/Sqlite3.hpp>//orm::Sqlite3DB def("./datas/test.db"); //if you want to use sqlite3//make it as default
orm::DB& orm::DB::Default = def;
#include<ORM/fields.hpp>
#include<ORM/models/SqlObject.hpp>//create you classclassPerso : publicorm::SqlObject<Perso>
{
public:Perso();
orm::CharField<255> name;
orm::IntegerField pv;
orm::IntegerField lvl;
MAKE_STATIC_COLUM(name,pv,lvl)
};
REGISTER_AND_CONSTRUCT(Perso,"perso",name,"nom",pv,"pv",lvl,"lvl")
int main(int argc,char* argv[])
{
//connect to database
orm::DB::Default.connect();
//orm::Tables::drop(); // delete all tables//orm::Tables::clear(); // clear tables contentsorm::Tables::create(); //create all thes tables//get perso with pk=1
Perso::type_ptr p1 = Perso::get(1);
//see it
cout<<*p1<<endl;
//modify it
p1->pv +=14;
//save it
p1->save();
//add one
Perso::type_ptr p2 = Perso::create();// = new Perso;
p2->name = "test insert";
p2->lvl = 75;
p2->save(); //save it
cout<<*p2<<endl;
// all
cout<<"All persos"<<endl;
Perso::result_type lis= Perso::all();
for(auto u : lis)
cout<<*u<<endl;
list.clear();
//custom queryPerso::query()\
.filter(Q<Perso>(4,"gt",Perso::$lvl)
and Q<Perso>(42,"gte",Perso::$lvl)
and Q<Perso>("test","startswith",Perso::$name)
andnot Q<Perso>(4,"lt",Perso::$lvl)
).orderBy(Perso::$name)\
.limit(42)\
.get(lis); //get take a list T::result_type& or a T& as paramfor(auto u : lis)
cout<<*u<<endl;
orm::DB::Default.disconnect();
return0;
}

Class

All class are under the orm namespace

orm::SqlObject

Base class for persistent T class. It add all static method / attribute to your class.

make some static method:

  • T::result_type get(int pk)
  • T::result_type all()
  • orm::QuerySet<T> T::query() construct a queryset to make custom query

static member:

  • DB* default_connection : database where the object is contain
  • std::string table : table name on the database

make member fonction:

  • bool save(bool recursive=false,DB&=*default_connection)
  • bool del(bool recursive=false,DB&=*default_connection)

Exemple: see main.cpp

Fields

  • AutoField

  • BooleanField

  • CharField<int>

  • TextField

  • DateTimeField

  • AutoDateTimeField

  • AutoNowDateTimeField

  • DoubleField

  • FloatField

  • IntegerField

  • FK<T>

  • ManyToMany<OWNER,T>

orm::Attr<T>

Make a T persistent in the database.

You can access to the value using:

  • T value;

All operators are overloads to make a easy use of it.

You may prefer to use premake fields

orm::ManyToMany<T,U>

T have to be the persistent class where the M2M is use, and U the persistent class. I create a link with the 2 class, and you can access to the U using:

accessors:

  • U::result_type .all()

orm::DB

Base classe to deal with your database. Use specialize database (MySqlDB, ...)

Constructor: DB(const std::string& username,const std::string& pass,const std::string& db,const std::string& serveur,const std::string& port);

You can use some fonction:

  • bool connect()
  • bool disconnect()
  • Query* query()
  • Query* query(std::string&)
  • Query* query(std::string&&)
  • Query* preparedQuery(std::string&)
  • Query* preparedQuery(std::string&&)

You can custom the default database:

orm::MySqlDB def("root","root","test");
orm::DB& orm::DB::Default = def;

Macros

There are some macos to help.

MAKE_STATIC_COLUM(...)

To call in your class with all persistent attrs in params. It will construct the static std::string to use (on filter ...). ORM_MAKE_NAME(colum) turn your colunm name to the on to use by adding ORM_COLUMN_CHAR ($ by default)

exemple:

classSpell : publicorm::SqlObject<Spell>
{
public:Spell();
orm::CharField<255> name;
orm::IntegerField element;
MAKE_STATIC_COLUMN(name,element);
};

the colums $name and $element will be created for query.

 Spell::
auto results = Spell::query().filter("spell name",orm::op::exact,Spell::$name);

REGISTER_AND_CONSTRUCT(klass,colum,[attr,colum]+)

Make the default constructor of your class, construct all comulm as static strings. This macro simply call REGISTER_TABLE(klass,colum) and MAKE_CONSTRUCTOR(klass,VA_ARGS)

Marcos II

Only to use if you want build a custum constructor

REGISTER_TABLE(klass,colum)

If you use REGISTER_AND_CONSTRUCT, you don't need to use it.

Thiis will create all the static variables needed by the library

MAKE_CONSTRUCTOR(klass[,attr,colum]+)

If you use REGISTER_AND_CONSTRUCT, you don't need to use it.

Make the default constructor for the class klass, and register all Att in params. It also call _MAKE_STRING_N to create attrs colum names as static.

 _MAKE_STRING_N(klass,NUM_ARGS(__VA_ARGS__),__VA_ARGS__)
klass::klass(): _MAKE_ATTRS_N(NUM_ARGS(__VA_ARGS__),__VA_ARGS__)
{
_MAKE_REGISTER_ATTRS(NUM_ARGS(__VA_ARGS__),__VA_ARGS__)
}

_MAKE_STRING_N(klass,N,...)

If you use REGISTER_AND_CONSTRUCT, you don't need to use it.

N have to be the number of attrs (in ...)

Simply construct all string as: std::string klass::_attr = colum;

_MAKE_ATTRS_N(N,...)

If you use REGISTER_AND_CONSTRUCT, you don't need to use it.

N have to be lenght of ...

simply add attr(colum) to constuctor for const initialize

_MAKE_REGISTER_ATTRS(N,...)

If you use REGISTER_AND_CONSTRUCT, you don't need to use it.

for each att in ...

this->registerAttr(this->name);

About

A project to create a simple ORM.

Topics

Resources

Stars

7 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages