Учебники

OrientDB — Крючки

Хуки 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, мы надеемся, что информация, содержащаяся в этом руководстве, даст вам преимущество и позволит вам чувствовать себя комфортно с технологией, позволяющей вам успешно создавать триггеры базы данных по мере необходимости.