orafce. Совместимость логики Oracle для PL/Pgsql#
Версия: 4.4.0.
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: отсутствуют.
Схема размещения:
ext.
Модуль orafce реализует некоторые функции из СУБД Oracle, которые отсутствуют или ведут себя по-другому в СУБД PostgreSQL.
Модуль является функциональным расширением совместимости для логики, написанной под Oracle.
Функционал#
dbms_alert#
Пакет добавляет модель межсессионного взаимодействия.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Процедура |
|
|
– |
Internal |
Триггер |
|
– |
|
Internal |
Процедура |
|
|
– |
Регистрация |
Процедура |
|
|
– |
Удаление |
Процедура |
|
– |
– |
Удаление всех |
Процедура |
|
|
– |
Определение |
Процедура |
|
|
– |
Регистрация сигнала для |
Функция |
|
|
|
Ожидание сигналов в течение |
Функция |
|
|
|
Ожидание сигнала в |
dbms_assert#
Пакет добавляет дополнительные проверки в целях защиты от SQL injection.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Функция |
|
|
|
Квотирование строки; верификация двойного квотирования строки |
Функция |
|
|
|
Квотирование имени объекта SQL. Опциональный параметр - приведение имени к нижнему регистру |
Функция |
|
|
|
Функция-заглушка. Изменений не производится. |
Функция |
|
|
|
Проверка того, что входной параметр является правильным именем объекта SQL |
Функция |
|
|
|
Проверка существования в БД определенной схемы |
Функция |
|
|
|
Проверка применимости входного параметра для использования в качестве идентификатора SQL |
Функция |
|
|
|
Проверка существования нефункционального объекта в БД с именем входного параметра |
dbms_output#
Пакет добавляет консольный вывод сообщений.
В Pangolin используется RAISE, однако поведение функций пакета отличается от принятого в Pangolin порядка выдачи сообщений. Функции пакета представляют собой очередь сообщений и могут быть прочитаны внутри сеанса.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Процедура |
|
– |
– |
Отключение вывода сообщений |
Процедура |
|
|
– |
Включение вывода сообщений. Опциональный параметр указывает размер буфера в байтах |
Функция |
|
– |
|
Получение сообщений |
Функция |
|
|
|
Получение блока последних сообщений |
Процедура |
|
– |
– |
Добавление нового пустого сообщения |
Функция |
|
|
– |
Добавление нового сообщения (блок) |
Функция |
|
|
– |
Добавление нового сообщения (строка) |
Процедура |
|
|
– |
Переключение вывода сообщений в консоль |
dbms_pipe#
Пакет добавляет эмуляцию каналов Oracle. Реализация основана на использовании shared memory.
Максимальное количество каналов - 50;
Длина канала определяется не в байтах, а в количестве элементов;
Возможна отправка сообщений без ожидания;
Возможна отправка пустых сообщений;
Тип
timestampдляnext_item_type=13;СУБД Pangolin не поддерживает тип
RAW. Используйте типbytea.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Представление |
|
– |
|
Список каналов |
Процедура |
|
|
– |
Передача параметров (имени, размера, признака) при создании канала |
Функция |
|
|
Определение формата сообщения в канале: |
|
Процедура |
|
|
– |
Добавление сообщения в канал |
Процедура |
|
|
– |
Очистка канала. |
Функция |
|
|
|
Прием сообщения. Копирование сообщения в локальный буфер. |
Процедура |
|
|
– |
Удаление канала. |
Процедура |
|
– |
– |
Очистка буфера |
Функция |
|
|
|
Передача сообщения. |
Функция |
|
– |
|
Возвращает уникальное имя сессии, в которой создан канал |
Функция |
|
– |
|
Распаковка сообщения |
Функция |
|
– |
|
Распаковка сообщения |
Функция |
|
– |
|
Распаковка сообщения |
Функция |
|
– |
|
Распаковка сообщения |
Функция |
|
– |
|
Распаковка сообщения |
Функция |
|
– |
|
Распаковка сообщения |
dbms_random#
Пакет добавляет псеводслучайные числа Oracle.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Процедура |
|
|
– |
Инициализация генератора псевдослучайных чисел c заданным зерном ( |
Функция |
|
– |
|
Генерация числа в нормальном распределении |
Функция |
|
– |
|
Генерация числа в полном диапазоне int4 (-2^31…2^31) |
Процедура |
|
|
– |
Передача зерна ( |
Процедура |
|
|
– |
Передача зерна ( |
Функция |
|
|
|
Генерация случайной строки длиной |
Процедура |
|
– |
– |
Окончание работы пакета |
Функция |
|
|
– |
Генерация псевдослучайного номера из диапазона с нижней границей |
dbms_utility#
Пакет добавляет просмотр стека вызовов.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Функция |
|
|
|
Возвращает стек вызовов внутри блока pl/pgsql |
utl_file#
Пакет добавляет операции с файловой системой.
В каждой сессии допускается до 10 открытых файловых дескрипторов. Длина строки ограничена 32 Кб.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Таблица |
|
|
– |
Таблица алиасов |
Домен |
|
|
– |
Домен для хранения файлового дескриптора |
Функция |
|
|
|
Закрытие файлового дескриптора |
Процедура |
|
– |
– |
Закрытие всех открытых файловых дескрипторов |
Процедура |
|
|
– |
Копирование файла. |
Процедура |
|
|
– |
Сброс буфера на диск |
Функция |
|
|
|
Получение атрибутов файла |
Функция |
|
|
|
Открытие файлового дескриптора. |
Процедура |
|
|
– |
Удаление файла |
Процедура |
|
|
– |
Переименование/перемещение файла |
Функция |
|
|
|
Получение строки из открытого файла |
Функция |
|
|
|
Получение строки из открытого файла |
Функция |
|
|
|
Проверка валидности файлового дескриптора |
Функция |
|
|
|
Добавление новой строки в открытый файл |
Функция |
|
|
|
Добавление записи в файл |
Функция |
|
|
|
Добавление новой строки в открытый файл |
Функция |
|
|
|
Форматированный вывод в открытый файл |
Функция |
|
– |
|
Вывод значения системной переменной |
plunit#
Пакет добавляет функции проверок.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Процедура |
|
|
– |
Проверка условия |
Процедура |
|
|
– |
Проверка условия |
Процедура |
|
|
– |
Проверка логического условия |
Процедура |
|
|
– |
Проверка логического условия |
Процедура |
|
|
– |
Проверка условия |
Процедура |
|
|
– |
Проверка условия |
Процедура |
|
|
– |
Проверка входного параметра на присутствие значения |
Процедура |
|
|
– |
Проверка входного параметра на отсутствие значения |
Процедура |
|
|
– |
Безусловный возврат с ошибкой |
plvchr#
Пакет добавляет специфичные для Oracle функции при работе с текстом.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Функция |
|
|
|
Скрытый траппер для функций |
Функция |
|
|
|
Возвращает код символа в кодировке |
Функция |
|
|
|
Возвращает первый символ в строке |
Функция |
|
|
|
Возвращает последний символ в строке |
Функция |
|
|
|
Возвращает |
Функция |
|
|
|
Возвращает текст, заключенный в апострофы |
Функция |
|
|
|
Возвращает текст, заключенный в кавычки |
Функция |
|
|
|
Удаление символов подстроки |
Функция |
|
|
|
Проверка значения параметра на заполненность |
Функция |
|
|
|
Проверка значения параметра на цифровой формат |
Функция |
|
|
|
Проверка значения параметра на текстовый формат |
Функция |
|
|
|
Проверка значения параметра на несоответствие ни цифровому, ни текстовому формату |
Функция |
|
|
|
Проверка значения текстового параметра на квотирование (кавычки или апострофы) |
plvdate#
Пакет добавляет специфичные для Oracle функции при работе с датами.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Функция |
|
|
|
Получение рабочей даты, спустя |
Функция |
|
|
|
Количество рабочих дней между двумя датами |
Функция |
|
|
|
Количество дней в месяце |
Процедура |
|
|
– |
Загрузка рабочего календаря. |
Функция |
|
|
|
Включение первой даты в расчет |
Функция |
|
– |
|
Исключение первой даты из расчета |
Функция |
|
|
|
Проверить, является ли дата рабочим днем |
Функция |
|
|
|
Проверить, является ли год високосным |
Функция |
|
|
|
Получить ближайшую дату рабочего дня |
Функция |
|
|
|
Получить дату следующего рабочего дня от заданного |
Функция |
|
|
|
Получить дату предыдущего рабочего дня относительно заданного |
Функция |
|
|
|
Задать дату как нерабочий день |
Процедура |
|
|
– |
Задать день недели как нерабочий. |
Функция |
|
|
|
Определение рабочего дня. Возвращаемый параметр - рекурсия (каждый год) |
Процедура |
|
|
– |
Задать день недели как рабочий. |
Функция |
|
– |
|
Задать Пасху как нерабочий день. Возвращаемый параметр - рекурсия (каждый год) |
Процедура |
|
|
– |
Задать Пасху как нерабочий день |
Функция |
|
– |
|
Задать Пасху как рабочий день. Возвращаемый параметр - рекурсия (каждый год) |
Процедура |
|
|
– |
Задать Пасху как рабочий день |
Функция |
|
– |
|
Задать Страстную пятницу как нерабочий день. Возвращаемый параметр - рекурсия (каждый год) |
Процедура |
|
|
– |
Задать Страстную пятницу как нерабочий день |
Функция |
|
– |
|
Проверить, является ли Пасха рабочим днем |
Функция |
|
– |
|
Проверить, является ли Страстная пятница рабочим днем |
Функция |
|
– |
|
Версия схем |
plvlex#
Пакет основан на оригинальном PL/Vision LEXical analysis и добавляет специфичные для Oracle функции при работе с лексемами.
ВНИМАНИЕ! Данный пакет основан на ключевых словах Postgresql и не является полностью совместимым с Oracle.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Функция |
|
|
|
Лексический парсер. |
plvstr#
Пакет добавляет специфичные для Oracle функции при работе со строками и текстовыми данными.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Функция |
|
|
|
Поиск подстроки в пределах от |
Функция |
|
|
|
Поиск позиции подстроки |
Функция |
|
|
|
Проверка, начинается ли искомая строка с определенного префикса |
Функция |
|
|
|
Возвращает |
Функция |
|
|
|
Возвращает |
Функция |
|
|
|
Возвращает подстроку, находящуюся до строки поиска |
Функция |
|
|
|
Возвращает подстроку, находящуюся после первого символа строки поиска |
Функция |
|
|
|
Усекает строку слева, если строка начинается с поисковой строки |
Функция |
|
|
|
Усекает строку справа, если строка заканчивается на поисковую строку |
Функция |
|
|
|
Реверсирует порядок символов в строке |
Функция |
|
|
|
Возвращает подстроку, начиная с позиции |
Функция |
|
|
|
Поиск и замена подстроки |
plvsubst#
Пакет добавляет специфичные для Oracle функции форматирования текста.
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Процедура |
|
|
– |
Задать маску поиска. |
Функция |
|
– |
|
Получить маску поиска |
Функция |
|
|
|
Применение форматирования по шаблону |
Изменения уровня базы данных#
Новые обьекты:
Тип |
Имя |
Входные переменные функции |
Выходные переменные функции |
Описание |
|---|---|---|---|---|
Представление |
|
– |
|
Специфичное для Oracle представление, необходимое для поддержки стандарта SQL |
Тип |
|
– |
– |
Специфичный для Oracle тип фиктивных данных, служащий для формирования корректного по форме запроса со всеми необходимыми полями и значениями |
Тип |
|
– |
– |
Специфичный для Oracle тип текстовых данных |
Тип |
|
– |
– |
Специфичный для Oracle тип текстовых данных |
Доработка#
Доработка:
В скриптах установки схема
publicзаменена наext.Ограничены привилегии.
Версия: 4.4.0.
В настоящее время используется нативный PL/PGSql. При миграции с Oracle процедуры переписываются вручную разработчиками. Расширение orafce представляет собой портирование части функциональных пакетов Oracle в базу данных PostgreSQL, а так же типов данных Oracle и функций для работы с этими типами данных.
Использование этого расширения позволяет сократить время для миграции баз данных с Oracle на Pangolin.
orafce принципиально не меняет модель работы с данными в Postgresql и не добавляет новых уровней поведения в модель Postgresql, в частности:
добавление пакетов Oracle не позволяет использовать переменные пакета; функциональный класс переменных отсутствует и не может быть портирован;
портирована модель Oracle 10g1.
В Oracle существует возможность объединить группу функций в один мета-объект – пакет. В Pangolin такая возможность отсутствует, а для объединения функций используются отдельные схемы базы данных.
В целях сокращения затрат при портировании БД Oracle, разработчикам предоставляются схемы данных:
Схема данных |
Описание |
|---|---|
|
Межсессионное взаимодействие, message queue |
|
Проверки, дополнительные тесты |
|
Логирование |
|
Межсессионное взаимодействие, каналы |
|
Генератор псевдослучайных значений |
|
Просмотр стека вызовов |
|
Работа с файловой системой |
|
Assert-функции |
|
Функции по работе с текстом |
|
Функции по работе с датами |
|
Семантический анализ запроса |
Влияние на обеспечение безопасности хранимых данных:
Решение добавляет функции для работы с файловой системой (пакет
utl_file). При эксплуатации решения следует явно разграничить права пользователей, имеющих право на работу с файловой системой. Добавляемые функции аналогичны существующим встроенным функциям СУБД Pangolin:pg_ls_dir();pg_stat_file();pg_read_file();pg_read_binary_file().
Решение добавляет функции межсессионного взаимодействия (пакет
dbms_pipe,dbms_alert). При эксплуатации решения следует явно разграничить права пользователей, имеющих право на работу с механизмом межсессионного взаимодействия.В целях обеспечения безопасности отозваны права
PUBLICна пакеты, нарушающие периметр БД:dbms_alert,dbms_pipe(межсессионное взаимодействие);dbms_output(вывод информации в консоль);dbms_utility(трассировка запросов);utl_file(работа с файловой системой).
Для использования этой функциональности следует явно указать права на использование схем для необходимых ролей.
Ограничения#
Для эксплуатации решения необходимо придерживаться принципа установки одинаковых версий расширения на всех узлах кластера высокой доступности, используемых в потоковой и логической репликации.
Схему
extследует добавить в параметрsearch_pathпоследней в порядке поиска.Все дополнительные пакеты и функции являются дополнительной функциональностью, не меняют поведения продукта в целом и требуют дополнительного тестирования в рамках миграции БД.
Установка#
Модуль считается «доверенным», поэтому его могут устанавливать пользователи, имеющие право CREATE в текущей базе данных:
CREATE EXTENSION IF NOT EXISTS orafce SCHEMA ext;
Настройка#
Настройка не требуется.
Использование модуля#
dbms_alert – модель межсессионного взаимодействия#
Сессия 1 |
Сессия 2 |
Сессия 3 |
Комментарий |
|---|---|---|---|
|
|
– |
Регистрация очереди событий |
|
|
– |
Ожидание событий в течение 10 секунд |
– |
– |
|
Добавление события |
dbms_assert – дополнительные проверки в целях защиты от SQL injection#
Сессия 1 |
Результат |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dbms_output – консольный вывод сообщений#
SELECT dbms_output.enable()
enable
--------
(1 row)
SELECT dbms_output.put(E'One\nTwo');
put
-----
(1 row)
SELECT dbms_output.get_lines(2);
get_lines
------------
("{""One +
Two""}",1)
(1 row)
SELECT dbms_output.get_line();
get_line
----------
(,1)
(1 row)
SELECT dbms_output.put_line(E'One\nTwo');
put_line
----------
(1 row)
SELECT dbms_output.get_line();
get_line
----------
("One +
Two",0)
(1 row)
SELECT dbms_output.serveroutput(true);
serveroutput
--------------
(1 row)
SELECT dbms_output.put(E'One\nTwo');
put
-----
(1 row)
SELECT dbms_output.get_line();
get_line
----------
("One +
Two",0)
(1 row)
SELECT dbms_output.disable();
disable
---------
(1 row)
dbms_pipe – эмуляция каналов Oracle#
Сессия 1 |
Сессия 2 |
Комментарий |
|---|---|---|
|
|
|
|
Список: |
|
|
||
|
||
|
||
|
||
|
||
|
||
|
Вывод кода возврата: 0 |
|
|
Вывод кода возврата: 0 |
|
|
Вывод 13 ( |
|
|
Вывод |
|
|
Вывод 12 ( |
|
|
ERROR: datatype mismatch |
|
|
Вывод: |
|
|
Вывод: 9 ( |
|
|
Вывод: 2 |
|
|
Вывод 9 ( |
|
|
Вывод: 2 |
|
|
Вывод 9 ( |
|
|
Вывод: 2 |
|
|
Вывод 11 ( |
|
|
Вывод: 2 |
|
|
Вывод: 0 (конец канала) |
|
|
dbms_random – псевдослучайные числа Oracle#
Сессия 1 |
Результат |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dbms_utility – просмотр стека вызовов#
do
$$
declare
res text;
begin
SELECT dbms_utility.format_call_stack() into res;
raise notice 'Call stack: %',res;
end
$$;
Пример результата запроса:
NOTICE: Call stack: ----- PL/pgSQL Call Stack -----
object line object
handle number name
0 function anonymous object
0 5 function anonymous object
DO
utl_file – операции с файловой системой#
INSERT INTO utl_file.utl_file_dir(dir,dirname) VALUES ('temp','/tmp');
COPY (SELECT * FROM pg_settings) TO '/tmp/pg_settings.csv';
Содержимое файла /tmp/pg_settings.csv:
do
$$
declare
f utl_file.file_type;
begin
if (SELECT fexists from utl_file.fgetattr('temp','pg_settings.csv')) then
f := utl_file.fopen('temp', 'pg_settings.csv', 'r');
<<readl>>
loop
begin
raise notice '%', utl_file.get_line(f);
exception
when no_data_found then
exit readl;
end;
end loop;
f := utl_file.fclose(f);
end if;
end;
$$;
SELECT utl_file.fremove('temp','pg_settings.csv');
SELECT utl_file.fclose_all();
plunit – функции проверок#
SELECT plunit.assert_equals(clock_timestamp(),current_timestamp,'Failed');
ERROR: Failed
DETAIL: Plunit.assertation fails (assert_equals).
SELECT plunit.assert_equals(clock_timestamp()::date,current_timestamp::date,'Failed');
assert_equals
---------------
(1 row)
SELECT plunit.assert_not_equals(clock_timestamp(),current_timestamp,'Failed');
assert_not_equals
-------------------
(1 row)
SELECT plunit.assert_not_equals(clock_timestamp()::date,current_timestamp::date,'Failed');
ERROR: Failed
DETAIL: Plunit.assertation fails (assert_not_equals).
SELECT plunit.assert_false(clock_timestamp()::date=current_timestamp::date,'Failed');
ERROR: Failed
DETAIL: Plunit.assertation fails (assert_false).
SELECT plunit.assert_true(clock_timestamp()=current_timestamp,'Failed');
ERROR: Failed
DETAIL: Plunit.assertation fails (assert_true).
SELECT plunit.assert_not_null(clock_timestamp(),'Failed');
assert_not_null
-----------------
(1 row)
SELECT plunit.assert_null(clock_timestamp(),'Failed');
ERROR: Failed
DETAIL: Plunit.assertation fails (assert_null).
SELECT plunit.fail('Failed');
ERROR: Failed
DETAIL: Plunit.assertation (assert_fail).
plvchr – специфичные для Oracle функции при работе с текстом#
Сессия 1 |
Результат |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plvdate – специфичные для Oracle функции при работе с датами#
Сессия 1 |
Результат |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plvlex – специфичные для Oracle функции при работе с лексемами#
SELECT * from plvlex.tokens ('
SELECT n.nspname AS schemaname,
c.relname AS viewname,
pg_get_userbyid(c.relowner) AS viewowner,
pg_get_viewdef(c.oid) AS definition
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = ''v''::"char";'
,true,true);
Пример результата выполнения запроса:
pos | token | code | class | separator | mod
-----+-----------------+------+---------+-----------+----------
0 | SELECT | 604 | KEYWORD | |
7 | n.nspname | | IDENT | |
17 | as | 290 | KEYWORD | |
20 | schemaname | | IDENT | |
30 | , | 44 | OTHERS | | self
32 | c.relname | | IDENT | |
42 | as | 290 | KEYWORD | |
45 | viewname | | IDENT | |
53 | , | 44 | OTHERS | | self
55 | pg_get_userbyid | | IDENT | |
70 | ( | 40 | OTHERS | | self
71 | c.relowner | | IDENT | |
81 | ) | 41 | OTHERS | | self
83 | as | 290 | KEYWORD | |
86 | viewowner | | IDENT | |
95 | , | 44 | OTHERS | | self
97 | pg_get_viewdef | | IDENT | |
111 | ( | 40 | OTHERS | | self
112 | c.oid | | IDENT | |
117 | ) | 41 | OTHERS | | self
119 | as | 290 | KEYWORD | |
122 | definition | | IDENT | |
133 | from | 418 | KEYWORD | |
138 | pg_class | | IDENT | |
147 | c | | IDENT | |
149 | left | 477 | KEYWORD | |
154 | join | 467 | KEYWORD | |
159 | pg_namespace | | IDENT | |
172 | n | | IDENT | |
174 | on | 524 | KEYWORD | |
177 | n.oid | | IDENT | |
183 | = | 61 | OTHERS | | self
185 | c.relnamespace | | IDENT | |
200 | where | 689 | KEYWORD | |
206 | c.relkind | | IDENT | |
216 | = | 61 | OTHERS | | self
218 | v | | SCONST | | qs
221 | v | 267 | OTHERS | | typecast
223 | char | | IDENT | | dq
229 | ; | 59 | OTHERS | | self
(40 rows)
plvstr – специфичные для Oracle функции при работе со строками и текстовыми данными#
Сессия 1 |
Результат |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plvsubst – специфичные для Oracle функции форматирования текста#
Применить форматирования по шаблону:
SELECT plvsubst.string('%s codename %s','Postgresql,Pangolin');или
SELECT plvsubst.string('%s codename %s',ARRAY['Postgresql','Pangolin']);Результат выполнения запросов:
string ------------------------------ Postgresql codename Pangolin (1 row)Получить маску поиска:
SELECT plvsubst.subst();Результат выполнения запросов:
subst ------- %s (1 row)
Ссылки на документацию разработчика#
Дополнительно поставляемый модуль orafce: https://github.com/orafce/orafce.