Разра-ботка и реализация библиотеки ORM на языке C++ | Прикладная дискретная математика. Приложение. 2011. № 4.

Разра-ботка и реализация библиотеки ORM на языке C++

The Object-RelationalMapping (ORM) library for C++ programming language is presented. Its design andimplementation are discussed. The library is compared with other ORM implementations,namely ODB and Wt::Dbo, and its advantages are concerned.

Design and implementation of the orm library in С + +.pdf Распространённым способом хранения информации в компьютерных системах яв-ляется использование реляционных баз данных (БД), при котором информация о сущ-ностях и связях предметной области представляется в виде записей в таблицах. Каж-дому из полей таблицы соответствует имя и тип хранимых данных. Можно выделитьдва класса библиотек взаимодействия с системами управления БД (СУБД) для язы-ков программирования (ЯП). Библиотеки первого класса устанавливают соответствиемежду данными, хранимыми в полях записей таблиц, и данными элементарных типовв соответствующем ЯП. Библиотеки второго класса характерны для объектно-ориен-тированных ЯП и устанавливают соответствие между записями БД и объектами в ЯП;при этом поля записей соответствуют член-данным объектов. Эти библиотеки, назы-ваемые также объектно-реляционными отображениями (или ORM - Object-RelationalMapping) [1], реализуются с помощью библиотек первого класса и удобнее в использо-вании, поскольку позволяют абстрагироваться от способа представления информациив БД и использовать только понятия соответствующего ЯП. Создана библиотека ORMдля языка C++ [2], рабочее название которой - «C++ ORM on Templates» (COT).Основной сложностью в реализации ORM является избавление пользователя отнеобходимости поддержания большого количества служебной информации, нужнойдля взаимодействия с СУБД. Во-первых, необходимо установить соответствие междутаблицами БД и классами объектов в ЯП. При этом от пользователя ORM требуетсязадание имени класса, а также имен и типов член-данных его экземпляров. Запросына вставку, удаление и изменение соответствующих записей в таблице БД генериру-ются ORM. Во-вторых, необходимо задавать запросы на выборку данных из таблицБД, используя только член-функции классов (называемые в языке C+-+ статически-ми ) и объектов и не прибегая к использованию языка запросов SQL [3]. Это означаетнеобходимость генерации член-функций запросов на выборку данных, не существую-щих в момент реализации ORM. Традиционно оба перечисленных требования к ORMреализуются с помощью рефлексии [4]-способа метапрограммирования, заключаю-щегося в доступе программы к информации о собственной структуре и возможностиизменять эту структуру. Под структурой программы подразумевается совокупностьтипов данных и алгоритмов, используемых в ней.Язык C++ не обладает встроенной возможностью рефлексии, поэтому реализаци-ям ORM необходимо поддерживать метаданные (данные о данных) самостоятельно.Например, библиотека ODB [5] подразумевает использование директив типа #pragmaв описании классов, соответствующих таблицам БД, и обработку этих описаний внеш-ним транслятором, расширяющим структуру программы.Очевидны недостатки та-кого способа реализации ORM: наличие дополнительного транслятора, что затрудня-ет использование библиотеки на всех программно-аппаратных платформах, имеющихтрансляторы с C++, а также невозможность автоматической проверки корректностипрограммы до этапа трансляции. Другая библиотека, Wt::Dbo [6], требует поддержа-ния метаданных от своих пользователей; кроме того, в член-функциях, осуществля-ющих запросы на выборку данных, необходимо использование частей строк запросаSELECT на языке SQL, что, во-первых, делает необходимым знание SQL пользователя-ми Wt::Dbo и, во-вторых, может привести к появлению в программе SQL-инъекций [7].В данной работе используется метапрограммирование на шаблонах в С++, поз-воляющее расширять структуру программы на этапе её трансляции. Современныетрансляторы имеют необходимые алгоритмы оптимизации программ, что делает ис-пользование метапрограммирования на шаблонах возможным не только в качествеэксперимента. Популярные библиотеки Boost [8] являются примером использованияэтого способа написания программ на C++.В языке C++ возможно рекурсивное описание типов с помощью конструкцийtypedef и typename. Библиотека COT использует для хранения информации о типахпараметров и результатах выполнения запросов односвязные списки классов, постро-енные этим способом.Для описания моделей - классов в ЯП, соответствующих таблицам в БД, - в COTиспользуются макросы BEGIN_MODEL, END_MODEL и FIELD (см. строки 1-4 листинга 1).Данные макросы заменяются препроцессором на описание соответствующего класса,которое включает определения: 1) член-данных его экземляров; 2) классов, содержа-щих информацию об этих член-данных и их связях с полями таблицы в БД; 3) стати-ческих член-функций, выполняющих запросы к СУБД, и другую служебную инфор-мацию.Запрос на выборку данных приведён в строках 6-8 листинга 1 - это статическаячлен-функция filter класса модели, принимающая переменное количество парамет-ров. Шаблонные параметры заключены в угловые скобки и представляют собой свя-занные булевыми функциями условия выборки - шаблонные классы сравнения Lt, Gtили Eq, осуществляющие проверку отношения «меньше», «больше» или «равно» со-ответственно. Параметром шаблонных классов сравнения является имя поля модели;значения, с которыми сравниваются эти поля, передаются в член-функцию filterв качестве параметров в круглых скобках (при этом первым должно быть указаноколичество сравнений).1 BEGIN_MODEL(Author)2 FIELD(name, StringValue)3 FIELD(age, IntValue)4 END_MODEL56 authors = Author::filter8 >::with(2, 40, "John Smith");Листинг 1. Пример описания модели и запроса на выборку данных в COTПредоставляемые библиотекой COT средства разрабатывались по аналогии с ORMиз библиотеки Django [9] для ЯП Python [10] -одной из самых известных реализацийORM. Описание модели и запроса на выборку данных, реализованные с помощьюDjango ORM, аналогичные представленным на листинге 1, можно найти в строках 1-3и 5-6 листинга 2 соответственно.1 class Author(models.Model):2 name = models.CharField(max_length=256)3 age = models.IntegerField ()45 authors = \6 Author.objects.filter(age__lt=40, name="John Smith")Листинг 2. Пример описания модели и запроса на выборку данных в Django ORMЗаметим, что в Django ORM условия выборки объединяются логической связкой«и», при этом использование связок «или» и «не» затруднено. В COT шаблонныеклассы And, Or и Not равноправны.Для связи с СУБД использован метод подготовленных запросов, позволяющий еди-ножды произвести синтаксический разбор строк на языке SQL и впоследствии толькоподставлять параметры при выполнении запроса. Это делает невозможным измене-ние синтаксической структуры запроса после его подготовки, что исключает SQL-инъекции. Для передачи результатов выполнения запросов из процедур использованыуказатели из библиотеки Boost, отслеживающие количество ссылок на объекты дляавтоматического управления памятью.Работа библиотеки изучалась с помощью инструментов GNU gprof [11] и Valgrind[12]. Результаты анализа показали, что библиотека COT в среднем не уступа-ет в производительности библиотеке ODB. При реализации судейской системы дляпроведения игр по защите информации CTF [13] COT превысила по быстродействиюбиблиотеку ODB не менее чем на 9 %. Использование инструмента Valgrind позволилоизбавиться от утечек памяти.

