Проектирование и разработка БД Oracle для информатизации объектов культуры

  • Вид работы:
    Дипломная (ВКР)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    3,06 Мб
  • Опубликовано:
    2014-03-18
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Проектирование и разработка БД Oracle для информатизации объектов культуры

Содержание

Введение

. Выбор модели БД

.1 Исходные требования к проектируемой БД

.2 Обзор основных моделей данных современных БД

.2.1 Иерархические базы данных

.2.2 Сетевая СУБД

.2.3 Многомерная СУБД

.2.4 Реляционная модель баз данных

.2.5 Объектно-ориентированные СУБД

.3 Реализация Объектно-ориентированного проектирования в реляционных БД

.3.1 Объекты как таблицы. Модель ROT

.3.2 Модификация ROT с учетом наследования

.3.3 Модель А. Тенцера “База-данных-хранилище объектов”

.3.4 Модификация модели Тенцера. Модель Entity-Attribute-Value

.3.5 Сравнительный анализ методов реализации объектно-ориентированного проектирования в реляционных БД

.3.6 Итоговый анализ эффективности методов объектно-ориентированного проектирования в реляционных СУБД

.4 Обоснование выбора Entity-Attribute-Value в качестве метода проектирования Базы Данных

. Разработка БД

.1 Общая архитектура БД информационной системы

.2 Модель системных данных

.2.1 Общая архитектура системных объектов БД

.2.2 Описание процесса генерации таблиц

.2.3 Реализация функциональности добавления, редактирования и удаления объектов

.2.4 Реализация функциональности тщательного контроля доступа на уровне объектов

.2.5 Реализация аудита на изменение объектов

.2.6 Реализация механизма поиска объектов

.3 Модель пользовательских данных

.3.1 Общая архитектура пользовательских объектов БД

.3.2 ER-диаграмма фотодокументов архива

.3.3 ER-диаграмма фонодокументов архива

.3.4 ER-диаграмма остальных пользовательских объектов

.3.5 Представления пользователя приложения

. Апробация функционирования БД

.1 Описание работы БД как основной части информационной системы

.2 Тестовые примеры (test cases)

.3 Сводная таблица тестирования (test log)

Заключение

Приложение 1. Листинги пакетов

Листинг пакета DATAMODIFICATION

Листинг пакета GENERATETABLES

Листинг пакета SEARCHDATA

Листинг пакета SECURITYDATA

Приложение 2. Расширенный список тестовых примеров

Список использованной литературы

Введение

В последнее время, в связи с новыми возможностями и вызовами времени, все острее ощущается потребность разных отраслей экономики в развитии информационных технологий, в том числе это касается и объектов культуры, где собраны воистину уникальные и бесценные документы. Кроме того применение информационных систем способствует улучшению функционирования объектов, увеличению производительности труда, расширения аудитории, увеличению информационной безопасности экспонатов объектов культуры. Как правило, к системам, проектируемым к сфере культуры предъявляются очень высокие требования по обеспечению сохранности информации и данных, их конфиденциальности, разграничению доступа пользователей к разным ресурсам этой системы. Вопрос производительности системы тоже не является праздным. Но все же главной задачей таких систем остается, конечно, сохранность информации и данных. Поэтому БД, как основная составляющая таких систем рассматривается, прежде всего, как хранилище данных. Это хранилище в то же время должно гарантировать сохранность и конфиденциальность хранимой в нем информации. база информационный таблица тенцер

В процессе разработки и внедрения системы я столкнулся с проблемой разграничения прав доступа для разных пользователей. Была предложена система разграничения прав пользователей на основе пакета SecurityData. Этот пакет, в зависимости от контекста подключения, предоставляет пользователю права владельца объекта или по умолчанию. Это важно, т.к. права устанавливаются динамически и их легко можно менять в процессе работы системы. Кроме того, нужно отметить, что в БД Oracle существует встроенный пакет DBMS_RLS в рамках реализации Fine Grained Access Control(FGAC), который осуществляет политику прав доступа на объекты. FGAC начиная с Oracle 8i позволяет во время выполнения динамически добавлять условие (конструкцию WHERE) ко всем запросам, обращенным к таблице или представлению баз данных. Можно проверить, кто выполнял запрос, с какого терминала и когда он выполнялся, а затем создать условие на основе данной информации. Однако средства тщательного контроля доступа доступны только в редакциях Enterprise и Personal Edition; в Standard Edition эти примеры не работают. На данный проект разработчики обладают лицензией на Oracle 10 Standart Edition, соответственно пришлось разрабатывать пакет SecurityData.

Любая информационная система не может состоять только из базы данных, в ней должен быть еще и интуитивно-понятный GUI-интерфейс. Данный интерфейс разрабатывался на языке Java c использованием различных J2EE фреймворков. Этот выбор сделан, потому что язык программирования Java - небольшая, простая для изучения система, оснащённая всесторонне расширяющимся набором API. Разработчики могут «написав однажды, запускать всюду», что даёт языку Java огромное преимущество перед другими языками на рынке. Кроме того, программы на Java на всех операционных системах при компиляции преобразуются к одному и тому же двоичному формату. Выигрыш по сравнению с ситуацией, когда для установки программы на нескольких платформах требуется писать и компилировать код отдельно для каждой платформы, очевиден. Программист может работать над приложением под одной платформой, сокращая при этом время и стоимость разработки, и быть уверенным, что его код будет работать везде. Возможность «написав однажды, запускать всюду», для многих программистов является достаточной причиной для перехода к языку Java от таких языков как C или С++, работоспособность приложений на которых зависит от платформы и, также, приложения являются «несетевыми». В дополнение к этому, возможно создание приложений, многократно использующих общедоступные объекты, что ещё более уменьшает стоимость разработок и позволяет разработчикам концентрировать свои усилия только на создании чего-то нового. Java хороша в основном мощными библиотеками, что в значительной степени избавляет разработчика от написания велосипедов. Ну и автоматическое управление памятью позволяет сосредоточиться на реализации самой задачи. Многие библиотеки, как из стандартной поставки, так и сторонних производителей проверены временем и продолжают совершенствоваться. Кроме того, нельзя не забывать что большинство библиотек и фреймворков свободных в доступе и бесплатны. Более того эти библиотеки, как правило, open-source. Также в Java наблюдается ориентация на Internet-задачи, сетевые распределенные приложения, что как раз и нужно при разработке информационной системы для базы данных разрабатываемой в работе.

Со стороны БД необходимо обеспечить функциональность данный интерфейс, в частности снабдить данную систему поисковым механизмом, обеспечить механизм аутентификации, механизмом разграничения прав на объекты, введение и поддержку пользовательских групп, прав доступа на объекты, поддержка логирования изменения пользовательских данных, поддержка Ajax-технологии со стороны БД, а именно, отображение в выпадающем комбобоксе возможных условий поиска по объектам, поддержка бизнес-логики приложения в целом. В рассматриваемых механизмах, в частности в поисковом, есть много своих нюансов, например, в поисковом механизме пользователю необходимо по его выбору предоставить возможность поиска различными способами: по всем объектам, по нужному пользователю объектному типу, по слову целиком или же по символьному совпадению и так далее.

Нельзя не отметить, что у таких систем требования к производительности и объему БД важны, но при выборе реализации между функциональностью, которая обеспечивает наилучшую производительность или функциональностью, обеспечивающий наименьший объем БД, в связи с активным развитием средств хранения данных, выбор будет сделан в пользу функциональности, обеспечивающей наивысшую производительность, нежели наименьший объем.

Наконец, важно то, что проектируемая в дипломном проекте система не должна работать в режиме 24х7х365. Должна гарантироваться ее работа во время работы архива, а именно в рабочие дневные часы будних дней, а значит обновления базы данных, действия по ее администрированию, репликации и разработке бизнес-логики возможно, даже более того, необходимо проводить или в ночное время будних дней или в выходные и праздничные дни.

1. Выбор модели БД

.1 Исходные требования к проектируемой БД

 

Разрабатываемая база данных (далее БД) предназначена для хранения и обработки информации архива, а именно аудиофайлов, фотофайлов и текстовой информации, которая характеризуется сильной разреженностью данных. Под разреженностью данных здесь понимается отношение занятых позиций данных к количеству всех возможных позиций.

БД должна обеспечивать:

1.       Поддержку модификацию схемы.

2.       СУБД: Oracle.Версия - 10.2.0.4 Standard Edition.

3.       Поддержку 3 языков (русский, английский и немецкий), должна быть реализована возможность переключения между языками.

.        Поддержку безязыкового символьного типа, т.е. типа, значения которого уникально как для русской, так и английской и немецкой версии БД.

.        Поддержку аудита изменения и удаления всех объектов в СУБД.

.        Поддержку логирования изменения и удаления значений атрибутов объектов.

.        Поддержку политики прав доступа к объектам в зависимости от пользователя. Политика безопасности должна обеспечивать разные права на объекты для владельцев объекта и для всех остальных пользователей.

.        Генерацию представлений для клиентского приложения.

.        Генерацию XML документов для клиентского приложения.

.        Механизма поиска, как по объектам, так и по атрибутам объекта.

.        Поддержку работы информационной системы на ОС Solaris Operating System (x86-64).

.        Поддержку хранения в БД фото и аудиодокументов.

Относительный приоритет требований и их предполагаемая трудоемкость отражен в таблице 1.1. Отмечу, что приоритет тем выше, чем меньше оценка, которая стоит в столбце приоритет.

Таблица 1.1. Таблица исходных требований.

№ требования

приоритет

Планируемые трудозатраты, дней

1

1

-

2

1

-

3

2

2

4

4

2

5

3

2

6

3

2

7

3

4

8

2

7

9

2

7

10

2

7

11

1

-

12

1

7


Кратко прокомментирую список исходных требований:

1.       БД должна поддерживать модификацию схемы.

В СУБД Oracle при любой DDL операции производится окончание транзакции и блокировка всех таблиц, над которыми производится данная DDL операция.

2.       СУБД: Oracle.Версия - 10.2.0.4 Standard Edition.

На данный момент разработчики БД в рамках проекта ограничены лицензией на СУБД Oracle Standard Edition.

4.       Поддержка безязыкового символьного типа, т.е. типа, значения которого уникально как для русской, так и английской и немецкой версии БД.

Таким значением, например, является шифр, который уникален и одинаков на любом языке.

7.       Поддержка политики прав доступа к объектам в зависимости от пользователя. Политика безопасности должна обеспечивать разные права на объекты для владельцев объекта и для пользователей, которые не являются.

В БД Oracle существует встроенный пакет DBMS_RLS в рамках реализации Fine Grained Access Control(FGAC), который осуществляет политику прав доступа на объекты. FGAC начиная с Oracle 8i позволяет во время выполнения динамически добавлять условие (конструкцию WHERE) ко всем запросам, обращенным к таблице или представлению баз данных. Можно проверить, кто выполнял запрос, с какого терминала и когда он выполнялся, а затем создать условие на основе данной информации. Однако средства тщательного контроля доступа доступны только в редакциях Enterprise и Personal Edition; в Standard Edition эти примеры не работают. Необходимо разработать пакет, который реализует политику тщательного контроля доступа (FGAC) на СУБД Oracle Standard Edition.

8.       Генерация представлений для клиентского приложения.

Пользовательским схемам даются синонимы на представления пользовательских таблиц. В коде представлений есть фильтрация по разным параметрам предоставляемых данных, в частности по политике прав доступа.

. Генерация XML документов для клиентского приложения.

Пользовательскому GUI-интерфейсу для динамического построения списков данных нужно возвращать динамически генерируемые XML-документы для их последующего вывода в клиентском приложении.

.2 Обзор основных моделей данных современных БД

.2.1 Иерархические базы данных

Иерархическая модель базы данных состоит из объектов с указателями от родительских объектов к потомкам, соединяя вместе связанную информацию. Иерархические базы данных могут быть представлены как дерево, состоящее из объектов различных уровней. Верхний уровень занимает один объект, второй - объекты второго уровня и т. д.

Между объектами существуют связи, каждый объект может включать в себя несколько объектов более низкого уровня. Такие объекты находятся в отношении предка (объект более близкий к корню) к потомку (объект более низкого уровня), при этом возможно, когда объект-предок не имеет потомков или имеет их несколько, тогда как у объекта-потомка обязательно только один предок. Объекты, имеющие общего предка, называются близнецами.

Например, если иерархическая база данных содержала информацию о покупателях и их заказах, то будет существовать объект «покупатель» (родитель) и объект «заказ» (дочерний). Объект «покупатель» будет иметь указатели от каждого заказчика к физическому расположению заказов покупателя в объект «заказ».

В этой модели запрос, направленный вниз по иерархии, прост (например: какие заказы принадлежат этому покупателю); однако запрос, направленный вверх по иерархии, более сложен (например, какой покупатель поместил этот заказ). Также, трудно представить неиерархические данные при использовании этой модели.

Иерархической базой данных является  <#"701130.files/image001.gif">

Рис. 1.1. Диаграмма классов предметной области.

База данных содержит информацию о 101 087 экземплярах товара, распределенных по 588 разделам, в том числе - 84 287 книг, 6 793 периодических изданий, 10 007 наименований кассет. База данных также содержит информацию о 5 243 издательствах и 42 857 авторах книг.

Основные измерения в [3] касались следующих операций:

открытия всей базы данных (запуск программы);

выборки всех данных по одному объекту «Книга» (максимальное количество атрибутов среди всех товаров);

выборки всех данных по одному объекту «Кассета» (минимальное количество атрибутов среди всех товаров);

выборки объекта-контейнера (справочника всех товаров со всеми их атрибутами);

вычисление общей стоимости товаров, добавленных в корзину (взято 7 наименований с различным количеством);

добавления нового объекта «Книга»;

изменения данных объекта «Книга».

Сразу оговорим, что независимо от подхода существует необходимость в поддержке уникальных идентификаторов («id») каждого объекта, по крайней мере - в ветке с корнем «Товар».

.3.1 Объекты как таблицы. Модель ROT

Первым из методов реализации объектно-ориентированного проектирования в реляционных БД рассмотрим подход, известный под названием Representing Objects as Tables (объекты как таблицы) [2] - ROT. Данный подход является наиболее «естественным» для реляционных баз данных. Суть его заключается в том, что каждому классу предметной области ставится в соответствие одна таблица реляционной базы данных с соответствующими атрибутами. Связи реализуются по соответствующим правилам проектирования реляционных баз данных. При этом таблицы для абстрактных классов не создаются, а атрибуты классов-предков присутствуют и в таблицах для классов-потомков.

Реализуемость: подход удобен для быстрой разработки программ, так как все операции над базой данных легко реализуются стандартными конструкциями SQL. Гибкость: очень низкая, практически любые изменения в структуре базы данных неизбежно приводят к необходимости исправления исходного кода. Особенности: нет необходимости в поддержке уникальных идентификаторов в пространстве всей базы данных, в принципе, можно обойтись даже без уникальных идентификаторов ветки «Товар». Объем базы данных и время выполнения почти всех операций - минимальные среди всех рассмотренных подходов [3].

.3.2 Модификация ROT с учетом наследования

Модель ROT напрямую отображает классы предметной области в таблицы реляционной базы данных. Однако, как это было показано выше, это приводит к тому, что некоторые общие данные классов, находящихся в отношении наследования, оказываются расположены в разных таблицах и однотипную обработку данных приходится реализовывать для каждой таблицы в отдельности (в нашем примере - это класс «Товар» и его наследники).

Существует подход, позволяющий решить эту проблему. Суть данного подхода заключается в том, что для суперклассов, имеющих атрибуты или ссылки на другие объекты, создаются соответствующие таблицы, а в таблицы наследников помещаются только идентификатор и атрибуты, доопределенные в классах-наследниках. При этом между таблицей родителя и таблицей наследника устанавливается связь 1:1.

Реализуемость: данный подход в реализации немного сложнее предыдущего, большинство операций также реализуются заранее подготовленными запросами SQL. Гибкость: выше, чем у модели ROT, однако большинство изменений в структуре базы данных также требуют исправления исходного кода программы. Объем базы данных и время выполнения операций - чуть больше, чем у модели ROT [3].

.3.3 Модель А. Тенцера “База-данных-хранилище объектов”

Главной идеей является неизменность схемы базы данных: по сути дела, предложенная в работе [3] схема является универсальной и готовой к использованию в любых объектно-ориентированных приложениях. К тому же заранее определена универсальная реализация методов материализации и дематериализации объектов.

Во-первых, описание свойств классов и связей между ними не дублируется у наследников, а восстанавливается благодаря зависимости Id -ParentId.

Во-вторых, у экземпляра объекта определены все свойства, и поэтому в упомянутые таблицы вносятся записи, соответствующие всем свойствам объекта.

В-третьих, в модели Тенцера отсутствует (явно не выражена) возможность создания атрибутов связи. В нашем примере - это атрибут «Количество», значение которого определяется только при сочетании одного конкретного экземпляра класса «Товар» с одним конкретным экземпляром класса «Корзина». Реализуем решение этого вопроса в виде ассоциативного класса «ТоварВКорзине» с атрибутом «Количество» (рис. 1.2).

Рис. 1.2. Представление атрибута связи в виде ассоциативного класса

В-четвертых, связи в этой модели реализованы только бинарные. В «классическом» проектировании баз данных существует возможность представления трех- и более сторонних связей. Трехстороннюю связь на диаграмме рис. 1.2 преобразуем в две бинарные путем введения дополнительного класса, описывающего связь. В данном случае классом связи может выступить сам ассоциативный класс, поэтому диаграмму на рис. 1.2 можно представить в следующем виде (рис. 1.3).

Рис. 1.3. Представление трехсторонней связи в виде совокупности бинарных отношений

Реализуемость: для реализации в программе данной модели необходимо, в первую очередь, реализовать подсистему управления данными, которая «на лету» собирает объекты. Подход применим при долговременной разработке либо при наличии уже реализованной подсистемы управления данными. Гибкость: высокая, практически все изменения в предметной области требуют внесения исправлений на уровне данных (конфигурирования) и не влияют на исходный код. Особенности - для универсальности программы имеется необходимость поддержки уникального идентификатора в пространстве всей базы данных. Разделение таблиц для атрибутов по типам приводит к необходимости выборки или поиска по всем таким таблицам. В таблицах такой базы данных очень удобно строить списки элементов (справочники). Объем базы данных и время выполнения операций - достаточно высокие, в большинстве тестов - максимальные [3].

.3.4 Модификация модели Тенцера. Модель Entity-Attribute-Value

Рассмотрим возможную модификацию модели Тенцера. Внесенные изменения, с одной стороны, вызваны обобщением подхода: описание атрибутов всех объектов производится в одной таблице Attributes. Хранение значений всех атрибутов объектов производится в пределах одной таблицы. При этом возникают естественные проблемы, связанные с увеличением объема таких данных. Однако объем в данном случае является ценой за универсальность подхода.

