wip: more documents [skip ci]

This commit is contained in:
Hamed Masafi 2019-06-20 12:39:34 +04:30
parent 35eb05ab8e
commit 126f214146
5 changed files with 240 additions and 51 deletions

View File

@ -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<Post*> 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

39
doc/database.md Normal file
View File

@ -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 <Database>
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<Post>(this))
, m_comments(new TableSet<Comment>(this))
{
}
```

67
doc/query.md Normal file
View File

@ -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\<QSharedPointer\<Post\>\>** 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<int>
```
## 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<int>() << 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();
```

61
doc/start.md Normal file
View File

@ -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<Post*> 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<Post>();
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<Comment>(new Comment) in shared_pointer mode
auto comment = Nut::create<Comment>();
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)

70
doc/table.md Normal file
View File

@ -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<Comment>(this)), m_id(0), m_title("")
{
}
```
For more example take a look at _tests/common_ folder