Ключевые слова

Авторы

ФИООрганизацияДополнительноE-mail
Стефанцов Дмитрий АлександровичНациональный исследовательский Томский государственный университетаспирант кафедры защиты информации и криптографииdastephantsov@mail.tsu.ru
Ткаченко Николай ОлеговичНациональный исследовательский Томский государственный университетстудент кафедры защиты информации и криптографииn.o.tkachenko@gmail.com
Чернов Дмитрий ВладимировичНациональный исследовательский Томский государственный университетстудент кафедры защиты информации и криптографииdm.vl.chernov@gmail.com
Шмакова Раиса ВладимировнаНациональный исследовательский Томский государственный университетстудентка факультета информатикиraya.shmakova@gmail.com
Всего: 4

Ссылки

Ambler S. W. Mapping Objects to Relational Databases: O/R Mapping In Detail / Ambysoft Inc. 2010. http://www.agiledata.org/essays/mappingObjects.html
Страуструп Б. Дизайн и эволюция языка C++. Объектно-ориентированный язык программирования. М.: ДМК Пресс, 2000. 448с.
Musteata B. and Lesser R. Standard SQL Relational Database Language Guide and Reference. TLM, Inc., 1988. 275 p.
Sobel J. M. and Friedman D. P An Introduction to Reflection-Oriented Programming / Computer Science Department, Indiana University, USA. 1996. 20 p. http://www. cs.indiana. edu/hyplan/jsobel/rop.ps.gz
ODB: C++ Object-Relational Mapping (ORM) / Code Synthesis Tools CC. 2011. http:// www.codesynthesis.com/products/odb/
Deforche K. Wt::Dbo Tutorial. 2010. http://www.webtoolkit.eu/wt/doc/tutorial/dbo/ tutorial.html
SQL Injection / OWASP -The Open Web Application Security Project. 2011. https://www. owasp.org/index.php/SQL_Injection
Dawes B., Abrahams D., and Rivera R. Boost C++ Libraries. 2011. http://www.boost.org/
Django / Django Software Foundation. 2011. http://www.djangoproject.com/
The Python Tutorial / Python Software Foundation. 2011. http://docs.python.org/ tutorial/
GNU gprof / Free Software Foundation Inc. 2009. http://sourceware.org/binutils/docs/ gprof/index.html
Valgrind / Valgrind™ Developers. 2011. http://valgrind.org/
Ткаченко Н. О., Чернов Д. В. Разработка и реализация сервера игры CTF // Прикладная дискретная математика. Приложение. 2010. №3. C. 62-64.
 Разра-ботка и реализация библиотеки ORM на языке C++ | Прикладная дискретная математика. Приложение. 2011. № 4.

Разра-ботка и реализация библиотеки ORM на языке C++ | Прикладная дискретная математика. Приложение. 2011. № 4.