С другой стороны, введение таблицы Containers продиктовано соображениями, вытекающими из практического опыта работы. Дело в том, что наиболее часто встречающимся видом ассоциации (кроме наследования) между классами является агрегация. Например, подсистема нормативно-справочной информации любой информационной системы обязательно будет содержать такой вид связи [4].

Наконец, другие виды связи в этой модели реализуются таким же образом, как и в исходном коде объектно-ориентированных программ - через атрибуты, являющиеся ссылками на другие объекты. В данном случае эти ссылки представляют собой внешние ключи, ссылающиеся на идентификатор соответствующего объекта. Значения этих атрибутов также располагаются в таблице ObjectData.

На рис. 1.4 представлена схема базы данных для предлагаемой модели.

Рис. 1.4. Схема базы данных модифицированной модели Тенцера.

Таблица Classes содержит описание классов системы. Атрибут Id - уникальный идентификатор, Parent_Id - ссылка на Id предка в этой же таблице, Caption - короткое (возможно, англоязычное - для исходного кода программы) название класса, Description - подробное описание класса.

Таблица Attributes содержит описание атрибутов классов. Id - уникальный идентификатор атрибута, Class_Id - ссылка на Id класса (в таблице Classes), к которому относится атрибут, Caption и Description - аналогично предыдущему. Для классов-наследников описание атрибутов не повторяется. Таким образом, для материализации описания класса необходимо восстановить всю структуру наследования «вверх» и выбрать описания всех атрибутов классов этого поддерева.

Таблица Objects содержит список экземпляров объектов. Id - уникальный идентификатор объекта, Class_Id - ссылка на Id класса (в таблице Classes), к которому относится экземпляр, Caption - краткое обозначение объекта (для быстрого вывода в списках), формируется программной системой, обычно соответствует значению одного (или комбинации нескольких) из свойств.

Таблица ObjectData содержит значения свойств объектов. Object_Id - ссылка на Id объекта (в таблице Objects), Attribute_Id - ссылка на Id атрибута (в таблице Attributes), Value - значение этого атрибута для данного объекта.

Таблица Containers содержит ключи ассоциации агрегирования. Здесь Container_Id - ссылка на Id объекта-владельца (в таблице Objects), Object_Id - ссылка на Id обекта (там же), содержащегося в контейнере. Сразу оговорим, что агрегирование в данном случае означает «содержит ссылку» и не подразумевает полное владение вложенными объектами.

Таким образом, таблицы Classes и Attributes содержат описание (метаданные), а остальные таблицы - сами данные.

Авторы измерений в [3] не стали касаться вопросов реализации описания типов атрибутов, контроля за совместимостью типов для ссылок и описания ролей классов в ассоциациях, так как это не является существенным для производимых измерений.

Реализуемость: аналогично предыдущей модели требует наличия подсистемы управления данными, облегчает ее реализацию благодаря представлению данных всех типов в одной таблице и требует лишь приведения типов. Гибкость: очень высокая, изменения в предметной области требуют внесения исправлений на уровне данных и не влияют на исходный код программы. Особенности - аналогичны модели Тенцера, для универсальности программы имеется необходимость поддержки уникального идентификатора в пространстве всей базы данных. Однако здесь эту проблему решить проще благодаря меньшему количеству таблиц. Объединение всех атрибутов в одну таблицу облегчает реализацию поиска и выборки их значений. Объем базы данных и время выполнения операций - очень высокие[3].

.3.5 Сравнительный анализ методов реализации объектно-ориентированного проектирования в реляционных БД

Результаты измерения времени выполнения операций и объема базы данных приведены в табл. 1.2 и на рис. 1.5-1.14.

Таблица 1.2. Время выполнения операций и объемы баз данных


В [3] был произведен анализ рассмотренных выше методов реализации объектно-реляционного проектирования в реляционных БД. Ниже изложу основные итоги данного анализа.

Открытие всех таблиц базы данных. Суммарное время открытия всех таблиц базы данных в модели Тенцера и ее модификации значительно превышает этот показатель для ROT и ее модификации (рис. 1.5.). Это связано с «гигантскими» таблицами Objects, Links и т.д.

Рис. 1.5. Открытие всех таблиц базы данных, с

Выборка всех данных по одной Книге. На проведение выборки данных по одной Книге (рис. 1.6, 1.7) не влияет определение типа на этапе выполнения, так как в любом случае количество атрибутов остается одинаковым - максимальным. Хорошие результаты показывает модифицированная модель Тенцера, так как выборка самих значений производится по одной таблице ObjectData.

Рис. 1.6. Выборка всех данных по одной Книге без определения типа, с

Рис. 1.7. Выборка всех данных по одной Книге с определением типа, с

Выборка всех данных по одной Кассете. Общая картина практически не изменяется (см. рис. 1.8.) - остается достаточно большим, стоимость владения такой сложной информационной системой будет значительно ниже, чем выполненной в ROT, так как определяется лишь при универсальном запросе (без определения типа). В случае динамического определения типа товара для модели ROT с наследованием и модели Тенцера происходит резкое уменьшение времени выполнения операции, так как в этом случае запрос строится по меньшему количеству таблиц.

Рис. 1.8. Выборка всех данных по одной Кассете без определения типа, с

Рис. 1.9. Выборка всех данных по одной Кассете с определением типа, с

Выборка всех данных по всем товарам. Результатом такой операции является не просто список наименований, а полная информация о каждом товаре. Поэтому модель Тенцера проигрывает модели ROT, однако значительно опережает ROT с наследованием благодаря меньшему количеству таблиц в таком запросе (см. рис.1.10.).

Рис. 1.10. Выборка всех данных по всем товарам, с

Вычисление суммы товаров в корзине. Время выполнения данной операции в модели Тенцера и ее модификации значительно больше, чем в модели ROT. Связано это с необходимостью учета ссылок через таблицу Links (или Containers) и вытекающим отсюда «каскадированием» запроса. К тому же, в модифицированной модели время вычисления суммы еще больше из-за необходимости преобразования данных строковых типов в числовые.

Рис. 1.11. Вычисление суммы товаров в корзине, с

Добавление и изменение данных одной Книги. Увеличенное время выполнения данных операций в модели Тенцера и ее модификации по сравнению с ROT (см. рис.1.12-1.14), опять же, объясняется более длинными таблицами, в которые вносятся данные. Причиной большого разброса времени выполнения этих операций, видимо, является ненаблюдаемое кэширование данных.

Рис. 1.12. Добавление новой Книги, с

Рис. 1.13. Изменение данных по одной Книге, с

Рис. 1.14. Объем базы данных, МБ

.3.6 Итоговый анализ эффективности методов объектно-ориентированного проектирования в реляционных СУБД

Полученные результаты показывают, что для создания небольших информационных систем, не требующих дальнейшего сопровождения, вполне подходит модель представления классов как таблиц (ROT): она позволяет быстро реализовать все необходимые операции над данными, при этом сами операции выполняются очень быстро, а размер базы данных получается минимальный. Для придания большей гибкости такой системе можно использовать модификацию модели ROT с наследованием (средние системы). При разработке сложных информационных систем, требующих длительного сопровождения и предполагающих дальнейшее развитие, рекомендуется использовать модифицированную модель Тенцера. При этом основной объем работ будет посвящен разработке подсистемы управления данными, оптимизации скорости выполнения операций (при проведении тестов задачи решались «в лоб», без рассмотрения проблемы оптимизации). И хотя время выполнения многих операций в такой модели все равно ценой подсистемы управления данными и ядром интерфейса. При этом практически все вопросы сопровождения программного продукта будут решаться на уровне конфигурирования специалистом квалификации «опытный пользователь» или «администратор ИС». В случае использования ROT, как было описано выше, стоимость сопровождения определяется работой более дорогого специалиста (возможно, нескольких) квалификации «программист».

В данной дипломной работе я ставлю перед собой цель спроектировать и реализовать базу данных (БД в дальнейшем) для одного из архивов нашего замечательного города.

.4 Обоснование выбора Entity-Attribute-Value в качестве метода проектирования Базы Данных

В качестве метода проектирования БД, я выбрал набирающую популярность в наши дни модель Entity-Attribute-Value, более известную в нашей литературе как модифицированная модель Анатолия Тенцера. Приведу причины, по которым я решил остановиться на данной модели.

Во-первых, Гибкость модели. Теоретически не существует ограничений на количество атрибутов на сущность. Число параметров может быть увеличено, когда это необходимо без изменения схемы БД.

Во-вторых, Эффективная организация пространства для сильно рассеянных данных. Отпадает нужда в резервировании места для атрибутов, у которых значения - null. Данная модель предполагает возможное наличие NULL значений для атрибутов, например, сотрудники архива создали новый объект, начали заполнять значения атрибутов, но по каким-либо причинам не заполнили все атрибуты (например, на момент создания объекта было известно значение определенного атрибута). Однако пользователям БД необходимо чтобы данный объект находился в БД (например, чтобы заполнить атрибуты объекта позднее, когда появится соответствующая информация). Механизм полного заполнения значений всех атрибутов объектов недопустим по этой причине, т.к. это приведет к неудобству и невозможности работы пользователей. Однако у данного механизма, очевидно, есть слабое место, а именно вероятность появления дубликатов объектов. Для устранения данной проблемы, для плоских таблиц создаются уникальные индексы на атрибуты, которые определят уникальность данного объекта. Кроме того, необходимо отслеживать объекты, на которые ни один другой объект не ссылается, и удалять их в нужный момент (например, раскрытия дампа на production server). Для выполнения этой задачи спроектирована процедура DropUnusedObjects пакета SystemData.

В-третьих, по данным системных таблиц происходит генерация пользовательских таблиц. Такая модель имеет свои преимущества: например если есть необходимость добавить поле в таблицу или удалить это поле. Если это делать напрямую с помощью DDL операции под живыми пользователями - то произойдет нарушение корректной работы приложения. EAV модель предлагает вместо этого изменить описание таблицы, а затем провести в удобный момент процесс генерации БД. Таким образом, отсутствие потерь данных и бесперебойность работы приложения гарантируется. На мой взгляд, в принципе в production БД не допустимы DDL операции (только как административные задачи и обновления), так как транзакционный DDL - очень сложная, дорогая и потому эксклюзивная операция. Нельзя доверять обычным пользователям приложения права на такие операции, т.к. DDL во время работы блокирует таблицы.

В-четвертых, описание атрибутов всех объектов производится в одной таблице Attributes со структурой. Хранение значений всех атрибутов объектов производится в пределах одной таблицы. При этом возникают естественные проблемы, связанные с увеличением объема таких данных. Однако объем в данном случае является ценой за универсальность подхода.

В-пятых, модель хорошо используется со структурами данных XML(атрибут вставляется между начальными и конечными тегами XML). Это очень важно, т.к. в ближайшем будущем предполагается реализации интеграции информационной системы с внешними сервисами, язык XML для которых, является стандартом.

Кроме того, Entity-Attribute-Value model (EAV) - Сущность - Атрибут - Значение модель - модель данных, в которой одна строка хранит в себе одиночный факт. Модель EAV очень полезна в случаях, когда число параметров, которые потенциально будут применимы к сущности, изменится в большую или меньшую сторону по сравнению с тем, что на данный момент есть. Это представляется весьма полезным ввиду возможной реорганизации работы архива.

Наконец, другие виды связи в этой модели реализуются таким же образом, как и в исходном коде объектно-ориентированных программ - через атрибуты, являющиеся ссылками на другие объекты. В данном случае эти ссылки представляют собой внешние ключи, ссылающиеся на идентификатор соответствующего объекта.

При разработке сложных информационных систем, требующих длительного сопровождения и предполагающих дальнейшее развитие данная модель имеет преимущества. Основной объем работ будет посвящен разработке подсистемы управления данными, оптимизации скорости выполнения операций. И хотя время выполнения многих операций в такой модели все равно останется достаточно большим, стоимость владения такой сложной информационной системой будет довольно низкой, так как определяется лишь ценой подсистемы управления данными и ядром интерфейса, а значит новые проекты при разработанной подсистеме управления данных, будут относительно легки в разработке, а потому дешевы. При этом практически все вопросы сопровождения программного продукта будут решаться на уровне конфигурирования специалистом квалификации «опытный пользователь» или «администратор ИС».

Проектирование БД состоит из двух частей:

1.       Проектирование системных таблиц, которые содержат в себе информацию обо всех несистемных таблиц, т.е. метаданные схемы.

2.       Проектирование несистемных таблиц, которые содержат пользовательские данные.

На основе системных таблиц осуществляется генерация несистемных таблиц в функции doGenerate пакета GenerateInstance. Системные таблицы организованы по модели Entity-Attribute-Value, а несистемные таблицы реализованы в виде плоских таблиц.

Концептуально EAV таблица состоит из 3 составляющих:

1.       ID Сущности/Объекта.

2.       Атрибут/Параметр объекта.

.        Значение атрибута.

2. Разработка БД

.1 Общая архитектура БД информационной системы

Рассмотрим в данной главе, каким образом я решал озвученную в 1 главе постановку задачи и требования системы. База данных состоит из двух частей: EAV-модели, состоящей их системных таблиц и обычной реляционной модели в виде плоских реляционных таблиц. Принципиально важно отметить то, что EAV-модели, состоящей их системных таблиц достаточно для полноценной работы Базы Данных, но в Базу данных были введены плоские реляционные таблицы по двум причинам: во-первых, сложность написания запросов к пользовательским данным в EAV-модели, во-вторых, высокая стоимость, а значит будет затрачиваться относительно большое время на выполнение запросов к пользовательским данным в EAV-модели. Соответственно для ускорения работы выполнения запросов к пользовательским данным была внедрена обычная реляционная модель в виде плоских пользовательских реляционных таблиц.

Составные части общей архитектуры БД отражены на рис2.1.

Рис. 2.1. Составные части архитектуры БД.

Итоговая ER-диаграмма с полным набором объектов БД, состоящей как из системных так и из пользовательских таблиц, представлена на рис. 2.2. Более детальное рассмотрение изложено в главах 2.2. “Модель системных данных” и 2.3. “Модель пользовательских данных”.

Рис. 2.2. ER-диаграмма общей архитектуры БД.

Перейдем к рассмотрению непосредственно архитектуры БД. Рассмотрим вначале модель системных данных, а затем модель пользовательских данных.

.2 Модель системных данных

.2.1 Общая архитектура системных объектов БД

В модели системных данных можно выделить: модель генерации таблиц, модель функциональности добавления, редактирования и удаления объектов, модель функциональности тщательного контроля доступа на уровне объектов, модель аудита и модель поискового механизма. ER-диаграмма модели системных объектов БД показана на рис. 2.3.

.2.2 Описание процесса генерации таблиц

В модели EAV пользовательские таблицы создаются динамически на основе информации системных таблиц в ходе так называемого процесса генерации БД. Процесс генерации заключается в создании или пересоздании, т.е. удалении и создания вновь, схем всех несистемных пользователей БД. Таким образом, будут пересозданы все объекты пользовательских схем: вначале будут созданы пользовательские таблицы, затем на них пользовательские представления. Итак, приведу ER-диаграмму объектов, определяющую создание пользовательских таблиц (рис. 2.4).

Коротко опишу структуру объектов рис.2.4.:

Таблица Datatypes содержит в себе следующие поля:

1.       id - первичный ключ.

2.       name - наименование типа данных.

3.       Usertablename - наименование словаря в котором хранятся значения атрибутов.

4.       Oracledatatype - нейтив тип данных БД Oracle.

Таблица Objecttypes содержит в себе следующие поля:

1.       id - первичный ключ.

2.       Note - наименование объектного типа на русском языке.

3.       Name - наименование объектного типа на английском языке.

Рис. 2.3. ER-диаграмма общей архитектуры системных объектов БД.

Ограничения, индексы, представления и синонимы. Коротко рассмотрим процесс генерации с точки зрения создания пользовательских таблиц. Важно то, что на этот момент должны быть созданы системные таблицы Datatypes, Attributes, Objecttypes и Objects, т.к. на их основе как раз и будут создаваться пользовательские таблицы.

Итак, приведу ER-диаграмму объектов, определяющую создание пользовательских таблиц (рис. 2.4).

Коротко опишу структуру объектов рис. 2.4.

Таблица Datatypes содержит в себе следующие поля:

5.       id - первичный ключ.

6.       name - наименование типа данных.

7.       Usertablename - наименование словаря в котором хранятся значения атрибутов.

8.       Oracledatatype - нейтив тип данных БД Oracle.

Таблица Objecttypes содержит в себе следующие поля:

4.       id - первичный ключ.

5.       Note - наименование объектного типа на русском языке.

6.       Name - наименование объектного типа на английском языке.

Таблица Attributes содержит в себе следующие поля:

1.       id - первичный ключ.

2.       idObjectType - id объектного типа атрибута.

3.       idDataType - id типа данных атрибута.

4.       Length - длина типа данных (только для varchar2).

5.       Name - наименование атрибута объектного типа на английском языке.

6.       Note - наименование атрибута объектного типа на русском языке.

Таблица Objects содержит в себе следующие поля:

1.       id - первичный ключ.

2.       idObjectType - id объектного типа к которому принадлежит этот объект.

3.       ID_OWNER - id владельца на данный объект. Внешний ключ к таблице Users.

4.       ORIGHTS - право владельца на данный объект.

5.       ARIGHTS - право всех пользователей кроме владельца на данный объект.

6.       Created_user - пользователь, который создал объект.

7.       Created_time - время, когда был создан объект.

8.       Last_modified_user - пользователь, который последним изменял объект.

9.       Last_modified_time - время, когда в последний раз объект изменялся.

Рис. 2.4. ER-диаграмма объектов, участвующих в генерации таблиц.

Для создания пользовательских таблиц был создан пакет generateTables. Код этого пакета приведен в приложении 1. Коротко рассмотрим спецификацию пакета.

SQL> CREATE OR REPLACE PACKAGE generateTables IS

procedure doGenerate;

procedure createParentTables;

procedure insertDataParentTables;

END generateTables;

Package created

Таблица 2.1. Комментарии к заголовку пакета generateTables.

Номер строчки кода

Комментарии

3

Процедура doGenerate предназначена для генерации, состоящей из удаления таблиц (если они существуют), создания и вставки значений данных в генерируемые таблицы.

4

Процедура createParentTables предназначена для создания генерируемых таблиц с атрибутами соответвующими объектному типу, для которого создается плоская таблица.

5

Процедура insertDataParentTables предназначена для вставки значений для сгенерированных таблиц.


Небольшие комментарии по реализации тела пакета generateTables:

Таблица 2.2. Комментарии к телу пакета generateTables.

Номера строчек кода

Комментарии

3-19

Процедура dropParentTables предназначена для удаления таблиц (если они существуют) схемы. Обратите внимание, что ее спецификации нету в заголовке пакета generateTables, поэтому она доступна только внутри пакета другим процедурам этого пакета. Создается курсор for curTables IN (select name from objecttypes) LOOP - 7 строка, по которым удаляются таблицы соответствующих объектных типов. Если такой таблицы по какой-либо причине нету, то срабатывает исключение, выводится сообщение о том, что такой таблицы нету, и цикл 7 строки продолжается.

21-38

Процедура createParentTables предназначена для создания генерируемых таблиц с атрибутами соответвующие объектному типу, для которого создается плоская таблица. Для этого создается курсор по всем объектным типам. В переменную сSQLCode, предназначенную для хранения динамического SQL кода, записывается код, который собирается, как совокупность объектного типа  (значение внешнего курсора for curTables IN (select name, id from objecttypes) LOOP - 25 строка кода) и атрибутов ему соответствующих (значения параметризированного внутреннего курсора for curAttributes IN (select name, iddatatype, length from attributes where idobjecttype = curTables.id) LOOP - 27 строка кода).

40-61

Процедура insertDataParentTables предназначена для вставки значений для сгенерированных таблиц. Для этого создается курсор по всем объектным типам. В переменную сSQLCode, предназначенную для хранения динамического SQL кода, записывается код, который собирается, как совокупность объектного типа (значение внешнего курсора for curTables IN (select name, id from objecttypes) LOOP - 45 строка кода) и атрибутов ему соответствующих (значения параметризированного курсора for curAttributes IN (select name, iddatatype, length from attributes where idobjecttype = curTables.id) LOOP - 47 строка кода). Значения в генерируемую таблицу выбираются из системной таблицы userStringValues, которая хранит в поле Value значения для соответветствующего атрибута и объекта (его id задается из внутреннего курсора for curObjects IN (SELECT id from objects where idobjecttype = curTables.id) LOOP - 50 строка кода).

63-68

Процедура doGenerate предназначена для генерации, состоящей из удаления таблиц (если они существуют), создания и вставки значений данных в генерируемые таблицы и состоит из последовательного вызова процедур dropParentTables, createParentTables и insertDataParentTables.


.2.3 Реализация функциональности добавления, редактирования и удаления объектов

Каждый объект в модели EAV состоит из набора присущих ему атрибутов. Эти атрибуты имеют свои значения. У каждого значения атрибута объекта есть свой тип данных. Каждый объект принадлежит конкретному объектному типу. Настройка параметров объекта (т.е. какому объектному типу принадлежит, какой у этого объекта набор атрибутов, типы данных этих атрибутов и т.д.) осуществляется программистом БД). ER-диаграмма объектов БД, участвующих в создании, редактирования или удалении объекта приведена на рис.2.5.

Рис. 2.5. ER-диаграмма объектов БД, участвующих в создании, редактирования или удалении объекта.

Структура и назначение таблиц Objects, Datatypes, Objecttypes и Attributes были рассмотрены чуть выше в описании процесса генерации таблиц. В этой диаграмме новой является таблица Userstringvalues. Опишем ее здесь. Таблица Userstringvalues -это таблица-справочник. Она содержит значения атрибутов, у которых тип данных String(VARCHAR). В этой таблице есть все поля, которые одназначно определят принадлежность данного значения конкретному атрибуту конкретного объекта, а именно:

1.       ID - первичный ключ.

2.       ID_OBJECT - определеяет ID объекта, которому принадлежит значение атрибута.

3.       ID_ATTRIBUTE - определяет ID атрибута, значение которого определено в справочике.

4.       VALUE - значение атрибута.

5.       Created_user - пользователь, который создал объект.

6.       Created_time - время, когда был создан объект.

7.       Last_modified_user - пользователь, который последним изменял объект.

8.       Last_modified_time - время, когда в последний раз объект изменялся.

Таким образом, рассмотрели структуру одного справочника Userstringvalues для типа данных String(VARCHAR). Однако в БД есть и другие типы данных: CLOB, DATE, DICTIONARY, MULTILANG и NUMBER. Для них будут аналогичные по структуре справочники: USERCLOBVALUES, USERDATEVALUES, USERDICTIONARYVALUES, USERMULTILANGVALUES и USERNUMBERVALUES. Стоит отметить, что в качестве значения Value справочника USERDICTIONARYVALUES будет указано id существующего объекта.

.2.4 Реализация функциональности тщательного контроля доступа на уровне объектов

В процессе разработки и внедрения системы я столкнулся с проблемой разграничения прав доступа для разных пользователей. Была предложена система разграничения прав пользователей на основе пакета SecurityData. Этот пакет, в зависимости от контекста подключения, предоставляет пользователю права владельца объекта или по умолчанию. Это важно, т.к. права устанавливаются динамически и их легко можно менять в процессе работы системы. Кроме того, нужно отметить, что в БД Oracle существует встроенный пакет DBMS_RLS в рамках реализации Fine Grained Access Control(FGAC), который осуществляет политику прав доступа на объекты. FGAC начиная с Oracle 8i позволяет во время выполнения динамически добавлять условие (конструкцию WHERE) ко всем запросам, обращенным к таблице или представлению баз данных. Можно проверить, кто выполнял запрос, с какого терминала и когда он выполнялся, а затем создать условие на основе данной информации. Однако средства тщательного контроля доступа доступны только в редакциях Enterprise и Personal Edition; в Standard Edition эти примеры не работают. Как раз на момент разработки у нас была на данный проект лицензия на Oracle 10 Standart Edition, поэтому необходимо было разработать пакет SecurityData.

Итак, приведу ER-диаграмму объектов, определяющую политику тщательного контроля доступа на уровне объектов (рис. 2.6.).

Рис. 2.6. ER-диаграмма объектов тщательного контроля доступа.

В ER-диаграмму объектов тщательного контроля доступа входят 3 таблицы: OBJECTS, USERS и OBJECTPRIVILEGES.

Таблица OBJECTS была рассмотрена выше. Поэтому рассмотрим структуру таблиц USERS и OBJECTPRIVILEGES. Таблица USERS предназначена для хранения информации о пользователях информационной системы. Ее структура:

1.       ID - первичный ключ.

2.       NAME - имя пользователя, т.е. логин.

3.       PASSWORD - пароль пользователя.

4.       NOTE - краткие комментарии о пользователе.

5.       Created_user - пользователь, который создал объект.

6.       Created_time - время, когда был создан объект.

7.       Last_modified_user - пользователь, который последним изменял объект.

8.       Last_modified_time - время, когда в последний раз объект изменялся.

Таблица OBJECTPRIVILEGES предназначена для хранения информации о видах прав на объект. Ее структура:

1.       ID - первичный ключ.

2.       NAME - наименование привелегии

3.       NOTE - краткие о привелегии.

Для реализации вышеозвученной задачи была принята следующая архитектура определения права на объект:

1.       Если пользователь, вызывающий объект, является его владельцем, т.е. его логин совпадает с полем owner, указанным в таблице objects, тогда пользователю назначаются права владельца объекта, т.е. значение поля orights таблицы objects. Иначе идем в п.2.

2.       Пользователю устанавливается право по умолчанию - значение поля arights таблицы objects для данного объекта.

Принято 3 категории прав:

Таблица 2.3. Классификация прав на объекты.

Что дает это право

0

Пользователю не дается никаких прав на объект, в том числе на просмотр.

1

Пользователю дается право read-only, т.е. он может только просматривать объект, но не имеет права его изменять или удалять.

2

Пользователю даются все права на объект, в том числе он может изменять, просматривать и удалять объект.

Для вышеозвученной политики был реализован пакет SECURITYDATA. Его спецификация:

SQL> CREATE OR REPLACE PACKAGE SECURITYDATA

AS

FUNCTION checkRights(idObject NUMBER) RETURN NUMBER;

FUNCTION checkRights(idObject NUMBER, oright NUMBER, owner VARCHAR2, aright NUMBER) RETURN NUMBER;

END SECURITYDATA;

/created

Таблица 2.4. Комментарии к заголовку пакета SECURITYDATA.

номер строчки кода

Комментарии

3

Функция checkRights предназначена для динамического определения прав вызывающего пользователя на объекты idObject.

4

Это перегруженная версия функции checkRights 3 строчки кода. Необходима для ускоренного динамического определения прав вызывающего пользователя на объекты idObject, для этого все параметры объекта должны быть определены заранее.


Для отображения на клиенте необходимо данные о правах из таблиц объектов, определяющих политику тщательного контроля доступа рис.2.2. представить в виде XML-документа. Для этого существует пакет Datamodification, его листинг приведен в приложении 1. Выходной документ должен содержать информацию о владельце, правах владельца, пользовательских группах в которые входит вызывающий, права пользовательских групп на этот объект и права пользовательских групп по умолчанию, а также право по умолчанию - т.е. для пользователей, которые не являются владельцами и не входят в пользовательские группы. Соответственно этому приложению выводится следующий XML-документ:

<object_rights ID_OBJECT="33760">

<owner>VMG</owner>

<owner_right>2</owner_right>

<others_right>1</others_right>

</object_rights>

Верхний тег object_rights содержит один атрибут - это id объекта. В нем 2 вложенных элемента: owner, owner_rights. В теге owner указывается информация о владельце объекта, в теге owner_rights - права владельца на объект, в теге others_right - право по умолчанию - т.е. для пользователей, которые не являются владельцами и не входят в пользовательские группы.

.2.5 Реализация аудита на изменение объектов

В процессе коммерческой эксплуатации приложения часто возникают такие моменты, когда необходимо просмотреть кто, когда и как изменил клиентские данные и если, возможно, то и восстановить их. Это требование было отражено в техническом задании к работе. Для реализации этого требования я ввел процедуру аудита пользовательских объектов (т.е. данных пользовательских таблиц). При изменении, добавлении или удалении объектов данные происходит соответствующая DML-операция в таблице objects и user*values(т.е. таблицах справочниках - userclobvalues, userdatevalues, userdictionaryvalues, usermultilangvalues, usernumbervalues, userstringvalues). Для логирования были написаны триггеры, срабатывающие на каждую DML-операцию вышеперечисленных таблиц. В теле таких триггеров в зависимости от типа DML-операции(INSERT, UPDATE, DELETE) и типа данных изменненого атрибута осуществляется соответствующая запись в целевую таблицу лога (userclobvalueslog, userdatevalueslog, userdictionaryvalueslog, usermultilangvalueslog, usernumbervalueslog, userstringvalueslog), а также производится запись в пользовательскую плоскую таблицу соответсвующего объектного типа с целью немедленного изменения данных, показываемых пользователям информационной системы.

В системе используется 6 типов данных: это Clob, Date, Dictionary, Multilang, Number, String. Метаинформация этих типов содержится в системной таблице datatypes. Соответствие типов данных приложения - нейтив типам СУБД Oracle приведено в таблице 2.4.

Таблица 2.4. Соответствие типов данных приложения - нейтив типам СУБД Oracle

Тип данных приложения

Фактический тип данных в СУБД Oracle

Предназначение

1

CLOB

CLOB

Для хранения значений больших текстовых полей

2

DATE

DATE

Для хранения значений полей дат

3

DICTIONARY

NUMBER

Для хранения значений ссылки на id объекта (например, если атрибут - это ссылка на другой объект)

4

MULTILANG

VARCHAR2(4000)

Для хранения значений незначительных по длине текстовых полей. Предназначен для текстовых полей, значения которых должно быть уникально вне зависимости от текущего языка приложения(например поле шифр документа).

5

NUMBER

NUMBER

Для хранения значений числовых полей.

6

STRING

VARCHAR2(4000)

Для хранения значений незначительных по длине текстовых полей. Предназначен для текстовых полей, значения которых должно быть от текущего языка приложения


Таблицы логов, т.е. user*valueslog по своей структуре близки друг к другу и дабы не повторяться можно рассмотреть таблицу Userstringvalues, остальные аналогичны ей по структуре. Итак:

SQL> desc userstringvalueslogType Nullable Default Comments NUMBER _OBJECT NUMBER Y _ATTRIBUTE NUMBER Y_VALUE VARCHAR2(4000) Y _VALUE VARCHAR2(4000) Y_USER VARCHAR2(50) Y user _TIME DATE Y sysdate _OF_OPERATION VARCHAR2(20)

Рис. 2.7. ER-диаграмма аудита таблицы Userstringvalues.

ER-диаграмма объектов аудита данной таблицы приведена на рис.2.7. Кратко опишу основные поля таблицы Userstringvalueslog.

1.       ID - первичный ключ.

2.       ID_OBJECT - foreign key на id таблицы objects. Определяет объект, на который ввелся аудит.

3.       ID_ATTRIBUTE - foreign key на id таблицы attributes. Определяет атрибут объекта, на который ввелся аудит.

4.       OLD_VALUE - старое значение атрибута.

5.       NEW_VALUE - новое значение атрибута.

6.       MODIFIED_USER - пользователь, изменивший атрибут.

7.       MODIFIED_TIME - время изменения атрибута.

8.       TYPE_OF_OPERATION - тип операции, т.е. INSERT, UPDATE или DELETE.

Как было упомянуто выше с целью логирования были написаны триггеры, срабатывающие на каждую DML-операцию вышеперечисленных таблиц. В теле таких триггеров в зависимости от типа DML-операции(INSERT, UPDATE, DELETE) и типа данных изменненого атрибута осуществляется соответствующая запись в целевую таблицу лога (userclobvalueslog, userdatevalueslog, userdictionaryvalueslog, usermultilangvalueslog, usernumbervalueslog, userstringvalueslog), а также производится запись в пользовательскую плоскую таблицу соответсвующего объектного типа с целью немедленного изменения данных, показываемых пользователям информационной системы. Приведу код триггера USERSTRINGVALUES_AUDIT, который осуществляет логирование строковых данных в таблицу USERSTRINGVALUESLOG:

SQL> CREATE OR REPLACE TRIGGER USERSTRINGVALUES_AUID

AFTER INSERT OR UPDATE OR DELETE ON USERSTRINGVALUES FOR EACH ROW

BEGIN

IF inserting THEN

INSERT INTO USERSTRINGVALUESLOG(ID, ID_OBJECT, ID_ATTRIBUTE, OLD_VALUE, NEW_VALUE, TYPE_OF_OPERATION)

VALUES(SequencesData.createId(), :NEW.IDOBJECT, :NEW.IDATTRIBUTE, :OLD.value, :NEW.value, 'INSERT');

ELSIF updating THEN

INSERT INTO USERSTRINGVALUESLOG(ID, ID_OBJECT, ID_ATTRIBUTE, OLD_VALUE, NEW_VALUE, TYPE_OF_OPERATION)

VALUES(SequencesData.createId(), :NEW.IDOBJECT, :NEW.IDATTRIBUTE, :OLD.value, :NEW.value, 'UPDATE');

ELSIF deleting THEN

INSERT INTO USERSTRINGVALUESLOG(ID, ID_OBJECT, ID_ATTRIBUTE, OLD_VALUE, NEW_VALUE, TYPE_OF_OPERATION)

VALUES(SequencesData.createId(), :NEW.IDOBJECT, :NEW.IDATTRIBUTE, :OLD.value, :NEW.value, 'DELETE');

END IF;

END;

/

Триггеры на остальные таблицы лога (userclobvalueslog, userdatevalueslog, userdictionaryvalueslog, usermultilangvalueslog, usernumbervalueslog) аналогичны триггеры USERSTRINGVALUES_AUDIT. На поля MODIFIED_TIME и MODIFIED_USER установлены значения по умолчанию, которые определены как sysdate и user соответственно.

Для отображения на клиенте необходимо данные из таблиц логирования представить в виде XML-документов. Для этого существует пакет Datamodification, его листинг приведен в приложении 1. Аудит проводится по 3 параметрам: по атрибуту, по объекту и объектному типу. Соответственно этому приложению выводится 3 типа XML-документов. Например, для аудита выходной документ будет таким:

<attribute_summary ID="643968">

<transaction MODIFIED_TIME="19-11-2009 19:41:56" MODIFIED_USER="VMG">

<attribute ID_ATTRIBUTE="643968" TYPE_OF_OPERATION="INSERT" ATTRIBUTE_NOTE="имя" ATTRIBUTE_DATATYPE="MULTILANG">

<old_value_attribute></old_value_attribute>

<new_value_attribute>1</new_value_attribute>

</attribute>

</transaction>

</attribute_summary>

Верхний тег attribute_summary содержит один атрибут - это id атрибута. В нем вложенный элемент transaction, в котором 2 атрибута: MODIFIED_TIME - время транзакции, MODIFIED_USER - пользователь, осуществивший транзакцию. В элементе transaction - есть вложенный элемент attribute, который содержит 4 атрибута: ID_ATTRIBUTE - id атрибута, TYPE_OF_OPERATION - тип совершенной операции, ATTRIBUTE_NOTE - имя атрибута, ATTRIBUTE_DATATYPE - тип данных атрибута, а также содержит 2 вложенных элемента - old_value_attribute(определяет значение этого атрибута до транзакции) и new_value_attribute(определяет значение этого атрибута после транзакции).

Структура XML для объекта и объектного типа будет другой, более сложной. Так как объект представляет собой совокупность атрибутов - то нужно собрать аудит транзакций всех атрибутов объекта и представить в виде вложенных тегов XML-документа. Таким образом, будет добавлен верхний тег object_summary, содержащий id объекта, а в нем будет коллекция XML-элементов аудита по всем атрибутам данного объекта. Пример такого документа:

<object_summary ID="51994">

<transaction MODIFIED_TIME="19-11-2009 19:36:56" MODIFIED_USER="VMG">

<attribute ID_ATTRIBUTE="643968" TYPE_OF_OPERATION="UPDATE" ATTRIBUTE_NOTE="Name" ATTRIBUTE_DATATYPE="MULTILANG">

<old_value_attribute>9</old_value_attribute>

<new_value_attribute>12</new_value_attribute>

</attribute>

</transaction>

<transaction MODIFIED_TIME="19-11-2009 18:12:35" MODIFIED_USER="VMG">

<attribute ID_ATTRIBUTE="643968" TYPE_OF_OPERATION="UPDATE" ATTRIBUTE_NOTE="Name" ATTRIBUTE_DATATYPE="MULTILANG">

<old_value_attribute>7</old_value_attribute>

<new_value_attribute>9</new_value_attribute>

</attribute>

</transaction>

</object_summary>

Для вывода аудита по объектному типу для выходного XML-документа нужно собрать информацию по всем транзакциям всех объектов данного типа. Для такого документа структуру я применил следующую структуру:

<object_type IDOBJECTTYPE="1">

<objects_summary>

<transaction MODIFIED_TIME="19-11-2009 19:36:56" MODIFIED_USER="VMG">

<object_info object_id="51994">

<attribute ID_ATTRIBUTE="643968" TYPE_OF_OPERATION="UPDATE" ATTRIBUTE_NOTE="Name" ATTRIBUTE_DATATYPE="MULTILANG">

<old_value_attribute>9</old_value_attribute>

<new_value_attribute>12</new_value_attribute>

</attribute>

</object_info>

</transaction>

<transaction MODIFIED_TIME="19-11-2009 18:12:35" MODIFIED_USER="VMG">

<object_info object_id="51994">

<attribute ID_ATTRIBUTE="643968" TYPE_OF_OPERATION="UPDATE" ATTRIBUTE_NOTE="Name" ATTRIBUTE_DATATYPE="MULTILANG">

<old_value_attribute>7</old_value_attribute>

<new_value_attribute>9</new_value_attribute>

</attribute>

</object_info>

</transaction>

</objects_summary>

</object_type>

Так как объект представляет собой совокупность атрибутов - то нужно собрать аудит транзакций всех атрибутов объекта и представить в виде вложенных тегов XML-документа. Таким образом, будет добавлен верхний тег object_type, содержащий id объектного типа, а в нем будет находиться коллекция XML-элементов аудита по всем объектам данного объектного типа.

.2.6 Реализация механизма поиска объектов

Поисковый механизм должен осуществлять поиск по объектам по определенным заранее неизвестным параметрам, задаваемым пользователями во время их работы. Так, например, пользователь захочет найти все фотодокументы выпущенные после 1930 до 1950 года, в Северо-Западном регионе или найти рукописи в которых есть определенное слово и т.д. Как видно, здесь будет осуществляться поиск по атрибутам с определенными критериями. Эти критерии описаны в таблице conditions. Ее структура:

1.       ID - первичный ключ.

2.       Смысловое описание параметра поиска.

На данный момент в таблице conditions заданы следующие параметры поиска:

Таблица 2.5. Возможные поисковые параметры.

ID

Смысловое описание параметра поиска

1

Содержит слово

2

Не содержит слово

3

Ровно

4

Не равно

5

Содержит

6

Больше

7

Больше или равно

8

Меньше

9

Меньше или равно

10

Не содержит

11

Не заполнено

12

Заполнено

13

Слово начинается


Понятно, что не всем атрибутам должны быть доступны все параметры поиска. По строковым атрибутам скорее всего будет осуществляться поиск по параметрам: “Содержит слово”, “Не содержит слово”, “Слово начинается” и т.д., однако не будет поиска по параметрам “Больше”или “Меньше или равно”. И для числовых типов должен осуществляться поиск по по параметрам “Больше”или “Меньше или равно”, но не будет осущестляться поиск по параметрам “Содержит слово”,“Не содержит слово”, “Слово начинается”. Эти соответствия задаются в таблице Conditiondatatypes, имеющей следующую структуру:

1.       ID - первичный ключ.

2.       IDATTRIBUTE - атрибут для которого задается соответствие.

3.       IDCONDITION - поисковый параметр доступный для атрибута.

4.       FDEFAULT - поисковый параметр для атрибута по умолчанию.

Таким образом, ER-диаграмма объектов, определяющих параметры поиска, приведена на рис. 2.8. Структура и назначение таблиц Attributes и Datatypes приведены выше, поэтому здесь их описывать смысла нету.

Рис. 2.8. ER-диаграмма объектов, определяющих параметры поиска.

Выбранные поисковые атрибуты необходимо где-то сохранить, чтобы в процессе поиска искать объекты, удовлетворяющие этим поисковым параметрам. С этой целью была создана временная таблица на время транзакции (т.е. использовалась конструкция temporary table SEARCHPARAMETERS on commit delete rows -которая позволяет создавать временные таблицы на уровне транзакции, так что при COMMIT или ROLLBACK данные из этой таблицы удаляются[5]). Таблица SEARCHPARAMETERS имеет следующую структуру:

1.       ID поискового параметра - первичный ключ.

2.       IDSEARCHOBJECTTYPE - id объектного типа, по которому осуществляется поиск.

3.       IDATTRIBUTE - id атрибута, для которого задается поисковый параметр. Foreign Key для таблицы Attributes.

4.       IDCONDITION - id поискового атрибута для параметра. Foreign Key для таблицы Conditions.

.        IDLANGUAGE - id языка, по которому будет осуществляться поиск. Foreign Key для таблицы Languages.

.        VALUE - значение поискового параметра(так если будет производиться поиск по параметру “Слово начинается с “утре”” - то значение VALUE будет “утре”, если по параметру “Больше 20” - то значение VALUE будет “20” и т.д.).

После выбора и инициализации поисковых параметров, а значит заполнения полей таблицы SEARCHPARAMETERS будет произведен поиск по объектам объектного типа поля IDSEARCHOBJECTTYPE. Поиск осуществляется с помощью пакета SearchData - его листинг в приложении 1.

Рис. 2.9. ER-диаграмма объектов, осуществляющие поисковый механизм.

Найденные значения вставляются во временную таблицу TEMPFOUNDOBJECTS. Она аналогично таблице SEARCHPARAMETERS является временной на уровне транзакции (т.е. с использованием конструкции on commit delete rows). Таблица TEMPFOUNDOBJECTS имеет следующую структуру:

1.       ID - это ID найденного объекта.

2.       OBJECTSERIAL - это серийный номер найденного объекта, задает порядок вывода найденный объектов.

Учитывая вышесказанное, ER-диаграмма объектов, осуществляющие поисковый механизм, будет следующей (см. рис. 2.9.).

2.3 Модель пользовательских данных

.3.1 Общая архитектура пользовательских объектов БД

Общая архитектура пользовательских объектов БД приведена на рис. 2.10.

Рис. 2.10. Общая архитектура пользовательских объектов БД.

Архитектура пользовательских объектов БД состоит из 3 основных частей:

1.       Объектов определяющих хранение фотодокументов архива.

2.       Объектов определяющих хранение фонодокументов архива.

.        Всех остальных пользовательских объектов.

Подробное описание каждой из частей архитектуры пользовательских объектов БД привожу ниже.

.3.2 ER-диаграмма фотодокументов архива

Один из основных типов документов, хранимых в БД являются фотодокументы. ER-диаграмма определяющая хранимые в БД фотодокументы приведена на рис. 2.11. Кратко опишу структуру входящих в эту ER-диаграмму объектов БД:

Рис. 2.11. ER-диаграмма фотодокументов архива.

Таблица Photodocuments определяет хранящиеся в БД фотодокументы архива. В таблице есть следующий колонки:

1.       ID - первичный ключ. Определяет id фотодокумента, является внешним ключом к id таблицы objects.

2.       SHOOTAUTHOR - Автор съемки. Существуют 3 колонки SHOOTAUTHOR: SHOOTAUTHOR1, SHOOTAUTHOR2, SHOOTAUTHOR3 соответственно для хранения инициалов автора съемки на русском, английском и немецком языках.

3.       DEED - id акта приема-передачи фотодокумента на хранение.

4.       ANNOTATION - аннотация.

5.       KIND - определяет id вида фотодокумента.

6.       SHOOTDATE - Дата съемки.

7.       IMAGE - само изображение.

8.       NUMBERNEGATIVES - количество негативов.

9.       NOTESHOOTPLACE - Комментарий к месту съемки.

10.     INSURANCECODE - Номер страхового договора на фотодокумент архива.

11.     NOTE - Примечание.

12.     DOCSIZE - id размера фотодокумента.

13.     COMPILER - id cоставителя записи.

14.     CODE -шифр фотодокумента.

Таблица SIZES определяет размеры документов, хранящиеся в БД. ЕЕ структура:

1.       ID - первичный ключ.

2.       NAME1 - размер документа на русском языке.

3.       NAME2 - размер документа на английском языке.

4.       NAME3 - размер документа на немецком языке.

Таблица STAFF определяет сотрудников, работающих в архиве. Структура таблицы:

1.       ID - первичный ключ.

2.       NAME1 - ФИО сотрудника на русском языке.

3.       NAME2 - ФИО сотрудника на английском языке.

4.       NAME3 - ФИО сотрудника на немецком языке.

5.       AKKNAME1 - размер документа на русском языке.

6.       AKKNAME2 - размер документа на английском языке.

7.       AKKNAME3 - размер документа на немецком языке.

8.       POSITION - id должности, занимаемой сотрудником.

Таблица Positions определяет должности, которые занимают сотрудники архива. Структура таблицы:

1.       ID - первичный ключ.

2.       NAME1 - Название должности на русском языке

3.       NAME2 - Название должности на английском языке

4.       NAME3 - Название должности на немецком языке.

Таблица ReceivingDeeds определяет акты приема-передачи. Структура таблицы:

1.       ID - первичный ключ.

2.       DEEDNUMBER - номер акта.

3.       DEEDDATE - дата оформления акта.

4.       INSPECTOR - id приемщика акта.

Таблица Inspectors определяет приемщиков актов. Структура таблицы:

1.       ID - первичный ключ.

2.       NAME1 - ФИО приемщика на русском языке.

3.       NAME2 - ФИО приемщика на английском языке.

4.       NAME3 - ФИО приемщика на немецком языке.

.3.3 ER-диаграмма фонодокументов архива

Один из основных типов документов, хранимых в БД являются фонодокументы. ER-диаграмма определяющая хранимые в БД фонодокументы приведена на рис. 2.12. Кратко опишу структуру входящих в эту ER-диаграмму объектов БД:

Таблица Phonodocuments определяет хранящиеся в БД фонодокументы архива. В таблице есть следующий колонки:

1.       ID - первичный ключ. Определяет id фонодокумента, является внешним ключом к id таблицы objects.

2.       DEED - id акта приема-передачи фотодокумента на хранение.

3.       CODE -шифр фотодокумента. Тип атрибута MULTILANG - т.е. значение шифра одинаково на всех языках, поддерживаемых БД.

4.       NAME1 - Наименование фонозаписи на русском языке.

5.       NAME2 - Наименование фонозаписи на английском языке.

6.       NAME3 - Наименование фонозаписи на немецком языках.

7.       TYPE - тип фонозаписи, внешний ключ к таблице MUSICTYPES.

8.       CREATIONDATE - дата создания фонозаписи.

9.       CREATIONPLACE - место создания фонозаписи, внешний ключ к таблице MUSICPRODUCTIONPLACES.

10.     SHOOTAUTHOR - Автор съемки. Существуют 3 колонки SHOOTAUTHOR: SHOOTAUTHOR1, SHOOTAUTHOR2, SHOOTAUTHOR3 соответственно для хранения инициалов автора съемки на русском, английском и немецком языках.

11.     NOTE1 - Примечание к фонодокументу на русском языке.

12.     NOTE2 - Примечание к фонодокументу на английском языке.

13.     NOTE3 - Примечание к фонодокументу на немецком языке.

14.     COMPILER - составитель фонозаписи, внешний ключ к таблице STAFF.

15.     COMPILEDATE - дата составления фонозаписи.

Рис.2.12. ER-диаграмма хранения фонодокументов архива.

Таблица MUSICTYPES определяет типы фонодокументов, хранимых в БД. Ее структура:

1.       ID - первичный ключ.

2.       NAME1 - Наименование типа фонодокумента на русском языке.

3.       NAME2 - Наименование типа фонодокумента на английском языке.

4.       NAME3 - Наименование типа фонодокумента на немецком языке.

Таблица MUSICPRODUCTIONPLACES определяет места издания фонодокументов, хранимых в БД. Ее структура:

1.       ID - первичный ключ.

2.       NAME1 - Наименование места издания фонодокумента на русском языке.

3.       NAME2 - Наименование места издания фонодокумента на английском языке.

4.       NAME3 - Наименование места издания фонодокумента на немецком языке.

Таблицы Insectors, Receivingdeeds, Staff и Positions описаны выше в разделе 2.7.1. ER-диаграмма фотодокументов архива.

.3.4 ER-диаграмма остальных пользовательских объектов

Кроме фонодокументов и фотодокументов в БД хранятся новости, информация о выставках архива и веб-страницы сайта архива. ER-диаграмма вышеперечисленных пользовательских данных приведена на рис. 2.13. Кратко опишу структуру входящих в эту ER-диаграмму объектов БД:

Таблица EXHIBITIONS определяет информацию о проведенных или планируемых к проведению выставках. Ее структура:

1.       ID - первичный ключ.

2.       NAME1 - Наименование выставки на русском языке.

3.       NAME2 - Наименование выставки на английском языке.

4.       NAME3 - Наименование выставки на немецком языке.

5.       NOTE1 - Примечание о проводимой выставке на русском языке.

6.       NOTE1 - Примечание о проводимой выставке на английском языке.

7.       NOTE1 - Примечание о проводимой выставке на немецком языке.

8.       COMPILEDATE - дата составления записи. На значение поля установлено значение по умолчанию в виде текущего времени и даты.

Таблица NEWS содержит информацию о новостях архива, публикуемых на сайте для посетителей архива. Ее структура:

1.       ID - первичный ключ.

2.       HEADER1 - Заголовок новости на сайте на русском языке.

3.       HEADER2 - Заголовок новости на сайте на английском языке.

4.       HEADER3 - Заголовок новости на сайте немецком языке.

5.       CONTENT1 - Содержимое статьи о новости на сайте на русском языке.

6.       CONTENT2 - Содержимое статьи о новости на сайте на английском языке.

7.       CONTENT3 - Содержимое статьи о новости на сайте на немецком языке.

8.       COMPILEDATE - дата составления новости. На значение поля установлено значение по умолчанию в виде текущего времени и даты.

Рис. 2.13. ER-диаграмма объектов БД, определящих хранимую информацию о выставках, новостях и вебстраницах веб-сайта.

Таблица WEBPAGES содержит информацию о веб-страницах сайта архива. Ее структура:

1.       ID - первичный ключ.

2.       NAME1 - Наименование веб-страницы на русском языке.

3.       NAME2 - Наименование веб-страницы на английском языке.

4.       NAME3 - Наименование веб-страницы на немецком языке.

5.       CONTENT1 - Информация о содержимом веб-сайта на русском языке.

6.       CONTENT2 - Информация о содержимом веб-сайта на английском языке.

7.       CONTENT3 - Информация о содержимом веб-сайта на немецком языке.

.3.5 Представления пользователя приложения

Перейдем теперь к рассмотрению работы политики тщательного контроля доступа к объектам. Напомню, что в 7 пункте списка исходных требований сказано, что в БД необходимо разработать политику прав доступа к объектам в зависимости от пользователя. Политика безопасности должна обеспечивать разные права на объекты для владельцев объекта, для пользовательских групп и для пользователей, которые не являются ни владельцами ни входят в пользовательские группы.

Важно отметить, что пользователь информационной системы, подключаясь к БД из клиентского приложения не имеет гранта на просмотр пользовательских таблиц, он имеет доступ только к представлениям, которые сгенерированы на пользовательских таблицах. Это сделано для функционирования политики тщательного контроля доступа к объектам. Поясню: создается представление к пользовательской таблице с фильтрацией по функции checkrights пакета SECURITYDATA, которому передается в качестве параметра id объекта, для которого нужно определить доступ. Функция возвращает право пользователя на данный объект. Например, для таблицы NEWS будет создано представление NEWS_VIEW1(см. рис.2.14.).

Рис. 2.14. Представления пользователя приложения, определяющие хранимые в БД новости.

Код представления будет таков:> CREATE OR REPLACE VIEW NEWS_VIEW1

AS SELECT ID, HEADER1, BRIEFDESCRIPTION1, FULLDESCRIPTION1, COMPILEDATE

FROM NEWS

WHERE SECURITYDATA.checkRights(ID)>0 created

Стоит обратить внимание что, в названии представления последним символом указана цифра1 - это обозначение языка системы, для которого представление сгенерировано. Т.к. в БД должна быть реализована поддержка 3 языков - то и представлений будет 3(см. таб.2.6.)

Таблица 2.6. Соответствие названия представления языку приложения.

Название представления

Язык БД, для которого представление создано

1

NEWS_VIEW1

Русский

2

NEWS_VIEW2

Английский

3

NEWS_VIEW3

Немецкий


Код представления соответственно для английского языка БД будет таков:

SQL> CREATE OR REPLACE VIEW NEWS_VIEW2

AS SELECT ID, HEADER1, BRIEFDESCRIPTION2, FULLDESCRIPTION2, COMPILEDATE

FROM NEWS

WHERE SECURITYDATA.checkRights(ID)>0 created

Код представления соответственно для немецкого языка БД будет таков:

SQL> CREATE OR REPLACE VIEW NEWS_VIEW3

AS SELECT ID, HEADER3, BRIEFDESCRIPTION3, FULLDESCRIPTION3, COMPILEDATE

FROM NEWS

WHERE SECURITYDATA.checkRights(ID)>0 created

Логика определения права пользователя на объект описана выше в главе “Реализация функциональности тщательного контроля доступа на уровне объектов.

Представления фонодокументов

Аналогично новостям для фонодокументов тоже будут сгенерированы 3 представления: Phonodocuments_View1, Phonodocuments _View2, Phonodocuments _View3(см.рис. 2.15.)

Рис.2.15. Представления пользователя приложения, определяющие хранимые в БД фонодокументы.

Для фотодокументов будут сгенерированы 3 представления: Photodocuments_View1, Photodocuments _View2, Photodocuments _View3(см.рис.2.16.)

Рис. 2.16. Представления пользователя приложения, определяющие хранимые в БД фотодокументы.

Представления веб-страниц.

Аналогично новостям для веб-страниц тоже будут сгенерированы 3 представления: Webpages_View1, Webpages_View2, Webpages_View3(см. рис.2.17.)

Рис. 2.17. Представления пользователя приложения, определяющие хранимые в БД веб-страницы.

Представления выставок.

Для выстовок будут сгенерированы 3 представления: Exhibitions_View1, Exhibitions_View2, Exhibitions _View3(см.рис.2.18.)

Рис. 2.18. Представления пользователя приложения, определяющие хранимые в БД выставки.

3. Апробация функционирования БД

.1 Описание работы БД как основной части информационной системы

При загрузке информационной системы загружается окно логирования, в котором предлагается пройти процедуру аутентификации. В этом окне необходимо ввести логин и пароль. Введенные данные будут проверены на соответствие пары логин/пароль учетной записи в базе данных. При неуспешной процедуре аутентификации данное окно появится снова с запросом логина/пароля. В случае успешной авторизации появится доступ к интерфейсу информационной системы. В этом интерфейсе будет предоставлена возможность выбора объектного типа, с которым пользователь хочет работать (см. рис.3.1.). В проектируемой информационной системе пользователю следующие объектные типы: Акты приема-передачи, веб-страницы, новости, фотодокументы, фонодокументы.

