OrientDB - крючки

OrientDB Hooksв терминологии базы данных не что иное, как триггеры, которые разрешают внутренние события до и после каждой операции CRUD в пользовательских приложениях. Вы можете использовать хуки для написания собственных правил проверки, для обеспечения безопасности или для организации внешних событий, таких как репликация в реляционной СУБД.

OrientDB поддерживает два типа перехватчиков:

Dynamic Hook - Триггеры, которые могут быть построены на уровне класса и / или на уровне документа.

Java (Native) Hook - Триггеры, которые могут быть построены с использованием классов Java.

Динамические хуки

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

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

  • onBeforeCreate - называется before создание нового документа.

  • onAfterCreate - называется after создание нового документа.

  • onBeforeRead - называется before чтение документа.

  • onAfterRead - называется after чтение документа.

  • onBeforeUpdate - называется before обновление документа.

  • onAfterUpdate - называется after обновление документа.

  • onBeforeDelete - называется before удаление документа.

  • onAfterDelete - называется after удаление документа.

Dynamic Hooks может вызывать -

  • Функции, написанные на SQL, Javascript или любом языке, поддерживаемом OrientDB и JVM.

  • Статические методы Java.

Крючки уровня класса

Перехватчики уровня класса определены для всех документов, относящихся к классу. Ниже приведен пример настройки ловушки, которая действует на уровне класса в отношении документов Invoice.

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'

Создадим preventDeletion() Функция Javascript.

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 является управление датами создания и обновления любого или всех классов. Например, вы можете установить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 при создании записи и устанавливает только UpdatedDate при каждом обновлении записи.

Компиляция хуков Java

Скомпилируйте код Java с помощью следующей команды. Note: Храните загруженный файл jar и эти файлы Java в одной папке.

$ jar cf hooks-1.0-SNAPSHOT.jar *.java

Переместите скомпилированный код туда, где сервер OrientDB может его найти

Вам нужно скопировать готовый файл .jar в каталог, где ваш сервер OrientDB будет их искать. Это означает './libПапка в корневом каталоге вашего сервера OrientDB будет выглядеть так:

$ cp hooks-1.0-SNAPSHOT.jar "$ORIENTDB_HOME/lib"

Включить Test Hook в файле конфигурации сервера 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 оставаться без изменений.

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