32
Особенности совместной работы Ruby и Oracle Никита Шильников, Латера

Особенности совместной работы Ruby и Oracle

  • Upload
    -

  • View
    342

  • Download
    12

Embed Size (px)

Citation preview

Page 1: Особенности совместной работы Ruby и Oracle

Особенности совместной работы Ruby и Oracle

Никита Шильников, Латера

Page 2: Особенности совместной работы Ruby и Oracle

Биллинг?

2

Page 3: Особенности совместной работы Ruby и Oracle

Oracle?

3

Page 4: Особенности совместной работы Ruby и Oracle

Условия

• Нет доступа к таблицам

• Все выборки делаются из

представлений БД

• Изменение данных происходит

через вызов хранимых процедур

4

Page 5: Особенности совместной работы Ruby и Oracle

Преимущества

• Отдельный слой API

• Безопасность. SQL-инъекции? Не слышал

• Близость к данным

• Скорость

• Повторное использование кода

5

Page 6: Особенности совместной работы Ruby и Oracle

Где это нужно?

Приложение Ok?

Интернет-магазин ✗

Социальная сеть ✗

Процессинг банка ✓

Биллинг ✓

6

Page 7: Особенности совместной работы Ruby и Oracle

• 160 таблиц

• 340 представлений

• 2000 хранимых процедур и

функций

• 250 моделей

• 120 контроллеров

7

Page 8: Особенности совместной работы Ruby и Oracle

Схема

8

Page 9: Особенности совместной работы Ruby и Oracle

Схема

9

Page 10: Особенности совместной работы Ruby и Oracle

Представления

10

Page 11: Особенности совместной работы Ruby и Oracle

PL/SQL

declarel_hello varchar2(500);

beginl_hello := 'Hello World!';dbms_output.put_line(l_hello);

end;

Переменные

Код

Анонимный блок

11

Page 12: Особенности совместной работы Ruby и Oracle

Хранимые процедуры

create procedure print_message(p_msg in varchar2)

asbegindbms_output.put_line(p_msg);

end;

Заголовок

Тело

12

Page 13: Особенности совместной работы Ruby и Oracle

Пакеты

create package hello_pkg asfunction salute(p_name in varchar2)return varchar2;

end hello_pkg;

create package body hello_pkg asfunction salute(p_name in varchar2)return varchar2asbeginreturn 'Hello, ' || p_name;

end;end hello_pkg;

Заголовок

Тело

13

Page 14: Особенности совместной работы Ruby и Oracle

PL/SQL

create procedure send_messages(p_group_id in users.group_id%type,p_msg in varchar2)

asbeginfor l_user in (select user_idfrom userswhere group_id = p_group_id)

loopsend_message(

p_user_id => l_user.user_id,p_msg => p_msg);

end loop;end;

SQL

PL

14

Page 15: Особенности совместной работы Ruby и Oracle

Динамический код

create procedure truncate_table(p_table_name in all_tables.table_name%type)

asbeginexecute immediate -- Выполняем любой код'truncate table ' || p_table_name;

end;

15

Page 16: Особенности совместной работы Ruby и Oracle

Вызов процедур

connection = ActiveRecord::Base.connection.raw_connectioncursor = connection.parse(<<-PLSQL) # Разборbeginmighty_package.destroy_the_earth;

end;PLSQLcursor.exec # Вызовcursor.close # Закрытие курсора

16

Page 17: Особенности совместной работы Ruby и Oracle

ruby-plsql

plsql.star_wars_pkg.start_episode(p_episode_no: 1,p_show_subtitles: ‘N’)

Kernel#plsql

Пакет star_wars_pkg

Вызов процедуры star_wars_pkg.start_episode

Аргументы процедуры

beginstar_wars_pkg.start_episode(p_episode_no => :p_episode_no, p_show_subtitles => :p_show_subtitles);

end;

17

Page 18: Особенности совместной работы Ruby и Oracle

ActiveRecord + ruby-plsql

class User < ActiveRecord::Baseset_create_method doplsql.users_pkg.add_user(p_name: name, p_band: band)

endendUser.create(name: 'Robert Plant', band: 'Led Zeppelin')

beginusers_pkg.add_user(p_name => :p_name, p_band => :p_band);

end;

18

Page 19: Особенности совместной работы Ruby и Oracle

AR + ruby-plsql + rails-plsql

class User < ActiveRecord::Baseprocedure_method :change_name, plsql.users_pkg['rename']

endUser.first.change_name(p_name: 'Nils Bohr')

beginusers_pkg.rename(p_user_id => :p_user_id,p_name => :p_name);

end;

Берется из атрибутов объекта

19

Page 20: Особенности совместной работы Ruby и Oracle

Последний штрих

module CustomSaveMethodsextend ActiveSupport::Concernincluded doset_create_method { put.values.first}set_update_method { put; reload_attributes }set_delete_method { del }

endend

20

Page 21: Особенности совместной работы Ruby и Oracle

Было

class Dragon < BaseModelheader doself.table_name = 'drgn_view'

endend

class Dragon < ActiveRecord::Baseself.table_name = 'drgn_view'self.primary_key = dragon_iddef create

_run_create_callbacks docursor = connection.parse(<<-PLSQL)

begindrgn_pkg.put_drgn(p_dragon_id => :p_dragon_id,p_name => :p_name,p_type => :p_type,p_birth_date => :p_birth_date,p_location => :p_location);

end;PLSQLcursor.bind(':p_gragon', nil, Number)cursor.bind(':p_name', name)cursor.bind(':p_type', type)cursor.bind(':p_birth_date',

birth_date, Date)cursor.bind(':p_location', location)cursor.execcursor.close...

Стало

21

Page 22: Особенности совместной работы Ruby и Oracle

22

Page 23: Особенности совместной работы Ruby и Oracle

Организация кода

23

Page 24: Особенности совместной работы Ruby и Oracle

Организация кода

ActiveRecord::Base

BaseModel

Accounts::Base Documents::Base

Accounts::Current Documents::Contract

24

Page 25: Особенности совместной работы Ruby и Oracle

Организация кода

25

Page 26: Особенности совместной работы Ruby и Oracle

Обработка исключений

UNIQUE_CONSTRAINT_VIOLATED = 1

beginplsql.users.insert(user_id: 1)plsql.users.insert(user_id: 1)

rescue OCIError => eif e.code == UNIQUE_CONSTRAINT_VIOLATEDputs 'Got it!’

elseraise

endend

26

Page 27: Особенности совместной работы Ruby и Oracle

Обработка исключений

class OCINamedError < OCIErrorclass_attribute :oci_error_code, instance_writer: false

def self.===(error)OCIError === error && error.code.in?([*oci_error_code])

endend

27

Page 28: Особенности совместной работы Ruby и Oracle

Обработка исключений

class UniqueConstraintViolated < OCINamedErrorself.oci_error_code = 1

end

beginplsql.users.insert(user_id: 1)plsql.users.insert(user_id: 1)

rescue UniqueConstraintViolated => eputs 'Got it!'

end

28

Page 29: Особенности совместной работы Ruby и Oracle

Обработка исключений

29

Page 30: Особенности совместной работы Ruby и Oracle

• 6 лет

• RoR 1 -> 2.3 -> 3.2

• MRI 1.8.7 -> 1.9.3

Заключение

30

Page 31: Особенности совместной работы Ruby и Oracle

Заключение

31