Рис 3.1. Внешний вид интерфейса информационной системы.

Выбор объектного типа.

В клиентском приложении согласно техническому заданию должен быть реализован вывод объектов как по определенным параметрам так и всех объектов данного объектного типа. Выбор вида вывода объектов задается соответствующим списком (см. рис.3.2.).

Рис. 3.2. Выбор механизма показа объектов (все объекты или только те, что удовлетворяют определенным критериям)

В случае выбора меню список будет осуществлен вывод в виде списка всех объектов выбранного объектного типа. Если же пользователь выбрал вывод объектов в виде параметра поиска - то ему будет предложено набрать поисковую форму, в которой он должен выбрать согласно алгоритму изложенному в главе “Реализация механизма поиска” атрибуты объекта, по которым ввести поиск (см. рис.3.3.) и задать поисковые условия, по которым осуществлять поиск по атрибутам объектов (см. рис. 3.4.). В этой форме фактически задаются поля таблицы SearchParameters описанной выше.

Рис. 3.3. Выбор атрибутов по которым искать объекты.

Рис. 3.4. Выбор поисковых условий по которым искать объекты.

После указания атрибутов и поисковых условий необходимо определить шаблон значения атрибута по которому ввести поиск (см. рис. 3.5.). Значение поискового параметра (так если будет производиться поиск по параметру “Слово начинается с “утре”” - то значение атрибута в данной поисковой форме (которое задаст значение поля VALUE таблицы SearchParameters) будет “утре”, если по параметру “Больше 20” - то значение VALUE будет “20” и т.д.).

Рис. 3.5. Выбор поисковых параметров.

После задания поисковых параметров и выбора атрибутов, по которым ввести поиск, будет произведен поиск объектов и осуществлен вывод всех объектов, которые удовлетворяют условиям поиска (см. рис. 3.6.). Вывод объектов в виде списка будет осуществлен в форме такого же интерфейса.

Рис. 3.6. Выбор механизма показа объектов(все объекты или только те что удовлетворяют определенным критериям)

Также в техническом задании необходимо обеспечить поддержку как минимум 2 языков: английского и русского. Для переключения языка пользовательского интерфейса сделано соответствующий список (см. рис. 3.7.), который определит idlanguage таблиц objects, attributes и справочников, по которым будет ввестись работа информационной системы.

Рис. 3.7. Меню выбора языка информационной системы.

После вывода объектов в виде списка пользователю должна быть предоставлена возможность редактирования объекта. Алгоритм редактирования объекта описан выше в главе “Реализация функциональности добавления, редактирования и удаления объектов”.

Здесь я привожу (см. рис. 3.8.) вид пользовательского интерфейса при редактировании произвольного объекта, например, объекта новость с заголовком “Выставки петербурга конец XIX - начало ХХ века” объектного типа новости. В этой форме с помощью * пользователь определяет обязательные для заполнения атрибуты объекта. Если они остаются незаполненными то при сохранении объекта, система выведет информационное окно с сообщением об ошибке.

Рис. 3.8. Редактирование объекта новость с заголовком “Выставки петербурга конец XIX - начало ХХ века” объектного типа новости.

Стоит отдельно упоминуть про аудит изменения пользовательских данных. На данный момент со стороны клиентского приложения поддержки нету, аудит осуществляется целиком со стороны БД. Восстановление потерянных данных осуществляется программистом БД. Приведу типичный пример.

Пользователь запросил из под приложения следующую новость:

SELECT briefdescrription1 FROM news WHERE id = 1292983;

Запрос вернет следующее:

"Июль - традиционная пора всякого рода заплывов в нашем городе. Пусть даже вода в Неве не слишком теплая, но теплее уже не станет, А плавать хочется".

А затем обновил поле briefdescrription1 следующим образом:

UPDATE news

SET briefdescrription1 = to_clob('"Июль, август - традиционная пора всякого рода заплывов в нашем городе. Пусть даже вода в Неве не слишком теплая, но теплее уже не станет, А плавать хочется."')

WHERE id = 1292983;

COMMIT;

Соответственно вышеупомянутый запрос вернет следующее:

"Июль, август - традиционная пора всякого рода заплывов в нашем городе. Пусть даже вода в Неве не слишком теплая, но теплее уже не станет, А плавать хочется".

Cодержимое данного поля изменилось. Была произведена DML-операция над таблицей USERCLOBVALUES, а значит сработал триггер USERCLOBVALUES_AUDIT, который зафиксирует изменения в таблице USERCLOBVALUESLOG.

Пользователь системы замечает логическую ошибку в данных и хочет вернуть предыдущее значение. Для этого программист БД осуществляет запрос к логу clob данных:

SELECT ID, ID_OBJECT, ID_ATTRIBUTE, OLD_VALUE, NEW_VALUE, MODIFIED_USER, MODIFIED_TIME, TYPE_OF_OPERATION  USERCLOBVALUESLOG

WHERE OLD_VALUE = to_clob('Июль - традиционная пора всякого рода заплывов в нашем городе. Пусть даже вода в Неве не слишком теплая, но теплее уже не станет, А плавать хочется.');

На данный запрос из БД вернутся следующие данные (см. рис.3.9.):

Рис.3.9. Возвращаемые данные из ДБ при запросе в аудит.

На основании этих данных можно осуществить DML-операцию, которая восстановит пользовательские данные. Ее код будет следующим:

UPDATE news

SET briefdescrription1 = to_clob('"Июль - традиционная пора всякого рода заплывов в нашем городе. Пусть даже вода в Неве не слишком теплая, но теплее уже не станет, А плавать хочется."')

WHERE id = 1292983;

COMMIT;

Тогда исходный запрос к данному объекту новости вернет иходные данные:

SELECT briefdescrription1 FROM news WHERE id = 1292983;

"Июль - традиционная пора всякого рода заплывов в нашем городе. Пусть даже вода в Неве не слишком теплая, но теплее уже не станет, А плавать хочется".

Перейдем теперь к рассмотрению работы политики тщательного контроля доступа к объектам. Напомню, в списке исходных требований 2 пунктом исходя из наличия лицензии на конкретный проект СУБД определена как Oracle версии - 10.2.0.3 Standard Edition. Кроме того, в 7 пункте списка сказано, что в БД необходимо разработать политику прав доступа к объектам в зависимости от пользователя. Политика безопасности должна обеспечивать разные права на объекты для владельцев объекта, для пользовательских групп и для пользователей, которые не являются ни владельцами ни входят в пользовательские группы. Продемонстрирую работу разработанного пакета SECURITYDATA.

Важно отметить, что пользователь информационной системы, подключаясь к БД из клиентского приложения не имеет гранта на просмотр пользовательских таблиц, он имеет доступ только к представлениям, которые сгенерированы на пользовательских таблицах. Это сделано для функционирования политики тщательного контроля доступа к объектам. Поясню: создается представление к пользовательской таблице с фильтрацией по функции checkrights пакета SECURITYDATA, которому передается в качестве параметра id объекта, для которого нужно определить доступ. Функция возвращает право пользователя на данный объект. Например, для таблицы NEWS будет создано представление NEWS_VIEW. Код представления будет таков:> CREATE OR REPLACE VIEW NEWS_VIEW

AS SELECT * FROM NEWS

WHERE SECURITYDATA.checkRights(ID)>0 created

Логика определения права пользователя на объект описана выше в главе “Реализация функциональности тщательного контроля доступа на уровне объектов.

Итак, возьмем 2 произвольных объекта в таблице NEWS, скажем с id = 2000899675 и id = 2000899693:

SQL> select id from news where id = 2000899675 or id = 2000899693

По умолчанию для этих объектов устанавливается владелец - пользователь, который его создал, право владельца принимается равным 2 (т.е. право на просмотр и редактирование объекта), а право для всех остальных пользователей тоже равным 2.

Проверим данные о владельце, праве владельца и праве всех остальных пользователей на данный объект:

SQL> COLUMN ID FORMAT A10> COLUMN owner FORMAT A10> COLUMN ORIGHTS FORMAT A7> COLUMN ARIGHTS FORMAT A7> select id, owner, orights, arights from objects where id = 2000899675 or id = 2000899693 or id = 2000899783;OWNER ORIGHTS ARIGHTS

PETROV 2 2

2000899693 PETROV 2 2

PETROV 2 2

Таким образом, убеждаемся, что владелец всех 3 объектов - пользователь PETROV, владельцу дано право 2 на таблицу, всем остальным пользователям - тоже право 2. Изменим это следующим образом (см. табл. 3.1.):

Таблица 3.1.

ID

OWNER

ORIGHTS

ARIGHTS

RIGHTS OF SIDOROV

2000899675

PETROV

2

2

2

2000899693

PETROV

2

0

0

2000899683

PETROV

0

2

2


В качестве всех остальных пользователей использую пользователя SIDOROV. Значение его прав определено в колонке RIGHTS OF SIDOROV. Код который осуществит конструкцию прав, указанной в табл.3.1., будет следующим:

SQL> update objects set orights = 0 where id = 2000899783;> update objects set arights = 0 where id = 2000899693;> select id, owner, orights, arights from objects where id = 2000899675 or id = 2000899693 or id = 2000899783;OWNER ORIGHTS ARIGHTS

PETROV 2 2

2000899693 PETROV 2 0

PETROV 0 2

Соответственно доступ для пользователя Petrov будет следующим:

Connected to Oracle Database 10g Release 10.2.0.3.0 as petrov> select id from NEWS_VIEW where id = 2000899675 or id = 2000899693 or id = 2000899783;

Соответственно доступ для пользователя Sidorov будет следующим:

Connected to Oracle Database 10g Release 10.2.0.3.0 as sidorov> select id from NEWS_VIEW where id = 2000899675 or id = 2000899693 or id = 2000899783;

Теперь проверим право 1. Напомню, что пользователю с таким правом на объект дается только право на просмотр объекта, на редактирование такого права нет. Установим права для пользователя PETROV права на объекты как показано в таблице 3.2.

Таблица 3.2.

ID

OWNER

ORIGHTS

2000899675

PETROV

2

1292983

PETROV

1

2000899683

PETROV

0


Соответственно доступ для пользователя Petrov будет следующим:

Connected to Oracle Database 10g Release 10.2.0.3.0 as petrov> select id from NEWS_VIEW where id = 2000899675 or id = 1292983 or id = 2000899783;

В приложении для пользователя Petrov на объект 1292983 будет установлено право 1, т.е. пользователь только сможет просматривать объект (см. рис.3.10.).

Рис.3.10. Просмотр объекта без права на редактирование объекта.

Если же в приложении для пользователя Petrov на объект 1292983 будет установлено право 2, то пользователь сможет просматривать и редактировать объект (см. рис.3.11.).

Connected to Oracle Database 10g Release 10.2.0.3.0 as petrov> update objects set arights = 2 where id = 1292983;> select id, owner, orights, arights from objects where id = 1292983;OWNER ORIGHTS ARIGHTS

PETROV 2 2

Рис.3.11. Просмотр объекта с правом на редактирование объекта.

.2 Тестовые примеры (test cases)

Ввиду большого количества тестовых примеров проводимых в процесс разработки БД информационной системы, приведу в таблице 3.3. только наиболее интересные тест кейсы. Возможные приоритеты тест-кейсов в порядке убывания их статуса: Blocker, Critical, Major, Minor, Trivial.

Таблица 3.3. Test cases.

ID

Название

Цель

Среда выполнения

Пошаговое выполнение

Критерий выполнения

Приоритет

DB1

Поддержка объектов на русском языке

Проверка создания, редактиро-вания и удаления объектов на русском языке.

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, в котором есть атрибуты на русском языке. 2.Создать объект та-кого объектного типа. 3.Заполнить значения атрибутов объектного типа литералами на русском языке. 4.Сохранить в БД. 5. Выбрать этот объект из БД.

Наличие объектов и корректный вывод  значений атрибутов объекта на русском языке.

Blocker

DB2

Поддержка объектов на английском языке

Проверка создания, редактирования и удаления объектов на английском языке.

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, в котором есть атрибуты на английском языке. 2.Создать объект такого объектного типа. 3.Заполнить значения атрибутов объектного типа литералами на английском языке. 4.Сохранить в БД. 5. Выбрать этот объект из БД.

Наличие объектов и корректный вывод  значений атрибутов объекта на английском языке.

Blocker

DB3

Поддержка объектов на немецком языке

Проверка создания, редактирования и удаления объектов на немецком языках.

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, в котором есть атрибуты на немецком языке. 2.Создать объект такого объектного типа. 3.Заполнить значения атрибутов объектного типа литералами на немецком языке. 4.Сохранить в БД. 5. Выбрать этот объект из БД.

Наличие объектов и корректный вывод  значений атрибутов объекта на немецком языке.

Blocker

DB4

Поддержка переключения работы информационной системы с русского на английский язык

Проверка функционирования переключения ра-боты информа-ционной системы с русского на ан-глийский язык

Internet Explorer 6.0.

1. Установить в приложении русский язык. 2. Выбрать объект. 3.Переключиться на английский язык. 4. Выбрать объект.

Корректное отображение значений атрибутов объекта как русском так и на английских языках

Critical

DB5

Поддержка переключения работы информационной системы с английского на русский язык

Проверка функционирования переключения ра-боты информа-ционной системы с русского на ан-глийский язык

PL\SQL Developer 7.1.5.1398

1. Установить в приложении английский язык. 2. Выбрать объект. 3.Переключиться на русский язык. 4. Выбрать объект

Корректное отображение значений атрибутов объекта как русском так и на английских языках

Critical

DB6

Поддержка без-языкового типа MULTILANG

Проверка функционирования безязыкового типа MULTILANG

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, в котором есть атрибуты типа данных MULTI-LANG. 2.Создать объект та-кого объектного типа. 3.Заполнить значения атрибутов объектного типа. 4.Сохранить в БД. 5. Выбрать этот объект из БД.

Наличие объектов и корректный вывод значения атрибута.

Major



.3 Сводная таблица тестирования (test log)

На основе данных этой таблицы таблицы 3.3. Test cases составлен test log. Данные тестлога приведены в таблице 3.4. На основании данных тестлога можно проследить примерный график разработки БД. В таблице если стоит Ok - то тогда тест-кейс успешно выполнен, иначе нет. Все тест-кейсы были выполнены, по итогам тест-лога видно, что БД разработана.

Таблица3.4. Test Log.

Test case

Build 1 01.09.09

Вuild 2 01.10.09

Build 3 01.11.09

Build 4 01.12.09

DB1


Ok

Ok

Ok

DB2

Ok

Ok

Ok

Ok

DB3


Ok

Ok

Ok

DB4



Ok

Ok

DB5



Ok

Ok

DB6




Ok



Заключение

 данной дипломной работе была спроектирована и разработана База Данных для информационной системы архива, в которой должны храниться и обрабатываться айдиофайлы, фотофайлы и текстовая информация, характеризуемая сильной разреженностью данных. В ходе разработки была предложена и выбрана в качестве модели БД - модель Entity-Attribute-Value. В данной работе был решен ряд интересных задач, а именно: реализация системы разграничения прав пользователей на объекты с помощью пользовательских представлений и пакета SecurityData. Кроме того, со стороны БД система обеспечена всей необходимой функциональностью: в частности, поисковым механизмом, поддержка логирования пользовательских данных и восстановления утерянных данных.

Реализованная БД позволяет модифицировать пользовательские объекты без блокировки системы. Напомню, что в СУБД Oracle при любой DDL операции производится окончание транзакции и блокировка всех таблиц, над которыми производится данная DDL операция. Эта проблема успешно обойдена использованием EAV-модели. К EAV-модели для ускорения работы выполнения запросов к пользовательским данным была добавлена обычная реляционная модель в виде плоских реляционных таблиц.

База данных осуществляет полноценную поддержку 3 языков (русский, английский и немецкий), а также безязыкового символьного типа, т.е. типа, значения которого уникально как для русской, так и английской и немецкой версии БД. Этот тип нужен, например, для шифра, который уникален и одинаков на любом языке. Кроме того, БД генерирует XML документы для клиентского приложения, т.к. пользовательскому GUI-интерфейсу информационной системы для динамического построения списков данных нужно возвращать динамически генерируемые XML-документы для их последующего вывода в клиентском приложении.

В целом, считаю, что поставленные задачи в списке исходных требований были выполнены, а дипломную работу - завершенной.

Список использованной литературы

1. Змеев О.А., Новиков Д.В., Моисеев А.Н. К вопросу проектирования уровня хранения в виде ООРБД // Вестник ТГУ. Приложение №1 (II), сентябрь 2002. Доклады IV Всероссийской конференции с международным участием «Новые информационные технологии в исследовании сложных структур», Томск, 10-13 сентября 2002. С. 363-367.

. Ларман К. Применение UML и шаблонов проектирования. 2-е изд. М.: Изд. дом «Вильямс», 2002. 624 с.

. Тенцер А. База данных - хранилище объектов // КомпьютерПресс. 2001. №8.

. Войтиков К.Ю., Змеев О.А., Моисеев А.Н. Объектный подход к проблеме проектирова-ния подсистемы нормативно-справочной информации // Обработка данных и управление в сложных системах. Томск: Изд-во Том. ун-та, 2002. Вып. 4. С. 13-20.

. Том Кайт. Oracle для профессионалов. Книга 1. Архитектура и основные особенности. Третье издание, переработанное и дополненное: Пер. с англ./ Том Кайт - СПб.: ООО “ДиаСофтЮП”, 2005 - С.312.

. Дейт, К. Дж. Введение в системы баз данных = Introduction to Database Systems. - 8-е изд. - М.: “Вильямс”, 2006. - 1328 с.

. Томас Коннолли, Каролин Бегг Базы данных. Проектирование, реализация и сопровождение. Теория и практика = Database Systems: A Practical Approach to Design, Implementation, and Management Third Edition. - 3-е изд. - М. Вильямс”:, 2003. - 1436 с.

8. Кузнецов Сергей Дмитриевич “Основы баз данных” - 1-е изд. - М.: «Интернет-университет информационных технологий - ИНТУИТ.ру», 2005. - 488 с.

. Дейт, К. Дж. Введение в системы баз данных, 8-е издание.: Пер. с англ. - М.: Издательский дом "Вильямс", 2005. - 103-104 с.

. Дейт, К. Дж. Введение в системы баз данных, 8-е издание.: Пер. с англ. - М.: Издательский дом "Вильямс", 2005. - 108 с.

. С.Д. Кузнецов. Основы современных баз данных, информационно-аналитические материалы Центра информационных материалов. Глава 22.

