diff --git a/README.md b/README.md index d08d7e9..50da158 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,8 @@ # Nut -## Build result -| Branch | Status | -| ------------- |:-------------:| -| master | [![Build Status](https://travis-ci.org/HamedMasafi/Nut.svg?branch=master)](https://travis-ci.org/HamedMasafi/Nut) | -| dev | [![Build Status](https://travis-ci.org/HamedMasafi/Nut.svg?branch=dev)](https://travis-ci.org/HamedMasafi/Nut) | - +[![Build Status](https://travis-ci.org/HamedMasafi/Nut.svg?branch=master)](https://travis-ci.org/HamedMasafi/Nut) [![GitLicense](https://gitlicense.com/badge/hamedmasafi/nut)](https://gitlicense.com/license/hamedmasafi/nut) - [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3802610beb946068f6cd2c2b6608a8b)](https://www.codacy.com/app/HamedMasafi/Nut?utm_source=github.com&utm_medium=referral&utm_content=HamedMasafi/Nut&utm_campaign=Badge_Grade) @@ -23,51 +17,9 @@ Badge](https://api.codacy.com/project/badge/Grade/f3802610beb946068f6cd2c2b6608a - Automatically create and update database - IDE auto complete support, No hard-code nedded - Table join detect - - Supported types: [Full list](doc/datatypes.md) + - Suppor every Qt types. [Full list](doc/datatypes.md) - -## Sample Codes -### Read data from database: - -```cpp -auto q = db.posts()->createQuery(); -q->setWhere(Post::idField() == postId); -auto posts = q->toList(); -// now posts is a QList contain all posts in -// database that has id equal to postId variable -auto post = q->first(); -// post is first row in database that its id is equal to postId -``` - -### Adding to database: -```cpp -Post *newPost = new Post; -newPost->setTitle("post title"); - -db.posts()->append(newPost); - -for(int i = 0 ; i < 3; i++){ - Comment *comment = new Comment; - comment->setMessage("comment #" + QString::number(i)); - - newPost->comments()->append(comment); -} -db.saveChanges(); -``` - -### Modify database data: -```cpp -auto q = db.posts()->createQuery(); -q->setWhere(Post::idField() == postId); -Post *post = q->first(); - -if(post) { - post->setTitle("new name"); - db.saveChanges(); -} else { - qWarning("No post found!"); -} -``` +[Getting start](doc/start.md) ### Donate Butcoin address: 1Dn1WHKkaxanXe4cTGDk4cFRRABxLUpEVj diff --git a/doc/database.md b/doc/database.md new file mode 100644 index 0000000..399ae72 --- /dev/null +++ b/doc/database.md @@ -0,0 +1,39 @@ +Database class must inherits from Nut::Database class. +Database class can have NUT_DB_VERSION for declaring version number, version will be stored in database if upgrade needed. +```cpp +NUT_DB_VERSION(major, minor) +``` + +for every table in database NUT_DECLARE_TABLE macro should be use, usage: +```cpp +NUT_DECLARE_TABLE(class_name, table_name) +``` + +Sample database class: +```cpp +#include + +class Post; +class Comment; +class WeblogDatabase : public Nut::Database +{ + Q_OBJECT + + NUT_DB_VERSION(1) + + NUT_DECLARE_TABLE(Post, post) + NUT_DECLARE_TABLE(Comment, comment) + +public: + WeblogDatabase(); +}; +``` + +Child tables should initalize in constructor, Example: +```cpp +WeblogDatabase::WeblogDatabase() : Nut::Database() + , m_posts(new TableSet(this)) + , m_comments(new TableSet(this)) +{ +} +``` \ No newline at end of file diff --git a/doc/query.md b/doc/query.md new file mode 100644 index 0000000..b752f34 --- /dev/null +++ b/doc/query.md @@ -0,0 +1,67 @@ +# Creating query +```cpp +auto q = db.posts().query(); +``` + +You can also create query in one command: +```cpp +auto result = db.posts().query() + ->where(Post::idField() == 1) + ->toList(); +``` +Now, _result_ contains **QList\\>** and can be used in code. query has other commands like: sum, avg, max, min and etc + +## Getting first record in query +```cpp +auto post = db.posts().query() + ->setWhete(Post::idField() == 1) + ->first(); + +if(post) + qDebug() << "Post found in database"; +else + qDebug() << "No post found!"; + +``` +## Sorting result +```cpp +auto posts = db.posts().query() + ->whete(Post::idField() == 1) + ->orderBy(Post::idField()) + ->toList(); +``` +Also you can sort descending by adding **!** to field name +```cpp +auto posts = db.posts().query() + ->whete(Post::idField() == 1) + ->orderBy(!Post::idField()) + ->toList(); +``` + +## Selecting single field +```cpp +auto ids = db.posts().query() + ->select(Post::idField()); +//ids is type of QList +``` +## Getting sum, count, min, max +```cpp +auto q = db.posts().query(); +auto sum = q.sum(Post::idField()); +auto max = q.max(Post::idField()); +auto min = q.min(Post::idField()); +auto count = q.count(Post::idField()); +``` + +## Checking field exists in list of values +```cpp +auto post = db.posts().query() + ->setWhete(Post::idField().in(QList() << 1 << 2 << 3 << 4) || Post::isAccepted()) + ->first(); +``` +Or +```cpp +auto post = db.posts().query() + ->setWhete(Post::idField().in({1, 2, 3, 4}) || Post::isAccepted()) + ->first(); +``` \ No newline at end of file diff --git a/doc/start.md b/doc/start.md new file mode 100644 index 0000000..a980903 --- /dev/null +++ b/doc/start.md @@ -0,0 +1,61 @@ +Welcome to the Nut wiki! + +# What is Nut + +Nut is advanced, Powerful and easy to use ORM for Qt5 + +## Sample Codes +### Read data from database: + +```cpp +auto posts = db.posts()->query() + where(Post::idField() == postId) + toList(); +// now posts is a QList contain all posts in +// database that has id equal to postId variable +auto post = q->first(); +// post is first row in database that its id is equal to postId +``` + +### Adding to database: +```cpp +auto newPost = Nut::create(); +newPost->setTitle("post title"); + +db.posts()->append(newPost); + +for(int i = 0 ; i < 3; i++){ + // Below line same as new Comment in non shared pointer mode + // or QSharedPointer(new Comment) in shared_pointer mode + + auto comment = Nut::create(); + comment->setMessage("comment #" + QString::number(i)); + + newPost->comments()->append(comment); +} +db.saveChanges(); +``` + +### Modify database data: +```cpp +auto post = db.posts()->query() + ->where(Post::idField() == postId) + ->first(); + +if(post) { + post->setTitle("new name"); + db.saveChanges(); +} else { + qWarning("No post found!"); +} +``` + +## How to use nut + +* [Create database class](database.md) + +* [Create table class](table.md) + +* [Using queries](query.md) + +* [SUpported data types](datatypes.md) \ No newline at end of file diff --git a/doc/table.md b/doc/table.md new file mode 100644 index 0000000..37e82cb --- /dev/null +++ b/doc/table.md @@ -0,0 +1,70 @@ +The class must inherits from Table class + +## Add primary key field +Primary key can be auto increment + +```cpp +NUT_PRIMARY_AUTO_INCREMENT(id) +NUT_DECLARE_FIELD(int, id, id, setId) +``` + +for declaring primary key use _NUT_PRIMARY_KEY_ macro, if primary key is auto increment use _NUT_PRIMARY_AUTO_INCREMENT_ + +| Macro | Description | +| ----------------------------- |:------------------------------------------------| +| NUT_PRIMARY_KEY(x) | The field *x* is primary key | +| NUT_AUTO_INCREMENT(x) | The field *x* is auto increment | +| NUT_PRIMARY_AUTO_INCREMENT(x) | The field *x* is primary key and auto increment | + +## Declare field +```cpp +NUT_DECLARE_FIELD(type, property_name, read_method_name, write_method_name) +``` +## Additional meta data +| Macro | Description | +| ----------------------------- |:-------------------------------------------------| +| NUT_NOT_NULL(x) | The field *x* is not allowed to store NULL value | +| NUT_LEN(x, len) | Max length of *x* is *len* in string types and in numeric typed field *x* will be store in *len* bytes | +| NUT_DEFAULT_VALUE(x, def) | Default value of *x* is *def* | +| NUT_UNIQUE(x) | Field *x* is unique (Not imlemented yet!) | +| NUT_DISPLAY_NAME(field, name) | Sets display name for field (used in model creation | + +## Sample table +```cpp +class Post : public Table +{ + Q_OBJECT + + NUT_PRIMARY_AUTO_INCREMENT(id) + NUT_DECLARE_FIELD(int, id, id, setId) + + NUT_NOT_NULL(title) + NUT_LEN(title, 50) + NUT_DECLARE_FIELD(QString, title, title, setTitle) + + NUT_DECLARE_FIELD(QDateTime, saveDate, saveDate, setSaveDate) + + NUT_LEN(body, 200) + NUT_DECLARE_FIELD(QString, body, body, setBody) +public: + explicit Post(QObject *tableSet = 0); + +}; +``` + +## Declare child table +If current table has one-to-many relation ship it must be declared. For example post table has a slave table named comment, every post has many comment: +```cpp +NUT_DECLARE_CHILD_TABLE(Comment, comments) +``` + +First argument id table name and second is field name, m_comments must be initalized in constructor: +```cpp +Post::Post(QObject *parent) : Table(parent), + m_comments(new TableSet(this)), m_id(0), m_title("") +{ + +} +``` + +For more example take a look at _tests/common_ folder \ No newline at end of file