-
Notifications
You must be signed in to change notification settings - Fork 20
ru_Tutorial1
В этом руководстве подразумевается, что вы используете окружение POSIX: Linux,
FreeBSD, Mac OS X или Cygwin для Windows — подойдут. Для пользователей сборки
под Windows все шаги практически те же, но пути и опции компилятора будут
отличаться. Будем считать, что переменная среды YBORM_ROOT
указывает на
корень вашей установки YB.ORM.
Замечание: доступен новый встроенный формат описания отображения, см. TutorialDecl.
Для начала нужно описать структуру таблиц в простом формате XML и сохранить ее
под именем tut1.xml
в вашей рабочей папке. В приведенной ниже схеме описана
одна таблица client_tbl
, ей соответствует класс Client
.
<schema>
<table name="client_tbl" sequence="client_seq" class="Client" xml-name="client">
<column name="id" type="longint">
<primary-key />
</column>
<column name="dt" type="datetime" null="false" default="sysdate" />
<column name="name" type="string" size="100" null="false" />
<column name="phone" type="string" size="50" null="true" />
<column name="email" type="string" size="100" null="false" />
<column name="budget" type="decimal" />
</table>
</schema>
Далее, с помощью специальной утилиты yborm_gen
нужно сгенерировать код C++
класса. Первый параметр — режим работы утилиты, второй параметр — имя файла со
схемой, третий — папка, куда помещать сгенерированные файлы классов, четвертый
(необязательный) — префикс для директивы #include
(по умолчанию domain/
).
$ mkdir domain
$ $YBORM_ROOT/bin/yborm_gen --domain tut1.xml domain
yborm_gen: table count: 1
yborm_gen: generation started...
yborm_gen: Generating file: domain/Client.h for table 'client_tbl'
yborm_gen: Generating cpp file: domain/Client.cpp for table 'client_tbl'
yborm_gen: generation successfully finished
Теперь в папке domain
находятся два файла: Client.h
и Client.cpp
. В них
содержится новый доменный класс Client
со всеми атрибутами. Его можно
смотреть и (осторожно) редактировать. Файл схемы может дополняться новыми
таблицами и колонками, при последующем запуске утилиты yborm_gen
она не
перезапишет полностью ранее созданные файлы с доменными классами, в них будут
обновлены лишь секции помеченные как "авто-сгенерированные".
Теперь можно использовать доменный класс Client
. См. пример ниже. Для
отслеживания новых, загруженных, измененных, удаленных объектов и их
синхронизации с БД используется экземпляр класса Yb::Session
. Более низкий
уровень абстракции для работы с SQL предоставляется классами Yb::Engine
и
Yb::SqlConnection
. В приведенном ниже примере показано создание сессии,
создание и заполнение нового экземпляра отображенного класса и регистрация его
в сессии с последующим сохранением в БД. При сохранении объекту присваивается
новый уникальный ID. Сохраните следующий код в файл tut1.cpp
.
#include <iostream>
#include "domain/Client.h"
int main()
{
Yb::init_schema();
Yb::Session session(Yb::theSchema(), "sqlite+sqlite://./tut1.sqlite");
Domain::Client client;
std::string name, email, budget;
std::cout << "Enter name, email, budget:\n";
std::cin >> name >> email >> budget;
client.name = name;
client.email = email;
client.budget = Yb::Decimal(budget);
client.dt = Yb::now();
client.save(session);
session.commit();
std::cout << "New client: " << client.id << std::endl;
return 0;
}
Для сборки программы с YB.ORM необходимо подключить библиотеки libyborm
,
libybutil
. Требуемые библиотеки обычно находятся в папке $YBORM_ROOT/lib
.
Если вы используете статическую компоновку, то нужно будет подключить и их
зависимости -lxml2
, -lboost_thread
, -lboost_date_time
, и, вероятно, одно
из -lodbc
, -lsqlite3
или -lsoci
. В простейшем случае следующей команды
достаточно, чтобы скомпилировать и собрать этот пример:
$ c++ -I. -I$YBORM_ROOT/include/yb -o tut1 tut1.cpp domain/Client.cpp -L$YBORM_ROOT/lib -lybutil -lyborm
Для того, чтобы пример заработал ему нужно дать базу данных с таблицами. В
этом простом примере создадим локальную базу данных SQLITE
. Можно
воспользоваться той же утилитой чтобы создать SQL DDL скрипт для создания
таблиц. При запуске нужно указать диалект SQL.
$ $YBORM_ROOT/bin/yborm_gen --ddl tut1.xml SQLITE > tut1.sql
yborm_gen: table count: 1
yborm_gen: generation started...
yborm_gen: generation successfully finished
В результате будет получен SQL наподобие такого:
CREATE TABLE client_tbl (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
dt TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
phone VARCHAR(50),
budget NUMERIC
);
Создадим файл базы данных и убедимся, что таблица пуста:
$ sqlite3 tut1.sqlite < tut1.sql
$ sqlite3 tut1.sqlite
SQLite version 3.7.9 2011-11-01 00:52:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select count(*) from client_tbl;
0
sqlite>
Иногда бывает удобно создать таблицы при старте программы. Следующий вызов создаст все объекты, описанные в схеме, в правильном порядке. Если таблицы уже существуют в БД, будет брошено исключение.
Yb::init_schema();
Yb::Session session(Yb::theSchema(), "sqlite+sqlite://./tut1.sqlite");
** session.create_schema(true);**
Давайте запустим пример и посмотрим на результат. Замечание: если используется
сборка YB.ORM в виде динамических библиотек, то, вероятно, потребуется
добавить папку lib
к списку поиска динамических библиотек.
$ export LD_LIBRARY_PATH=$YBORM_ROOT/lib
$ ./tut1
Enter name, email, budget:
Vasya [email protected] 23.45 _<-- пользовательский ввод_
New client: 1
$
Проверим, что сейчас в таблице:
$ sqlite3 tut1.sqlite
SQLite version 3.7.9 2011-11-01 00:52:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from client_tbl;
1|2014-06-01T13:30:36|Vasya|[email protected]||23.45
sqlite>
Теперь в таблице есть одна запись. Чтобы посмотреть что происходит внутри мы
можем включить журнал событий. Внесите следующие изменения в наш пример
tut1.cpp
:
int main()
{
** Yb::LogAppender appender(std::cerr);**
Yb::init_schema();
Yb::Session session(Yb::theSchema(), "sqlite+sqlite://./tut1.sqlite");
** session.set_logger(Yb::ILogger::Ptr(new Yb::Logger(&appender)));**
Скомпилируем и выполним опять, это откроет кучу подробностей взаимодействия с базой данных, в данном случае с SQLite:
$ ./tut1
Enter name, email, budget:
Petya [email protected] 56.78 _<-- пользовательский ввод_
14-06-01 13:55:12.738 28833/28833 DEBG orm: flush started
14-06-01 13:55:12.739 28833/28833 DEBG sql: begin transaction
14-06-01 13:55:12.739 28833/28833 DEBG sql: prepare: INSERT INTO client_tbl (dt, name, email, phone, budget) VALUES (?, ?, ?, ?, ?)
14-06-01 13:55:12.739 28833/28833 DEBG sql: bind: (DateTime, String, String, String, Decimal)
14-06-01 13:55:12.739 28833/28833 DEBG sql: exec prepared: p1="'2014-06-01 13:55:12'" p2="'Petya'" p3="'[email protected]'" p4="NULL" p5="56.78"
14-06-01 13:55:12.740 28833/28833 DEBG sql: prepare: SELECT SEQ LID FROM SQLITE_SEQUENCE WHERE NAME = 'client_tbl'
14-06-01 13:55:12.740 28833/28833 DEBG sql: exec prepared:
14-06-01 13:55:12.740 28833/28833 DEBG sql: fetch: LID='2'
14-06-01 13:55:12.740 28833/28833 DEBG sql: fetch: no more rows
14-06-01 13:55:12.740 28833/28833 DEBG orm: flush finished OK
New client: 2
14-06-01 13:55:12.740 28833/28833 DEBG sql: commit
$
Инструмент YB.ORM предоставляет удобный уровень абстракции, позволяя оперировать с таблицами и строками, оставаясь в рамках объектно- ориентированной парадигмы. Можно привычным образом получать доступ к полям объекта. Кроме того, учитываются особенности конкретного диалекта SQL. Этот инструмент позволяет управлять транзакциями и вести журнал сообщений, в случае необходимости.