. Дуглас Крамер. Платформа Java. Официальное издание. - JavaSoft, Sun Microsystems Inc. 5-7 c.

Приложение 1. Листинги пакетов

Листинг пакета DATAMODIFICATION

Пакет DATAMODIFICATION предназначен для вывода аудита по объекту, объектному типу или атрибуту в виде XML-документа, а также подсчета количества транзакций проводимых над атрибутом, объектом или объектным типом, вывода прав на объект в виде XML-документа. Вывод аудита в виде XML-документа возможен в постраничном виде - это необходимо для отображения большого количества транзакций в приложении. Код заголовка пакета и комментарии к заголовку пакета (см. таб.Пр.1.1.) ниже:

Таблица Пр.1.1. Комментарии к заголовку пакета DATAMODIFICATION.

номер строчки кода

Комментарии

3

Функция showAuditByAttribute предназначена для вывода аудита по конкретному атрибуту.

5

Функция showAuditByObject предназначена для вывода аудита по конкретному объекту.

6

Функция showAuditByObjectType предназначена для вывода аудита по конкретному объектному типу.

7

Функция countTransactionsByAttribute предназначена для вывода количества транзакций по конкретному атрибуту.

8

Функция countTransactionsByObject предназначена для вывода количества транзакций по конкретному объекту.

9

Функция countTransactionsByObjectType предназначена для вывода количества транзакций по конкретному объектному типу.

10

Функция pageAuditByAttribute предназначена для вывода аудита по конкретному атрибуту в постраничном виде.

11

Функция pageAuditByObject предназначена для вывода аудита по конкретному объекту в постраничном виде.

12

Функция pageAuditByObjectType предназначена для вывода аудита по конкретному объектному типу в постраничном виде.

13

Функция showObjectRights предназначена для вывода прав на объект в виде XML-документа.

14

Функция showFoundObjectRights предназначена для вывода прав на найденные объекты в таблице Tempfoundobjects в виде XML-документа


SQL> create or replace package DATAMODIFICATION as

FUNCTION showAuditByAttribute(nIDAttribute attributes.id%TYPE, nIdLanguage NUMBER) RETURN XMLTYPE;

function showAuditByObject(nIDObject objects.id%TYPE, nIdLanguage NUMBER) RETURN XMLTYPE;

function showAuditByObjectType(nIDObjectType objecttypes.id%TYPE, nIdLanguage NUMBER) RETURN XMLTYPE;

function countTransactionsByAttribute(nIDAttribute attributes.id%TYPE, nIdLanguage NUMBER) RETURN NUMBER;

function countTransactionsByObject(nIDObject objects.id%TYPE, nIdLanguage NUMBER) RETURN NUMBER;

function countTransactionsByObjectType(nIDObjectType objecttypes.id%TYPE, nIdLanguage NUMBER) RETURN NUMBER;

FUNCTION pageAuditByAttribute(nIDAttribute attributes.id%TYPE, nIdLanguage NUMBER, nPageNumber NUMBER, nAmountPerPage NUMBER) RETURN XMLTYPE;

FUNCTION pageAuditByObject(nIDObject objects.id%TYPE, nIdLanguage NUMBER, nPageNumber NUMBER, nAmountPerPage NUMBER) RETURN XMLTYPE;

FUNCTION pageAuditByObjectType(nIDObjectType objecttypes.id%TYPE, nIdLanguage NUMBER, nPageNumber NUMBER, nAmountPerPage NUMBER) RETURN XMLTYPE;

function showObjectRights(nIDObject objects.id%TYPE) RETURN XMLTYPE;

FUNCTION showFoundObjectRights RETURN XMLTYPE;

end DATAMODIFICATION;

17 /

Тело пакета DATAMODIFICATION представлено ниже:

SQL> create or replace package body DATAMODIFICATION as

FUNCTION showAuditByAttribute(nIDAttribute attributes.id%TYPE, nIdLanguage NUMBER) RETURN XMLTYPE AS

nDataType attributes.iddatatype%TYPE;

xDocument XMLTYPE;

vName datatypes.name%TYPE;

BEGIN

SELECT idDataType INTO nDataType FROM attributes WHERE id = nIDAttribute;

SELECT name INTO vName FROM datatypes WHERE id = nDataType;

IF vName = 'MULTILANG' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'MULTILANG' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, uml.*, s.*, rownum r

FROM attributes a, usermultilangvalueslog uml, systemdatavalues s

WHERE a.id = nIDAttribute and uml.id_attribute = nIDAttribute AND uml.id_attribute = s.idparent AND s.idlanguage = nIdLanguage

)A

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'VARCHAR2' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'STRING' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, userstringvalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'NUMBER' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'NUMBER' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, usernumbervalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'DATE' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'DATE' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, userdatevalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'CLOB' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'CLOB' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, userclobvalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'DICTIONARY' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'DICTIONARY' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, userdictionaryvalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

END IF;

RETURN NULL;

END showAuditByAttribute;

FUNCTION showAuditByObject(nIDObject objects.id%TYPE, nIdLanguage NUMBER) RETURN XMLTYPE AS

xDocument XMLTYPE;

BEGIN

SELECT

XMLElement("object_summary", XMLAttributes(nIDObject AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

A.new_idattribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.attribute_note AS attribute_note,

A.attribute_datatype AS attribute_datatype, A.datatype_length AS datatype_length

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

),

XMLElement("object",

XMLAttributes(

A.OLD_IDPARENTOBJECT AS OLD_IDPARENTOBJECT,

A.NEW_IDPARENTOBJECT AS NEW_IDPARENTOBJECT,

A.OBJECTTYPE NEW_OBJECTTYPE,

A.OLD_OWNER OLD_OWNER,

A.NEW_OWNER NEW_OWNER,

A.OLD_ORIGHTS OLD_ORIGHTS,

A.NEW_ORIGHTS NEW_ORIGHTS,

A.OLD_ARIGHTS OLD_ARIGHTS,

A.NEW_ARIGHTS NEW_ARIGHTS,

A.OPERATION OPERATION,

A.OBJECTNOTE OBJECTNOTE

)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

--usermultilangvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'MULTILANG' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usermultilangvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userstringvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'STRING' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userstringvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdatevalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'DATE' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdatevalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userclobvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userclobvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--usernumbervalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null OBJECTTYPE,

null NEW_OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usernumbervalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdictionaryvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdictionaryvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

SELECT null AS new_idattribute,

null AS old_value,

null AS new_value,

null AS old_serialnumber,

null AS new_serialnumber,

OL.MODIFIED_USER AS modified_user,

OL.MODIFIED_TIME AS modified_time,

null AS type_of_operation,

null AS attribute_note,

null AS attribute_datatype,

null AS datatype_length,

OL.OLD_IDPARENTOBJECT OLD_IDPARENTOBJECT,

OL.NEW_IDPARENTOBJECT NEW_IDPARENTOBJECT,

OL.NEW_OBJECTTYPE NEW_OBJECTTYPE,

OL.OLD_OWNER OLD_OWNER,

OL.NEW_OWNER NEW_OWNER,

OL.OLD_ORIGHTS OLD_ORIGHTS,

OL.NEW_ORIGHTS NEW_ORIGHTS,

OL.OLD_ARIGHTS OLD_ARIGHTS,

OL.TYPE_OF_OPERATION OPERATION,

s.value OBJECTNOTE

FROM objectslog OL, systemdatavalues s

WHERE OL.ID_OBJECT = nIDObject and s.idparent = OL.ID_OBJECT AND S.IDLANGUAGE = nIdLanguage

) A

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

END showAuditByObject;

function showAuditByObjectType(nIDObjectType objecttypes.id%TYPE, nIdLanguage NUMBER) RETURN XMLTYPE IS

xDocument XMLTYPE;

BEGIN

SELECT XMLElement("object_type",

XMLAttributes(1 AS idObjectType),

XMLElement("objects_summary",

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLElement("object_info",

XMLAttributes(A.id AS "object_id"),

XMLElement("attribute",

XMLAttributes(

A.new_idattribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.attribute_note AS attribute_note,

A.attribute_datatype AS attribute_datatype, A.datatype_length AS datatype_length

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

),

XMLElement("object_change",

XMLAttributes(

A.OLD_IDPARENTOBJECT AS OLD_IDPARENTOBJECT,

A.NEW_IDPARENTOBJECT AS NEW_IDPARENTOBJECT,

A.OBJECTTYPE NEW_OBJECTTYPE,

A.OLD_OWNER OLD_OWNER,

A.NEW_OWNER NEW_OWNER,

A.OLD_ORIGHTS OLD_ORIGHTS,

A.NEW_ORIGHTS NEW_ORIGHTS,

A.OLD_ARIGHTS OLD_ARIGHTS,

A.NEW_ARIGHTS NEW_ARIGHTS,

A.OPERATION OPERATION,

A.OBJECTNOTE OBJECTNOTE

)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

)

INTO xDocument

--showAuditByObject(id, nIdLanguage)

--) AS objects)

FROM (

SELECT B.*, rownum r

FROM (

--usermultilangvalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'MULTILANG' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usermultilangvalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userstringvalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'STRING' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userstringvalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdatevalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'DATE' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdatevalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userclobvalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userclobvalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--usernumbervalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null OBJECTTYPE,

null NEW_OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usernumbervalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdictionaryvalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdictionaryvalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

SELECT

o.id AS id,

null AS new_idattribute,

null AS old_value,

null AS new_value,

null AS old_serialnumber,

null AS new_serialnumber,

OL.MODIFIED_USER AS modified_user,

OL.MODIFIED_TIME AS modified_time,

null AS type_of_operation,

null AS attribute_note,

null AS attribute_datatype,

null AS datatype_length,

OL.OLD_IDPARENTOBJECT OLD_IDPARENTOBJECT,

OL.NEW_IDPARENTOBJECT NEW_IDPARENTOBJECT,

OL.NEW_OBJECTTYPE NEW_OBJECTTYPE,

OL.OLD_OWNER OLD_OWNER,

OL.NEW_OWNER NEW_OWNER,

OL.OLD_ORIGHTS OLD_ORIGHTS,

OL.NEW_ORIGHTS NEW_ORIGHTS,

OL.OLD_ARIGHTS OLD_ARIGHTS,

OL.NEW_ARIGHTS NEW_ARIGHTS,

OL.TYPE_OF_OPERATION OPERATION,

s.value OBJECTNOTE

FROM objectslog OL, systemdatavalues s, objects o

WHERE o.idobjecttype = nIDObjectType AND OL.ID_OBJECT = o.id and s.idparent = OL.ID_OBJECT AND S.IDLANGUAGE = nIdLanguage

-- ORDER BY modified_time

) B)A

GROUP BY A.modified_time, A.MODIFIED_USER

ORDER BY A.modified_time;

RETURN xDocument;

END showAuditByObjectType;

function countTransactionsByAttribute(nIDAttribute attributes.id%TYPE, nIdLanguage NUMBER) RETURN NUMBER IS

nAmountTransactions NUMBER;

nDataType attributes.iddatatype%TYPE;

vName datatypes.name%TYPE;

BEGIN

SELECT idDataType INTO nDataType FROM attributes WHERE id = nIDAttribute;

SELECT name INTO vName FROM datatypes WHERE id = nDataType;

IF vName = 'MULTILANG' THEN

SELECT count(*)

INTO nAmountTransactions

FROM

(SELECT modified_time

FROM usermultilangvalueslog u, systemdatavalues s

WHERE u.id_attribute = nIDAttribute AND u.id_attribute = s.idparent AND s.idlanguage = nIdLanguage

GROUP BY u.modified_time) A;

RETURN nAmountTransactions;

ELSIF vName = 'VARCHAR2' THEN

SELECT count(*)

INTO nAmountTransactions

FROM

(SELECT modified_time

FROM userstringvalueslog u, systemdatavalues s

WHERE u.id_attribute = nIDAttribute AND u.id_attribute = s.idparent AND s.idlanguage = nIdLanguage

GROUP BY u.modified_time) A;

RETURN nAmountTransactions;

ELSIF vName = 'NUMBER' THEN

SELECT count(*)

INTO nAmountTransactions

FROM

(SELECT modified_time

FROM usernumbervalueslog u, systemdatavalues s

WHERE u.id_attribute = nIDAttribute AND u.id_attribute = s.idparent AND s.idlanguage = nIdLanguage

GROUP BY u.modified_time) A;

RETURN nAmountTransactions;

ELSIF vName = 'DATE' THEN

SELECT count(*)

INTO nAmountTransactions

FROM

(SELECT modified_time

FROM userdatevalueslog u, systemdatavalues s

WHERE u.id_attribute = nIDAttribute AND u.id_attribute = s.idparent AND s.idlanguage = nIdLanguage

GROUP BY u.modified_time) A;

RETURN nAmountTransactions;

ELSIF vName = 'CLOB' THEN

SELECT count(*)

INTO nAmountTransactions

FROM

(SELECT modified_time

FROM userclobvalueslog u, systemdatavalues s

WHERE u.id_attribute = nIDAttribute AND u.id_attribute = s.idparent AND s.idlanguage = nIdLanguage

GROUP BY u.modified_time) A;

RETURN nAmountTransactions;

ELSIF vName = 'DICTIONARY' THEN

SELECT count(*)

INTO nAmountTransactions

FROM

(SELECT modified_time

FROM userdictionaryvalueslog u, systemdatavalues s

WHERE u.id_attribute = nIDAttribute AND u.id_attribute = s.idparent AND s.idlanguage = nIdLanguage

GROUP BY u.modified_time) A;

RETURN nAmountTransactions;

END IF;

RETURN 0;

RETURN nAmountTransactions;

EXCEPTION WHEN NO_DATA_FOUND THEN

RETURN 0;

END countTransactionsByAttribute;

function countTransactionsByObject(nIDObject objects.id%TYPE, nIdLanguage NUMBER) RETURN NUMBER IS

nAmountTransactions NUMBER;

BEGIN

SELECT count(*) INTO nAmountTransactions FROM (

SELECT a.modified_time

FROM (

--usermultilangvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

s.value AS attribute_note,

'MULTILANG' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usermultilangvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userstringvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'STRING' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userstringvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdatevalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'DATE' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdatevalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userclobvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userclobvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--usernumbervalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null OBJECTTYPE,

null NEW_OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usernumbervalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdictionaryvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdictionaryvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

SELECT null AS new_idattribute,

null AS old_value,

null AS new_value,

null AS old_serialnumber,

null AS new_serialnumber,

OL.MODIFIED_USER AS modified_user,

OL.MODIFIED_TIME AS modified_time,

null AS type_of_operation,

null AS attribute_note,

null AS attribute_datatype,

null AS datatype_length,

OL.OLD_IDPARENTOBJECT OLD_IDPARENTOBJECT,

OL.NEW_IDPARENTOBJECT NEW_IDPARENTOBJECT,

OL.NEW_OBJECTTYPE NEW_OBJECTTYPE,

OL.OLD_OWNER OLD_OWNER,

OL.NEW_OWNER NEW_OWNER,

OL.OLD_ORIGHTS OLD_ORIGHTS,

OL.NEW_ORIGHTS NEW_ORIGHTS,

OL.OLD_ARIGHTS OLD_ARIGHTS,

OL.NEW_ARIGHTS NEW_ARIGHTS,

OL.TYPE_OF_OPERATION OPERATION,

s.value OBJECTNOTE

FROM objectslog OL, systemdatavalues s

WHERE OL.ID_OBJECT = nIDObject and s.idparent = OL.ID_OBJECT AND S.IDLANGUAGE = nIdLanguage

) A

GROUP BY A.modified_time) B;

RETURN nAmountTransactions;

END countTransactionsByObject;

function countTransactionsByObjectType(nIDObjectType objecttypes.id%TYPE, nIdLanguage NUMBER) RETURN NUMBER IS

nAmountTransactions NUMBER;

BEGIN

SELECT sum(countTransactionsByObject(id, nIdLanguage))

INTO nAmountTransactions

FROM objects o

WHERE o.idobjecttype = nIDObjectType

AND (EXISTS (SELECT * FROM userclobvalueslog u WHERE u.id_object = o.id)

OR EXISTS (SELECT * FROM userdatevalueslog u WHERE u.id_object = o.id)

OR EXISTS (SELECT * FROM userdictionaryvalueslog u WHERE u.id_object = o.id)

OR EXISTS (SELECT * FROM usermultilangvalueslog u WHERE u.id_object = o.id)

OR EXISTS (SELECT * FROM usernumbervalueslog u WHERE u.id_object = o.id)

OR EXISTS (SELECT * FROM userstringvalueslog u WHERE u.id_object = o.id));

RETURN nAmountTransactions;

END countTransactionsByObjectType;

FUNCTION pageAuditByAttribute(nIDAttribute attributes.id%TYPE, nIdLanguage NUMBER, nPageNumber NUMBER, nAmountPerPage NUMBER) RETURN XMLTYPE AS

nDataType attributes.iddatatype%TYPE;

xDocument XMLTYPE;

vName datatypes.name%TYPE;

BEGIN

SELECT idDataType INTO nDataType FROM attributes WHERE id = nIDAttribute;

SELECT name INTO vName FROM datatypes WHERE id = nDataType;

IF vName = 'MULTILANG' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'MULTILANG' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, uml.*, s.*, rownum r

FROM attributes a, usermultilangvalueslog uml, systemdatavalues s

WHERE a.id = nIDAttribute and uml.id_attribute = nIDAttribute AND uml.id_attribute = s.idparent AND s.idlanguage = nIdLanguage

)A

WHERE (A.r between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage))

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'VARCHAR2' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'STRING' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, userstringvalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

WHERE (A.r between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage))

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'NUMBER' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'NUMBER' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, usernumbervalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

WHERE (A.r between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage))

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'DATE' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'DATE' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, userdatevalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

WHERE (A.r between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage))

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'CLOB' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'CLOB' AS attribute_datatype

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, userclobvalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

WHERE (A.r between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage))

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

ELSIF vName = 'DICTIONARY' THEN

SELECT

XMLElement("attribute_summary", XMLAttributes(nIDAttribute AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

nIDAttribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.note AS attribute_note,

'DICTIONARY' AS attribute_datatype

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT a.*, usl.*, s.*, rownum r

FROM attributes a, userdictionaryvalueslog usl, systemdatavalues s

WHERE a.id = nIDAttribute and usl.id_attribute = nIDAttribute AND usl.id_attribute = s.idparent AND s.idlanguage = 1

)A

WHERE (A.r between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage))

GROUP BY A.modified_time, A.MODIFIED_USER;

RETURN xDocument;

END IF;

RETURN NULL;

END pageAuditByAttribute;

FUNCTION pageAuditByObject(nIDObject objects.id%TYPE, nIdLanguage NUMBER, nPageNumber NUMBER, nAmountPerPage NUMBER) RETURN XMLTYPE AS

xDocument XMLTYPE;

