Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Особенности совместнойработы Ruby и OracleНикита Шильников, Латера
Биллинг?2
Oracle?3
Условия• Нет доступа к таблицам• Все выборки делаются изпредставлений БД• Изменение данных происходитчерез вызов хранимых ...
Преимущества• Отдельный слой API• Безопасность. SQL-инъекции? Не слышал• Близость к данным• Скорость• Повторное использова...
Где это нужно?Приложение Ok?Интернет-магазин ✗Социальная сеть ✗Процессинг банка ✓Биллинг ✓6
• 160 таблиц• 340 представлений• 2000 хранимых процедур ифункций• 250 моделей• 120 контроллеров7
Схема8
Схема9
Представления10
PL/SQLdeclarel_hello varchar2(500);beginl_hello := Hello World!;dbms_output.put_line(l_hello);end;ПеременныеКодАнонимный б...
Хранимые процедурыcreate procedure print_message(p_msg in varchar2)asbegindbms_output.put_line(p_msg);end;ЗаголовокТело12
Пакетыcreate package hello_pkg asfunction salute(p_name in varchar2)return varchar2;end hello_pkg;create package body hell...
PL/SQLcreate procedure send_messages(p_group_id in users.group_id%type,p_msg in varchar2)asbeginfor l_user in (select user...
Динамический кодcreate procedure truncate_table(p_table_name in all_tables.table_name%type)asbeginexecute immediate -- Вып...
Вызов процедурconnection = ActiveRecord::Base.connection.raw_connectioncursor = connection.parse(<<-PLSQL) # Разборbeginmi...
ruby-plsqlplsql.star_wars_pkg.start_episode(p_episode_no: 1,p_show_subtitles: ‘N’)Kernel#plsqlПакет star_wars_pkgВызов про...
ActiveRecord + ruby-plsqlclass User < ActiveRecord::Baseset_create_method doplsql.users_pkg.add_user(p_name: name, p_band:...
AR + ruby-plsql + rails-plsqlclass User < ActiveRecord::Baseprocedure_method :change_name, plsql.users_pkg[rename]endUser....
Последний штрихmodule CustomSaveMethodsextend ActiveSupport::Concernincluded doset_create_method { put.values.first}set_up...
Былоclass Dragon < BaseModelheader doself.table_name = drgn_viewendendclass Dragon < ActiveRecord::Baseself.table_name = d...
22
Организация кода23
Организация кодаActiveRecord::BaseBaseModelAccounts::Base Documents::BaseAccounts::Current Documents::Contract24
Организация кода25
Обработка исключенийUNIQUE_CONSTRAINT_VIOLATED = 1beginplsql.users.insert(user_id: 1)plsql.users.insert(user_id: 1)rescue ...
Обработка исключенийclass OCINamedError < OCIErrorclass_attribute :oci_error_code, instance_writer: falsedef self.===(erro...
Обработка исключенийclass UniqueConstraintViolated < OCINamedErrorself.oci_error_code = 1endbeginplsql.users.insert(user_i...
Обработка исключений29
• 6 лет• RoR 1 -> 2.3 -> 3.2• MRI 1.8.7 -> 1.9.3Заключение30
Заключение31
Никита Шильников, Латера• fg@flashgordon.ru• github.com/flash-gordon• latera.ru32
Upcoming SlideShare
Loading in …5
×

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

779 views

Published on

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

http://devconf.ru/offers/91

Published in: Technology
  • Be the first to comment

  • Be the first to like this

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

  1. 1. Особенности совместнойработы Ruby и OracleНикита Шильников, Латера
  2. 2. Биллинг?2
  3. 3. Oracle?3
  4. 4. Условия• Нет доступа к таблицам• Все выборки делаются изпредставлений БД• Изменение данных происходитчерез вызов хранимых процедур4
  5. 5. Преимущества• Отдельный слой API• Безопасность. SQL-инъекции? Не слышал• Близость к данным• Скорость• Повторное использование кода5
  6. 6. Где это нужно?Приложение Ok?Интернет-магазин ✗Социальная сеть ✗Процессинг банка ✓Биллинг ✓6
  7. 7. • 160 таблиц• 340 представлений• 2000 хранимых процедур ифункций• 250 моделей• 120 контроллеров7
  8. 8. Схема8
  9. 9. Схема9
  10. 10. Представления10
  11. 11. PL/SQLdeclarel_hello varchar2(500);beginl_hello := Hello World!;dbms_output.put_line(l_hello);end;ПеременныеКодАнонимный блок11
  12. 12. Хранимые процедурыcreate procedure print_message(p_msg in varchar2)asbegindbms_output.put_line(p_msg);end;ЗаголовокТело12
  13. 13. Пакеты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
  14. 14. PL/SQLcreate 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;SQLPL14
  15. 15. Динамический кодcreate procedure truncate_table(p_table_name in all_tables.table_name%type)asbeginexecute immediate -- Выполняем любой кодtruncate table || p_table_name;end;15
  16. 16. Вызов процедурconnection = ActiveRecord::Base.connection.raw_connectioncursor = connection.parse(<<-PLSQL) # Разборbeginmighty_package.destroy_the_earth;end;PLSQLcursor.exec # Вызовcursor.close # Закрытие курсора16
  17. 17. ruby-plsqlplsql.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
  18. 18. ActiveRecord + ruby-plsqlclass 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
  19. 19. AR + ruby-plsql + rails-plsqlclass 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
  20. 20. Последний штрихmodule CustomSaveMethodsextend ActiveSupport::Concernincluded doset_create_method { put.values.first}set_update_method { put; reload_attributes }set_delete_method { del }endend20
  21. 21. Былоclass Dragon < BaseModelheader doself.table_name = drgn_viewendendclass Dragon < ActiveRecord::Baseself.table_name = drgn_viewself.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
  22. 22. 22
  23. 23. Организация кода23
  24. 24. Организация кодаActiveRecord::BaseBaseModelAccounts::Base Documents::BaseAccounts::Current Documents::Contract24
  25. 25. Организация кода25
  26. 26. Обработка исключенийUNIQUE_CONSTRAINT_VIOLATED = 1beginplsql.users.insert(user_id: 1)plsql.users.insert(user_id: 1)rescue OCIError => eif e.code == UNIQUE_CONSTRAINT_VIOLATEDputs Got it!’elseraiseendend26
  27. 27. Обработка исключенийclass OCINamedError < OCIErrorclass_attribute :oci_error_code, instance_writer: falsedef self.===(error)OCIError === error && error.code.in?([*oci_error_code])endend27
  28. 28. Обработка исключенийclass UniqueConstraintViolated < OCINamedErrorself.oci_error_code = 1endbeginplsql.users.insert(user_id: 1)plsql.users.insert(user_id: 1)rescue UniqueConstraintViolated => eputs Got it!end28
  29. 29. Обработка исключений29
  30. 30. • 6 лет• RoR 1 -> 2.3 -> 3.2• MRI 1.8.7 -> 1.9.3Заключение30
  31. 31. Заключение31
  32. 32. Никита Шильников, Латера• fg@flashgordon.ru• github.com/flash-gordon• latera.ru32

×