Хуки OrientDB — это не что иное, как триггеры в терминологии базы данных, которые разрешают внутренние события до и после каждой операции CRUD в пользовательских приложениях. Вы можете использовать ловушки для написания пользовательских правил проверки, для обеспечения безопасности или для организации внешних событий, таких как репликация в реляционную СУБД.
OrientDB поддерживает два вида хуков —
Динамический зацеп — триггеры, которые могут быть построены на уровне класса и / или уровне документа.
Java (Native) Hook — триггеры, которые могут быть построены с использованием классов Java.
Динамические крючки
Динамические хуки являются более гибкими, чем хуки Java, потому что они могут быть изменены во время выполнения и могут запускаться для каждого документа, если это необходимо, но медленнее, чем хуки Java.
Чтобы выполнить хуки для ваших документов, сначала позвольте вашим классам расширить базовый класс OTriggered . Позже определите пользовательское свойство для интересующего события. Ниже приведены доступные события.
-
onBeforeCreate — вызывается перед созданием нового документа.
-
onAfterCreate — вызывается после создания нового документа.
-
onBeforeRead — Вызывается перед чтением документа.
-
onAfterRead — Вызывается после прочтения документа.
-
onBeforeUpdate — вызывается перед обновлением документа.
-
onAfterUpdate — вызывается после обновления документа.
-
onBeforeDelete — Вызывается перед удалением документа.
-
onAfterDelete — Вызывается после удаления документа.
onBeforeCreate — вызывается перед созданием нового документа.
onAfterCreate — вызывается после создания нового документа.
onBeforeRead — Вызывается перед чтением документа.
onAfterRead — Вызывается после прочтения документа.
onBeforeUpdate — вызывается перед обновлением документа.
onAfterUpdate — вызывается после обновления документа.
onBeforeDelete — Вызывается перед удалением документа.
onAfterDelete — Вызывается после удаления документа.
Динамические Крючки могут звонить —
-
Функции, написанные на SQL, Javascript или любом языке, поддерживаемом OrientDB и JVM.
-
Статические методы Java.
Функции, написанные на SQL, Javascript или любом языке, поддерживаемом OrientDB и JVM.
Статические методы Java.
Крючки уровня класса
Хуки уровня класса определены для всех документов, которые относятся к классу. Ниже приведен пример настройки ловушки, которая действует на уровне класса в отношении документов счета.
CREATE CLASS Invoice EXTENDS OTriggered ALTER CLASS Invoice CUSTOM onAfterCreate = invoiceCreated
Давайте создадим функцию invoiceCreated в Javascript, которая печатает на консоли сервера номер созданного счета.
CREATE FUNCTION invoiceCreated "print('\\nInvoice created: ' + doc.field ('number'));" LANGUAGE Javascript
Теперь попробуйте зацепить, создав новый документ Invoice .
INSERT INTO Invoice CONTENT {number: 100, notes: 'This is a test}
Если эта команда выполнена успешно, вы получите следующий вывод.
Invoice created: 100
Уровень документа Крюк
Вы можете определить специальное действие только для одного или нескольких документов. Для этого позвольте вашему классу расширить класс OTriggered .
Например, давайте выполним триггер в виде функции Javascript для существующего класса Profile для всех документов со свойством account = ‘Premium’. Триггер будет вызван для предотвращения удаления документов.
ALTER CLASS Profile SUPERCLASS OTriggered UPDATE Profile SET onBeforeDelete = 'preventDeletion' WHERE account = 'Premium'
Давайте создадим функцию Javascript protectDeletion () .
CREATE FUNCTION preventDeletion "throw new java.lang.RuntimeException('Cannot delete Premium profile ' + doc)" LANGUAGE Javascript
А затем протестируйте ловушку, пытаясь удалить «Премиум» аккаунт.
DELETE FROM #12:1 java.lang.RuntimeException: Cannot delete Premium profile profile#12:1{onBeforeDelete:preventDeletion,account:Premium,name:Jill} v-1 (<Unknown source>#2) in <Unknown source> at line number 2
JAVA Крючки
Один из распространенных вариантов использования OrientDB Hooks (триггеры) — управление созданными и обновленными датами для любого или всех классов. Например, вы можете установить поле CreatedDate всякий раз, когда создается запись, и устанавливать поле UpdatedDate при каждом обновлении записи, и делать это таким образом, чтобы вы реализовали логику один раз на уровне базы данных, и вам больше никогда не придется беспокоиться об этом в прикладной уровень.
Перед созданием вам необходимо скачать файл orientdb-core.jar, перейдя по следующей ссылке скачать ядро OrientDB . А затем скопируйте этот файл JAR в папку, где вы хотите сохранить исходный файл Java.
Создать файл хука
Создайте файл Java с именем HookTest.java , который будет проверять механизм Hook с использованием языка Java.
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.ReentrantLock; import com.orientechnologies.orient.core.hook.ODocumentHookAbstract; import com.orientechnologies.orient.core.hook.ORecordHook; import com.orientechnologies.orient.core.hook.ORecordHookAbstract; import com.orientechnologies.orient.core.db.ODatabaseLifecycleListener; import com.orientechnologies.orient.core.db.ODatabase; import com.orientechnologies.orient.core.record.ORecord; import com.orientechnologies.orient.core.record.impl.ODocument; public class HookTest extends ODocumentHookAbstract implements ORecordHook { public HookTest() { } @Override public DISTRIBUTED_EXECUTION_MODE getDistributedExecutionMode() { return DISTRIBUTED_EXECUTION_MODE.BOTH; } public RESULT onRecordBeforeCreate( ODocument iDocument ) { System.out.println("Ran create hook"); return ORecordHook.RESULT.RECORD_NOT_CHANGED; } public RESULT onRecordBeforeUpdate( ODocument iDocument ) { System.out.println("Ran update hook"); return ORecordHook.RESULT.RECORD_NOT_CHANGED; } }
Приведенный выше пример кода печатает соответствующий комментарий каждый раз, когда вы создаете или обновляете запись этого класса.
Давайте добавим еще один подключаемый файл setCreatedUpdatedDates.java следующим образом:
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.ReentrantLock; import com.orientechnologies.orient.core.hook.ODocumentHookAbstract; import com.orientechnologies.orient.core.hook.ORecordHook; import com.orientechnologies.orient.core.hook.ORecordHookAbstract; import com.orientechnologies.orient.core.db.ODatabaseLifecycleListener; import com.orientechnologies.orient.core.db.ODatabase; import com.orientechnologies.orient.core.record.ORecord; import com.orientechnologies.orient.core.record.impl.ODocument; public class setCreatedUpdatedDates extends ODocumentHookAbstract implements ORecordHook { public setCreatedUpdatedDates() { } @Override public DISTRIBUTED_EXECUTION_MODE getDistributedExecutionMode() { return DISTRIBUTED_EXECUTION_MODE.BOTH; } public RESULT onRecordBeforeCreate( ODocument iDocument ) { if ((iDocument.getClassName().charAt(0) == 't') || (iDocument.getClassName().charAt(0)=='r')) { iDocument.field("CreatedDate", System.currentTimeMillis() / 1000l); iDocument.field("UpdatedDate", System.currentTimeMillis() / 1000l); return ORecordHook.RESULT.RECORD_CHANGED; } else { return ORecordHook.RESULT.RECORD_NOT_CHANGED; } } public RESULT onRecordBeforeUpdate( ODocument iDocument ) { if ((iDocument.getClassName().charAt(0) == 't') || (iDocument.getClassName().charAt(0)=='r')) { iDocument.field("UpdatedDate", System.currentTimeMillis() / 1000l); return ORecordHook.RESULT.RECORD_CHANGED; } else { return ORecordHook.RESULT.RECORD_NOT_CHANGED; } } }
Вышеприведенный код выполняет поиск любого класса, который начинается с букв « r » или « t » и устанавливает CreatedDate и UpdatedDate при создании записи и устанавливает только UpdateDate при каждом обновлении записи.
Компиляция Java-хуков
Скомпилируйте код Java с помощью следующей команды. Примечание . Храните загруженный файл jar и эти файлы Java в одной папке.
$ jar cf hooks-1.0-SNAPSHOT.jar *.java
Переместить скомпилированный код туда, где его может найти сервер OrientDB
Вам необходимо скопировать готовый файл .jar в каталог, где их будет искать ваш сервер OrientDB. Это означает, что папка « ./lib » в корневом каталоге вашего сервера OrientDB будет выглядеть так:
$ cp hooks-1.0-SNAPSHOT.jar "$ORIENTDB_HOME/lib"
Включите тестовый хук в файле конфигурации сервера OrientDB
Отредактируйте файл $ ORIENTDB_HOME / config / orientdb-server-config.xml и добавьте следующий раздел в конец файла.
<hooks> <hook class = "HookTest" position = "REGULAR"/> </hooks> ... </orient-server>
Перезагрузите сервер OrientDB
После перезапуска сервера OrientDB перехват, определенный вами в orientdb-server-config.xml, становится активным. Запустите консоль OrientDB, подключите ее к базе данных и выполните следующую команду:
INSERT INTO V SET ID = 1;
Если эта команда выполнена успешно, вы получите следующий вывод.
Ran create hook
Теперь выполните следующую команду —
UPDATE V SET ID = 2 WHERE ID = 1;
Если эта команда выполнена успешно, вы получите следующий вывод.
Ran update hook
Включите Real Hook в файле конфигурации сервера OrientDB
Отредактируйте $ ORIENTDB_HOME / config / orientdb-server-config.xml и измените раздел ловушек следующим образом:
<hooks> <hook class="setCreatedUpdatedDates" position="REGULAR"/> </hooks> ... </orient-server>
Перезагрузите сервер OrientDB
Создайте новый класс, который начинается с буквы « r » или « t » —
CREATE CLASS tTest EXTENDS V;
Теперь вставьте запись —
INSERT INTO tTest SET ID = 1 SELECT FROM tTest
Если эта команда выполнена успешно, вы получите следующий вывод.
----+-----+------+----+-----------+----------- # |@RID |@CLASS|ID |CreatedDate|UpdatedDate ----+-----+------+----+-----------+----------- 0 |#19:0|tTest |1 |1427597275 |1427597275 ----+-----+------+----+-----------+-----------
Даже если вы не указали значения для CreatedDate и updatedDate , OrientDB установил эти поля автоматически.
Далее вам необходимо обновить запись с помощью следующей команды —
UPDATE tTest SET ID = 2 WHERE ID = 1; SELECT FROM tTest;
Если эта команда выполнена успешно, вы получите следующий вывод.
----+-----+------+----+-----------+----------- # |@RID |@CLASS|ID |CreatedDate|UpdatedDate ----+-----+------+----+-----------+----------- 0 |#19:0|tTest |2 |1427597275 |1427597306 ----+-----+------+----+-----------+-----------
Вы можете видеть, что OrientDB изменил UpdatedDate, но оставил CreatedDate без изменений.
OrientDB Java Hooks может быть чрезвычайно ценным инструментом, помогающим автоматизировать работу, которую в противном случае пришлось бы выполнять в коде приложения. Поскольку многие администраторы баз данных не всегда являются экспертами по Java, мы надеемся, что информация, содержащаяся в этом руководстве, даст вам преимущество и позволит вам чувствовать себя комфортно с технологией, позволяющей вам успешно создавать триггеры базы данных по мере необходимости.