BEGIN

SELECT

XMLElement("object_summary", XMLAttributes(nIDObject AS id),

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLConcat(

XMLElement("attribute",

XMLAttributes(

A.new_idattribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.attribute_note AS attribute_note,

A.attribute_datatype AS attribute_datatype, A.datatype_length AS datatype_length

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

),

XMLElement("object",

XMLAttributes(

A.OLD_IDPARENTOBJECT AS OLD_IDPARENTOBJECT,

A.NEW_IDPARENTOBJECT AS NEW_IDPARENTOBJECT,

A.OBJECTTYPE NEW_OBJECTTYPE,

A.OLD_OWNER OLD_OWNER,

A.NEW_OWNER NEW_OWNER,

A.OLD_ORIGHTS OLD_ORIGHTS,

A.NEW_ORIGHTS NEW_ORIGHTS,

A.OLD_ARIGHTS OLD_ARIGHTS,

A.NEW_ARIGHTS NEW_ARIGHTS,

A.OPERATION OPERATION,

A.OBJECTNOTE OBJECTNOTE

)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

INTO xDocument

FROM (

SELECT B.*, rownum r

FROM (

--usermultilangvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'MULTILANG' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usermultilangvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userstringvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'STRING' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userstringvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdatevalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'DATE' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdatevalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userclobvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userclobvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--usernumbervalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null OBJECTTYPE,

null NEW_OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usernumbervalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdictionaryvalueslog

SELECT uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdictionaryvalueslog uml, systemdatavalues s

WHERE o.id = nIDObject and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

SELECT null AS new_idattribute,

null AS old_value,

null AS new_value,

null AS old_serialnumber,

null AS new_serialnumber,

OL.MODIFIED_USER AS modified_user,

OL.MODIFIED_TIME AS modified_time,

null AS type_of_operation,

null AS attribute_note,

null AS attribute_datatype,

null AS datatype_length,

OL.OLD_IDPARENTOBJECT OLD_IDPARENTOBJECT,

OL.NEW_IDPARENTOBJECT NEW_IDPARENTOBJECT,

OL.NEW_OBJECTTYPE NEW_OBJECTTYPE,

OL.OLD_OWNER OLD_OWNER,

OL.NEW_OWNER NEW_OWNER,

OL.OLD_ORIGHTS OLD_ORIGHTS,

OL.NEW_ORIGHTS NEW_ORIGHTS,

OL.OLD_ARIGHTS OLD_ARIGHTS,

OL.NEW_ARIGHTS NEW_ARIGHTS,

OL.TYPE_OF_OPERATION OPERATION,

s.value OBJECTNOTE

FROM objectslog OL, systemdatavalues s

WHERE OL.ID_OBJECT = nIDObject and s.idparent = OL.ID_OBJECT AND S.IDLANGUAGE = nIdLanguage

-- ORDER BY modified_time

) B)A

WHERE (A.r between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage))

GROUP BY A.modified_time, A.MODIFIED_USER

-- HAVING count(A.MODIFIED_TIME) between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage)--;

ORDER BY A.modified_time;

RETURN xDocument;

END pageAuditByObject;

FUNCTION pageAuditByObjectType(nIDObjectType objecttypes.id%TYPE, nIdLanguage NUMBER, nPageNumber NUMBER, nAmountPerPage NUMBER) RETURN XMLTYPE IS

xDocument XMLTYPE;

BEGIN

--SELECT --XMLElement("object_type",

-- XMLAttributes(nIDObjectType AS idObjectType),

-- XMLElement("a",

SELECT XMLElement("object_type",

XMLAttributes(1 AS idObjectType),

XMLElement("objects_summary",

XMLAgg(XMLElement("transaction",

XMLAttributes(to_char(A.modified_time, 'dd-mm-yyyy hh24:mi:ss') AS modified_time, A.MODIFIED_USER AS MODIFIED_USER),

XMLAgg(

XMLElement("object_info",

XMLAttributes(A.id AS "object_id"),

XMLElement("attribute",

XMLAttributes(

A.new_idattribute AS id_attribute,

A.old_serialnumber AS old_serialnumber, A.new_serialnumber AS new_serialnumber,

A.type_of_operation AS type_of_operation, A.attribute_note AS attribute_note,

A.attribute_datatype AS attribute_datatype, A.datatype_length AS datatype_length

),

XMLElement("old_value_attribute",A.old_value),

XMLElement("new_value_attribute",A.new_value)

),

XMLElement("object_change",

XMLAttributes(

A.OLD_IDPARENTOBJECT AS OLD_IDPARENTOBJECT,

A.NEW_IDPARENTOBJECT AS NEW_IDPARENTOBJECT,

A.OBJECTTYPE NEW_OBJECTTYPE,

A.OLD_OWNER OLD_OWNER,

A.NEW_OWNER NEW_OWNER,

A.OLD_ORIGHTS OLD_ORIGHTS,

A.NEW_ORIGHTS NEW_ORIGHTS,

A.OLD_ARIGHTS OLD_ARIGHTS,

A.NEW_ARIGHTS NEW_ARIGHTS,

A.OPERATION OPERATION,

A.OBJECTNOTE OBJECTNOTE

)

)

)--XMLConcat

)--XMLAgg

)--XMLAttributes

order by A.modified_time desc

)

)

)

INTO xDocument

--showAuditByObject(id, nIdLanguage)

--) AS objects)

FROM (

SELECT B.*, rownum r

FROM (

--usermultilangvalueslog

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'MULTILANG' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usermultilangvalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userstringvalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'STRING' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userstringvalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdatevalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'DATE' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdatevalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userclobvalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userclobvalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--usernumbervalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null OBJECTTYPE,

null NEW_OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, usernumbervalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

--userdictionaryvalueslog

SELECT

o.id AS id,

uml.id_attribute AS new_idattribute,

to_clob(uml.old_value) AS old_value,

to_clob(uml.new_value) AS new_value,

uml.old_serialnumber AS old_serialnumber,

uml.new_serialnumber AS new_serialnumber,

uml.modified_user AS modified_user,

uml.modified_time AS modified_time,

uml.type_of_operation AS type_of_operation,

s.value AS attribute_note,

'CLOB' AS attribute_datatype,

a.length AS datatype_length,

null OLD_IDPARENTOBJECT,

null NEW_IDPARENTOBJECT,

null OBJECTTYPE,

null OLD_OWNER,

null NEW_OWNER,

null OLD_ORIGHTS,

null NEW_ORIGHTS,

null OLD_ARIGHTS,

null NEW_ARIGHTS,

null OPERATION,

null OBJECTNOTE

FROM objects o, attributes a, objecttypes ot, userdictionaryvalueslog uml, systemdatavalues s

WHERE o.idobjecttype = nIDObjectType and o.idobjecttype = ot.id and a.idobjecttype = ot.id and s.idparent = a.id AND S.IDLANGUAGE = nIdLanguage

AND

(uml.id_object = o.id and uml.id_attribute = a.id)

UNION ALL

SELECT

o.id AS id,

null AS new_idattribute,

null AS old_value,

null AS new_value,

null AS old_serialnumber,

null AS new_serialnumber,

OL.MODIFIED_USER AS modified_user,

OL.MODIFIED_TIME AS modified_time,

null AS type_of_operation,

null AS attribute_note,

null AS attribute_datatype,

null AS datatype_length,

OL.OLD_IDPARENTOBJECT OLD_IDPARENTOBJECT,

OL.NEW_IDPARENTOBJECT NEW_IDPARENTOBJECT,

OL.NEW_OBJECTTYPE NEW_OBJECTTYPE,

OL.OLD_OWNER OLD_OWNER,

OL.NEW_OWNER NEW_OWNER,

OL.OLD_ORIGHTS OLD_ORIGHTS,

OL.NEW_ORIGHTS NEW_ORIGHTS,

OL.OLD_ARIGHTS OLD_ARIGHTS,

OL.NEW_ARIGHTS NEW_ARIGHTS,

OL.TYPE_OF_OPERATION OPERATION,

s.value OBJECTNOTE

FROM objectslog OL, systemdatavalues s, objects o

WHERE o.idobjecttype = nIDObjectType AND OL.ID_OBJECT = o.id and s.idparent = OL.ID_OBJECT AND S.IDLANGUAGE = nIdLanguage

-- ORDER BY modified_time

) B)A

WHERE

(A.r between ((nPageNumber-1)*nAmountPerPage+1) and (nPageNumber*nAmountPerPage))

GROUP BY A.modified_time, A.MODIFIED_USER--, A.ID

ORDER BY A.modified_time;

RETURN xDocument;

END pageAuditByObjectType;

FUNCTION addGroupRights(nIDObject objects.id%TYPE) RETURN XMLTYPE IS

xDocument XMLTYPE;

BEGIN

SELECT

XMLAgg(

XMLElement("usergroup",

XMLAttributes(ug.name AS group_name

,uug.grights AS "group_default_right"

,oug.grights AS "group_object_right")

)

)

INTO xDocument

FROM users u, usergroups ug, users_usergroups uug, objects_usergroups oug

WHERE u.id = uug.id_user and uug.id_usergroup = oug.id_usergroup(+) and u.name = user

and (oug.id_object = nIDObject or oug.id_object is null)

and ug.id = uug.id_usergroup;

RETURN xDocument;

END addGroupRights;

FUNCTION showObjectRights(nIDObject objects.id%TYPE) RETURN XMLTYPE IS

xDocument XMLTYPE;

BEGIN

SELECT

XMLElement("object_rights",

XMLAttributes(nIDObject AS id_object),

XMLElement("owner", o.owner),

XMLElement("owner_right", o.orights),

XMLElement("usergroups",addGroupRights(nIDObject)),

XMLElement("others_right", o.arights)

)

INTO xDocument

FROM objects o

WHERE o.id = nIDObject;

RETURN xDocument;

END showObjectRights;

FUNCTION showFoundObjectRights RETURN XMLTYPE IS

xDocument XMLTYPE;

BEGIN

SELECT

XMLElement("Found_object_rights",

XMLAgg(

XMLElement("object",

XMLAttributes(o.id AS id_object),

XMLElement("owner", o.owner),

XMLElement("owner_right", o.orights),

XMLElement("usergroups",datamodification.addGroupRights(o.id)),

XMLElement("others_right", o.arights)

)

)

)

INTO xDocument

FROM objects o, tempfoundobjects t

WHERE o.id = t.id;

RETURN xDocument;

END showFoundObjectRights;

end DATAMODIFICATION;

1871 /

Листинг пакета GENERATETABLES

Пакет GENERATETABLES предназначен для генерации пользовательских таблиц. Таким образом, будут пересозданы все объекты пользовательских схем: вначале будут созданы пользовательские таблицы, затем на них пользовательские представления. Код заголовка пакета и комментарии к заголовку пакета (см. таб.Пр.1.2.) ниже:

Таблица Пр1.2. Комментарии к заголовку пакета generateTables.

Номер строчки кода

Комментарии

3

Процедура doGenerate предназначена для генерации, состоящей из удаления таблиц (если они существуют), создания и вставки значений данных в генерируемые таблицы.

4

Процедура createParentTables предназначена для создания генерируемых таблиц с атрибутами соответвующими объектному типу, для которого создается плоская таблица.

5

Процедура insertDataParentTables предназначена для вставки значений для сгенерированных таблиц.



SQL> CREATE OR REPLACE PACKAGE generateTables IS

procedure doGenerate;

procedure createParentTables;

procedure insertDataParentTables;

END generateTables;

/created

Небольшие комментарии по реализации тела пакета generateTables:

Таблица Пр1.3. Комментарии к телу пакета generateTables.

Номера строчек кода

Комментарии

3-19

Процедура dropParentTables предназначена для удаления таблиц (если они существуют) схемы. Обратите внимание, что ее спецификации нету в заголовке пакета generateTables, поэтому она доступна только внутри пакета другим процедурам этого пакета. Создается курсор for curTables IN (select name from objecttypes) LOOP - 7 строка, по которым удаляются таблицы соответствующих объектных типов. Если такой таблицы по какой-либо причине нету, то срабатывает исключение, выводится сообщение о том, что такой таблицы нету, и цикл 7 строки продолжается.

21-38

Процедура createParentTables предназначена для создания генерируемых таблиц с атрибутами соответвующие объектному типу, для которого создается плоская таблица. Для этого создается курсор по всем объектным типам. В переменную сSQLCode, предназначенную для хранения динамического SQL кода, записывается код, который собирается, как совокупность объектного типа  (значение внешнего курсора for curTables IN (select name, id from objecttypes) LOOP - 25 строка кода) и атрибутов ему соответствующих (значения параметризированного внутреннего курсора for curAttributes IN (select name, iddatatype, length from attributes where idobjecttype = curTables.id) LOOP - 27 строка кода).

40-61

Процедура insertDataParentTables предназначена для вставки значений для сгенерированных таблиц. Для этого создается курсор по всем объектным типам. В переменную сSQLCode, предназначенную для хранения динамического SQL кода, записывается код, который собирается, как совокупность объектного типа (значение внешнего курсора for curTables IN (select name, id from objecttypes) LOOP - 45 строка кода) и атрибутов ему соответствующих (значения параметризированного курсора for curAttributes IN (select name, iddatatype, length from attributes where idobjecttype = curTables.id) LOOP - 47 строка кода). Значения в генерируемую таблицу выбираются из системной таблицы userStringValues, которая хранит в поле Value значения для соответветствующего атрибута и объекта (его id задается из внутреннего курсора for curObjects IN (SELECT id from objects where idobjecttype = curTables.id) LOOP - 50 строка кода).

63-68

Процедура doGenerate предназначена для генерации, состоящей из удаления таблиц (если они существуют), создания и вставки значений данных в генерируемые таблицы и состоит из последовательного вызова процедур dropParentTables, createParentTables и insertDataParentTables.


SQL> CREATE OR REPLACE PACKAGE BODY generateTables IS

procedure dropParentTables is

vSQLCode VARCHAR2(4000);

eTableNotExists EXCEPTION;

PRAGMA EXCEPTION_INIT(eTableNotExists, -00942);

begin

for curTables IN (select name from objecttypes) LOOP

BEGIN

vSQLCode := 'DROP TABLE '||curTables.Name;

EXECUTE IMMEDIATE vSQLCode;

DBMS_OUTPUT.put_line(vSQLCode);

EXCEPTION

WHEN eTableNotExists THEN

--catch the exception that the table doesn't exist and continue dropping the schema tables

DBMS_OUTPUT.put_line('TABLE '||curTables.Name||' doesn''t exist and therefore can''t be dropped');

END;

END LOOP;

end dropParentTables;

procedure createParentTables is

cSQLCode VARCHAR2(4000);

vName VARCHAR2(4000);

begin

for curTables IN (select name, id from objecttypes) LOOP

cSQLCode := 'CREATE TABLE '||curTables.Name||'(ID NUMBER PRIMARY KEY';

for curAttributes IN (select name, iddatatype, length from attributes where idobjecttype = curTables.id) LOOP

select name into vName from datatypes where id = curAttributes.Iddatatype;

cSQLCode := cSQLCode || ',' || curAttributes.Name || ' ' || vName;

if vName = 'VARCHAR2' THEN

cSQLCode := cSQLCode ||'(' || curAttributes.Length ||')';

END IF;

end loop;

cSQLCode := cSQLCode ||')';

--DBMS_OUTPUT.put_line(cSQLCode);

EXECUTE IMMEDIATE cSQLCode;

END LOOP;

end createParentTables;

procedure insertDataParentTables is

cSQLCode VARCHAR2(4000);

cTableCode VARCHAR2(2000);

vValue VARCHAR2(200);

begin

for curTables IN (select name, id from objecttypes) LOOP

cTableCode := 'INSERT INTO '||curTables.Name||'(ID';

for curAttributes IN (select name, iddatatype, length from attributes where idobjecttype = curTables.id) LOOP

cTableCode := cTableCode ||',' || curAttributes.Name;

end loop;

for curObjects IN (SELECT id from objects where idobjecttype = curTables.id) LOOP

cSQLCode := cTableCode || ') VALUES (' || curObjects.id;

for curAttributes IN (select name, iddatatype, length, id from attributes where idobjecttype = curTables.id) LOOP

select value into vvalue from userstringvalues where idobject = curObjects.id and idattribute = curAttributes.id;

cSQLCode := cSQLCode || ', ''' || vvalue || '''';

end loop;

cSQLCode := cSQLCode || ')';

END LOOP;

END LOOP;

COMMIT;

end insertDataParentTables;

procedure doGenerate IS

BEGIN

dropParentTables;

createParentTables;

insertDataParentTables;

END doGenerate;

END generateTables;

/body created

Листинг пакета SEARCHDATA

Пакет SEARCHDATA предназначен для поиска объектов по набору атрибутов и заданным поисковых параметрам по этим атрибутам. Код заголовка пакета и комментарии к заголовку пакета (см. таб.Пр.1.4.) ниже:

Таблица Пр.1.4. Комментарии к заголовку пакета SEARCHDATA.

номер строчки кода

Комментарии

2

Функция insertSearchParameters предназначена для вставки задаваемых в приложении поисковых параметров в таблицу SEARCHPARAMETERS.

3

Процедура clearSearchParameters предназначена для удаления записей поисковых параметров в таблице SEARCHPARAMETERS.

4

Функция getObjectPageIndex предназначена для вывода номера страницы на найденный объект.

5

Функция doSearch предназначена для поиска.

6

Функция getSearchParamNum предназначена для вывода количества заданных поисковых параметров в таблице SEARCHPARAMETERS.

7

Функция getFoundObjectNum предназначена для вывода общего количества найденных объектов.

8

Перегруженная функция getFoundObjectNum предназначена для вывода общего количества найденных объектов по заданному объектному типу.

9

Функция getConditionType предназначена для вывода наименования поискового атрибута по его id.


SQL> create or replace package SEARCHDATA as

function insertSearchParameters (nIDAttribute NUMBER,nIDCondition NUMBER,vValue VARCHAR2,nIDLanguage NUMBER) return NUMBER;

procedure clearSearchParameters;

function getObjectPageIndex (nIDObject NUMBER,nPageSize NUMBER) return NUMBER;

function doSearch (nIDObjectType NUMBER) return NUMBER;

function getSearchParamNum return NUMBER;

function getFoundObjectNum return NUMBER;

function getFoundObjectNum (nIDObjectType NUMBER) return NUMBER;

function getConditionType (nIdCondition NUMBER) return VARCHAR2;

end SEARCHDATA;

/

Листинг пакета SEARCHDATA приведен ниже. Отмечу, что в теле пакета есть private-функция getQueryText(31-57 строки). Эта функция предназначена для формирования кода запроса для поиска по объектам.

SQL> create or replace package body SEARCHDATA as

function insertSearchParameters (nIDAttribute NUMBER,nIDCondition NUMBER,vValue VARCHAR2,nIDLanguage NUMBER) return NUMBER as

BEGIN

INSERT INTO SEARCHPARAMETERS (IDATTRIBUTE,IDCONDITION,IDLANGUAGE,VALUE,IDSEARCHOBJECTTYPE)

SELECT nIDAttribute,nIDCondition,nIDLanguage, NVL(vValue, 0), ID

FROM attributes WHERE idobjecttype = nIDAttribute;

RETURN SQL%ROWCOUNT;

END;

procedure clearSearchParameters as

begin

DELETE FROM SEARCHPARAMETERS;

end;

function getObjectPageIndex (nIDObject NUMBER,nPageSize NUMBER) return NUMBER as

nPageNumber NUMBER;

nSerial NUMBER;

BEGIN

-- get object serial number

SELECT A.OBJECTSERIAL INTO nSerial FROM TEMPFOUNDOBJECTS A WHERE A.ID = nIDObject;

-- get page number

SELECT CEIL(COUNT(*)/nPageSize) INTO nPageNumber FROM TEMPFOUNDOBJECTS A

WHERE A.OBJECTSERIAL <= nSerial;

RETURN nPageNumber;

EXCEPTION WHEN NO_DATA_FOUND THEN RETURN -1;

END;

function getQueryText (nIDObjectType NUMBER) return CLOB as

vBaseTableName VARCHAR2(50) := ObjectsData.getObjectTypeSystemName(nIDObjectType);

cSQLText CLOB;

BEGIN

SELECT A.NAME

INTO vBaseTableName

FROM OBJECTTYPES A

WHERE A.ID = nIDOBjectType;

cSQLText := 'INSERT INTO TEMPFOUNDOBJECTS (ID,OBJECTSERIAL,HIERARCHICALSERIAL,FUSEOBJECT) ' ||

'SELECT ID,row_number() over (order by rnum) OBJECTSERIAL,row_number() over (order by rnum) HIERARCHICALSERIAL,1 FROM (SELECT ';

IF cSQLText IS NOT NULL THEN

-- hint for connect sort and search tables

cSQLText := cSQLText || '/*+ USE_NL(M) */ '

|| vBaseTableName || '.ID, ROWNUM RNUM FROM ' || vBaseTableName || ',(' || cSQLText || ') M';

ELSE

cSQLText := cSQLText || vBaseTableName || '.ID, ROWNUM RNUM FROM ' || vBaseTableName;

END IF;

-- sorting

cSQLText := cSQLText || ' ORDER BY 1';

-- close query

cSQLText := cSQLText || ')';

RETURN cSQLText;

END;

function doSearch (nIDObjectType NUMBER) return NUMBER as

cSQLCode CLOB;

BEGIN

cSQLCode := getQueryText(nIDObjectType);

-- execute search query

EXECUTE IMMEDIATE cSQLCode;

RETURN SQL%ROWCOUNT;

END;

function getSearchParamNum return NUMBER as

nSearchParamNum NUMBER;

BEGIN

SELECT COUNT(*) INTO nSearchParamNum FROM SEARCHPARAMETERS A;

RETURN nSearchParamNum;

END;

function getConditionType (nIdCondition NUMBER) return VARCHAR2 as

cValue CONDITIONS.VALUE%TYPE;

BEGIN

SELECT C.VALUE INTO cValue FROM CONDITIONS C WHERE C.ID = nIDCondition;

RETURN cValue;

EXCEPTION WHEN NO_DATA_FOUND THEN

RETURN NULL;

END;

function getFoundObjectNum return NUMBER as

nObjectsNum NUMBER;

BEGIN

SELECT COUNT(*) INTO nObjectsNum

FROM TEMPFOUNDOBJECTS A WHERE A.FUSEOBJECT = 1;

RETURN nObjectsNum;

END;

function getFoundObjectNum (nIDObjectType NUMBER) return NUMBER as

nObjectsNum NUMBER;

BEGIN

SELECT

COUNT(*) INTO nObjectsNum

FROM

tempfoundobjects tf,

objects obj

WHERE

tf.id = obj.id

AND obj.idobjecttype = nIDObjectType

AND tf.fuseobject = 1;

RETURN nObjectsNum;

END;

end SEARCHDATA;

/

Листинг пакета SECURITYDATA

Пакет SECURITYDATA реализует политику тщательного контроля доступа, т.е. в зависимости от контекста подключения, предоставляет пользователю на объект права владельца или по умолчанию. Код заголовка пакета и комментарии к заголовку пакета (см. таб.Пр.1.5.) ниже:

Таблица Пр.1.5. Комментарии к заголовку пакета SECURITYDATA.

номер строчки кодаКомментарии


3

Функция checkRights предназначена для динамического определения прав вызывающего пользователя на объекты idObject.

4

Это перегруженная версия функции checkRights 3 строчки кода. Необходима для ускоренного динамического определения прав вызывающего пользователя на объекты idObject, для этого все параметры объекта должны быть определены заранее.


SQL> CREATE OR REPLACE PACKAGE SECURITYDATA

AS

FUNCTION checkRights(idObject NUMBER) RETURN NUMBER;

FUNCTION checkRights(idObject NUMBER, oright NUMBER, owner VARCHAR2, aright NUMBER) RETURN NUMBER;

END SECURITYDATA;

/

created

Код тела пакета SECURITYDATA:

Таблица Пр.1.6. Комментарии к телу пакета SECURITYDATA.

номера строчки кодаКомментарии


5-21

Функция checkRights предназначена для динамического определения прав вызывающего пользователя на объекты idObject. Строки 13-16: если пользователь является владельцем объекта то функция возвращает права владельца на объект. Строки 18-19: Иначе возвращаются права по умолчанию.

23-33

Это перегруженная версия функции checkRights 3 строчки кода. Необходима для ускоренного динамического определения прав вызывающего пользователя на объекты idObject, для этого все параметры объекта должны быть определены заранее. Строки 27-29: если пользователь является владельцем объекта то функция возвращает права владельца на объект. Строка 31: Иначе возвращаются права по умолчанию.



SQL> CREATE OR REPLACE PACKAGE BODY SECURITYDATA

AS

FUNCTION checkRights(idObject NUMBER) RETURN NUMBER

AS

nRight objectprivileges.id%TYPE;

vOwner objects.owner%TYPE;

BEGIN

SELECT owner INTO vOwner FROM objects WHERE id = idObject;

IF SYS_CONTEXT ('USERENV', 'SESSION_USER') = vOwner THEN

SELECT orights INTO nRight FROM objects WHERE id = idObject;

RETURN nRight;

END IF;

SELECT arights INTO nRight FROM objects WHERE id = idObject;

RETURN nRight;

END checkRights;

FUNCTION checkRights(idObject NUMBER, oright NUMBER, owner VARCHAR2, aright NUMBER) RETURN NUMBER

AS

BEGIN

IF SYS_CONTEXT ('USERENV', 'SESSION_USER')= owner THEN

RETURN oright;

END IF;

RETURN aright;

END checkRights;

END SECURITYDATA;

/

Приложение 2. Расширенный список тестовых примеров

В таблице Пр2.1. приведены тест-кейсы, которые проводились при разработке и тестировании базы данных. Возможные приоритеты тест-кейсов в порядке убывания их статуса: Blocker, Critical, Major, Minor, Trivial. К сожалению, ввиду относительно большого, проведенных тест-кейсов, здесь я размещаю только тест-кейсы у которых относительный приоритет Major и выше.

Таблица Пр2.1. Test cases.

ID

Название

Цель

Среда выполнения

Пошаговое выполнение

Критерий выполнения

Приоритет

DB1

Поддержка объектов на русском языке

Проверка создания, редактирования и удаления объектов на русском языке.

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, в котором есть атрибуты на русском языке. 2.Создать объект та-кого объектного типа. 3.Заполнить значения атрибутов объектного типа литералами на русском языке. 4.Сохранить в БД. 5. Выбрать этот объект из БД.

Наличие объектов и корректный вывод значений атрибутов объекта на русском языке.

Blocker

DB2

Поддержка объектов на английском языке

Проверка создания, редактирования и удаления объектов на английском языке.

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, в котором есть атрибуты на английском языке. 2.Создать объект такого объектного типа. 3.Заполнить значения атрибутов объектного типа литералами на английском языке. 4.Сохранить в БД. 5. Выбрать этот объект из БД.

Наличие объектов и корректный вывод значений атрибутов объекта на английском языке.

Blocker

DB3

Поддержка объектов на немецком языке

Проверка создания, редактирования и удаления объектов на немецком язы-ках.

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, в котором есть атрибуты на немецком языке. 2.Создать объект такого объектного типа. 3.Заполнить значения атрибутов объектного типа литералами на немецком языке. 4.Сохранить в БД. 5. Выбрать этот объект из БД.

Наличие объектов и корректный вывод значений атрибутов объекта на немецком языке.

Blocker

DB4

Поддержка переключения работы информационной системы с русского на английский язык

Проверка функционирования переключения работы информационной системы с русского на английский язык

Internet Explorer 6.0.

1. Установить в приложении русский язык. 2. Выбрать объект. 3.Переключиться на английский язык. 4. Выбрать объект.

Корректное отображение значений атрибутов объекта как русском так и на английских языках

Critical

DB5

Поддержка переключения работы информационной системы с английского на русский язык

Проверка функционирования переключения ра-боты информа-ционной системы с русского на ан-глийский язык

PL\SQL Developer 7.1.5.1398

1. Установить в приложении английский язык. 2. Выбрать объект. 3.Переключиться на русский язык. 4. Выбрать объект

Корректное отображение значений атрибутов объекта как русском так и на английских языках

Critical

DB6

Поддержка безязыково-го типа MULTILANG

Проверка функционирования безязыкового типа MULTILANG

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, в котором есть атрибуты типа данных MULTI-LANG. 2.Создать объект та-кого объектного типа. 3.Заполнить значения атрибутов объектного типа. 4.Сохранить в БД. 5. Выбрать этот объект из БД.

Наличие объектов и корректный вывод значения атрибута.

Major

DB7

Поддержка аудита вставки нового объекта с атрибутом типа DATE

Поддержка функционирования аудита на вставку нового объекта с атрибутом типа DATE

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных DATE. 2. Создать новый объект выбранного объектного типа. 3.Вывести аудит на атрибут, на объект и на выбранный объектный тип.

Наличие записи аудита о вставки в логе атрибута и объекта.

Major

DB8

Поддержка аудита изменения объекта с атрибутом типа DATE

Поддержка функционирования аудита на изменение объекта с атрибутом типа DATE

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных DATE. 2. Выбрать объект данного объектного типа. 3. Изменить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о изменении в логе атрибута и объекта.

Major

DB9

Поддержка аудита удаления объекта с атрибутом типа DATE

Поддержка функционирования аудита на удаление объекта с атрибутом типа DATE

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных DATE. 2. Выбрать объект данного объектного типа. 3. Удалить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о удаление в логе атрибута и объекта.

Major

DB10

Поддержка аудита вставки нового объекта с атрибутом типа CLOB

Поддержка функционирования аудита на вставку нового объекта с атрибутом типа CLOB

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных CLOB. 2. Создать новый объект выбранного объектного типа. 3.Вывести аудит на атрибут, на объект и на выбранный объектный тип.

Наличие записи аудита о вставки в логе атрибута и объекта.

Major

DВ11

Поддержка аудита изменения объекта с атрибутом типа CLOB

Поддержка функционирования аудита на изменение объекта с атрибутом типа CLOB

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных CLOB. 2. Выбрать объект данного объектного типа. 3. Изменить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о изменении в логе атрибута и объекта.

Major

DB12

Поддержка аудита удаления объекта с атрибутом типа CLOB

Поддержка функционирования аудита на удаление объекта с атрибутом типа CLOB

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных CLOB. 2. Выбрать объект данного объектного типа. 3. Удалить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о удаление в логе атрибута и объекта.

Major

DB13

Поддержка аудита вставки нового объекта с атрибутом типа DICTIONARY

Поддержка функционирования аудита на вставку нового объекта с атрибутом типа DICTIONARY

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных CLOB. 2. Создать новый объект выбранного объектного типа. 3.Вывести аудит на атрибут, на объект и на выбранный объектный тип.

Наличие записи аудита о вставки в логе атрибута и объекта.

Major

DВ14

Поддержка аудита изменения объекта с атрибутом типа DICTIONARY

Поддержка функционирования аудита на изменение объекта с атрибутом типа DICTIONARY

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных DICTIONARY. 2. Выбрать объект данного объектного типа. 3. Изменить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о изменении в логе атрибута и объекта.

Major

DB15

Поддержка аудита удаления объекта с атрибутом типа DICTIONARY

Поддержка функционирования аудита на удаление объекта с атрибутом типа DICTIONARY

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных DICTIONARY. 2. Выбрать объект данного объектного типа. 3. Удалить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о удаление в логе атрибута и объекта.

Major

DB16

Поддержка аудита вставки нового объекта с атрибутом типа MULTILANG

Поддержка функционирования аудита на вставку нового объекта с атрибутом типа MULTILANG

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных MULTILANG. 2. Создать новый объект выбранного объектного типа. 3.Вывести аудит на атрибут, на объект и на выбранный объектный тип.

Наличие записи аудита о вставки в логе атрибута и объекта.

Major

DВ17

Поддержка аудита изменения объекта с атрибутом типа MULTILANG

Поддержка функционирования аудита на изменение объекта с атрибутом типа MULTILANG

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных MULTILANG. 2. Выбрать объект данного объектного типа. 3. Изменить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о изменении в логе атрибута и объекта.

Major

DB18

Поддержка аудита удаления объекта с атрибутом типа MULTILANG

Поддержка функционирования аудита на удаление объекта с атрибутом типа MULTILANG

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных MULTILANG. 2. Выбрать объект данного объектного типа. 3. Удалить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о удаление в логе атрибута и объекта.

Major

DB19

Поддержка аудита вставки нового объекта с атрибутом типа NUMBER

Поддержка функционирования аудита на вставку нового объекта с атрибутом типа NUMBER

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных NUMBER. 2. Создать новый объект выбранного объектного типа. 3.Вывести аудит на атрибут, на объект и на выбранный объектный тип.

Наличие записи аудита о вставки в логе атрибута и объекта.

Major

DВ20

Поддержка аудита изменения объекта с атрибутом типа NUMBER

Поддержка функционирования аудита на изменение объекта с атрибутом типа NUMBER

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных NUMBER. 2. Выбрать объект данного объектного типа. 3. Изменить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о изменении в логе атрибута и объекта.

Major

DB21

Поддержка аудита удаления объекта с атрибутом типа NUMBER

Поддержка функционирования аудита на удаление объекта с атрибутом типа NUMBER

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных NUMBER. 2. Выбрать объект данного объектного типа. 3. Удалить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о удаление в логе атрибута и объекта.

Major

DB22

Поддержка аудита вставки нового объекта с атрибутом типа VARCHAR2

Поддержка функционирования аудита на вставку нового объекта с атрибутом типа VARCHAR2

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных VARCHAR2. 2. Создать новый объект выбранного объектного типа. 3.Вывести аудит на атрибут, на объект и на выбранный объектный тип.

Наличие записи аудита о вставки в логе атрибута и объекта.

Major

DВ23

Поддержка аудита изменения объекта с атрибутом типа VARCHAR2

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных VARCHAR2. 2. Выбрать объект данного объектного типа. 3. Изменить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о изменении в логе атрибута и объекта.

Major

DB24

Поддержка аудита удаления объекта с атрибутом типа VARCHAR2

Поддержка функционирования аудита на удаление объекта с атрибутом типа VARCHAR2

PL\SQL Developer 7.1.5.1398

1. Выбрать объектный тип, который имеет атрибут типа данных VARCHAR2. 2. Выбрать объект данного объектного типа. 3. Удалить выбранный объект. 4.Вывести аудит на атрибут, на объект и на выбранный объект.

Наличие записи аудита о удаление в логе атрибута и объекта.

Major

DB25

Проверка права владельца на объект

Удостовериться, что установив права владельца на объект равный 2 - владелец может просматривать и изменять объект.

PL\SQL Developer 7.1.5.1398

1.Выбрать объект. 2.Установить orights равным 2. 3. Зайти в БД с логином владельца объекта. 4. Попытаться выбрать объект. 5. Попытаться изменить объект.

Возможность просмотра и изменения объекта с логином владельца.

Critical

DB26

Проверка права владельца на объект

Удостовериться, что установив права владельца на объект равный 1 - владелец может только просматривать объект.

PL\SQL Developer 7.1.5.1398

1.Выбрать объект. 2.Установить orights равным 2. 3. Зайти в БД с логином владельца объекта. 4. Попытаться выбрать объект. 5. Попытаться изменить объект.

Возможность просмотра и невозможность изменения объекта с логином владельца.

Critical

DB27

Проверка права владельца на объект

Удостовериться, что установив права владельца на объект равный 0 - владелец не может просматривать и изменять объект.

PL\SQL Developer 7.1.5.1398

1.Выбрать объект. 2.Установить orights равным 2. 3. Зайти в БД с логином владельца объекта. 4. Попытаться выбрать объект.

Невозможность просмотра и изменения объекта с логином владельца.

Critical

DB28

Проверка права по умолчанию на объект

Удостовериться, что установив права по умолчанию на объект равный 2 - пользователь-невладелец может просматривать и изменять объект.

PL\SQL Developer 7.1.5.1398

1.Выбрать объект. 2.Установить orights равным 2. 3. Зайти в БД с логином невладельца объекта. 4. Попытаться выбрать объект. 5. Попытаться изменить объект.

Возможность просмотра и изменения объекта с логином невладельца.

Critical

DB29

Проверка права по умолчанию на объект

Удостовериться, что установив права по умолчанию на объект равный 1 - пользователь-невладелец может только просматривать объект.

PL\SQL Developer 7.1.5.1398

1.Выбрать объект. 2.Установить orights равным 2. 3. Зайти в БД с логином невладельца объекта. 4. Попытаться выбрать объект. 5. Попытаться изменить объект.

Возможность просмотра и невозможность изменения объекта с логином невладельца.

Critical

DB30

Проверка права по умолчанию на объект

Удостовериться, что установив права по умолчанию на объект равный 0 - пользователь-невладелец не может просматривать и изменять объект.

PL\SQL Developer 7.1.5.1398

1.Выбрать объект. 2.Установить orights равным 2. 3. Зайти в БД с логином невладельца объекта. 4. Попытаться выбрать объект.

Невозможность просмотра и изменения объекта с логином невладельца.

Critical


Похожие работы на - Проектирование и разработка БД Oracle для информатизации объектов культуры

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!