Я не предлагаю вшивать ООП возможности непосредственно в SQL. Да у меня и нет возможности сделать это – написание SQL-серверов дело сложное. Предлагается сделать прослойку между объектным языком запросов (OQL) и стандартным SQL (описано без конкретной привязке к определенному серверу). Пишем методы в OQL и ретранслируем их в SQL. Исходные тексты можно хранить в специальных таблицах той же базы. Итак о реализации.
Класс данных – обычная таблица в реляционной БД. Единственное требование наличие уникального первичного ключа uid, который автоматически создается ретранслятором. Объект – запись таблицы, первичный ключ аналогом ссылки на объект в обычном ООП. Data member – поля таблицы. Member function – хранимые процедуры, оперирующие объектом или классом данных. Отдельно хочу выделить абстрактный класс, объекты которого не создаются – следовательно, и таблицы нет. Поля и методы такого класса реализуются в наследниках.
Элементариные типы данных остаются теми же: строки, числа, логический тип, дата/время. Добавляются тип ссылки на другую таблицу (внешний ключ). Если это ссылка на абстрактный класс, то реализуется двумя полями, ссылка на класс и ссылка на объект.
Инкапсуляция в ООП необходима по двум причинам. Первая это разделение прав доступа на члены класса. Здесь достаточно просто, достаточно на этапе ретрансляции анализировать работу с данными разного уровня доступа. Вторая - корректное поведение (согласованность), обычно запрещается непосредственно изменять поля класса извне. В одних языках для этого используются свойства, другие обходятся setter методами. В OQL вместо запрета можно воспользоваться триггерами. Таким образом меняя поле, вы вызываете и некое поведение. Получаем нечто вроде property.
Наследование реализуется ссылкой на базовый класс, если тот не абстрактный. В абстрактном случае поля просто реализуются в наследнике.
Полиморфизм. Самое, пожалуй, тонкое место. Объекты класса имеющие виртуальные методы обязаны носить в себе не только указатель на объект (идентификатор записи таблицы), но и иднтификатор самой таблицы. Сами же виртуальные методы реализуются следующим образом:
Если ТипКласса=1 Тогда МетодКласса1(Объект); ИначеЕсли ТипКласса=2 Тогда МетодКласса2(Объект); ИначеЕсли ТипКласса=3 Тогда МетодКласса3(Объект); КонецЕсли;Естественно данноe преобразование делает ретранслятор.
В целом конструкции языка SQL остаются рабочими и только пополняются расширенями.
Служебное слово object - ссылка на объект класса для использования в дальнейшем методов и полей «через точку». Реализуется ретранслятором как uid (плюс идентфикатор класса для абстрактных классов)
SELECT object FROM MyClass INTO: MyObjectVariable
uid - фактически тоже самое, но значение числовое. Только для чтения.
this(self) - ссылка внутри метода на себя
Использование SELECT атрибутов «через точку»
SELECT Title, Author. Name, Author.Country.Name FROM Bookвыдает список названия книг, имя автора и названия стран авторов. Ретранслятор преобразует это в LEFT JOIN
SELECT Title, Author. Name, Author.Country.Name FROM Book LEFT JOIN Author ON (Book. Author= Author.UID) LEFT JOIN Country ON (Author. Country= Country.UID)SELECT для абстрактных классов сводится к набору конкретных SELECT объединенных UNION
Оператор INSERT. Также как и обычная вставка, но переменная <ИмяОбъекта> ссылается на созданный объект (запись)
INSERT <ИмяОбъекта> INTO <ИмяКласса>([Поля]) VALUES ([Значения])
Оператор UPDATE. Изменяет конкретную запись
UPDATE <ИмяОбъекта> SET <Поле>=<Значение>,…
Оператор DELETE. Удаляет запись
DELETE <ИмяОбъекта>
Множественное выполнение EXEC. Выполняется для всех объектов класса, если нужно ограничить используем обычное WHERE, если важен порядок обхода ORDER BY
EXEC <ВызовМетода>() FROM <ИмяКласса>