ldap.search( :base => treebase, :filter => filter ) do |entry|
puts "DN: #{entry.dn}"
entry.each do |attribute, values|
puts " #{attribute}:"
values.each do |value|
puts " --->#{value}"
end
end
end
p ldap.get_operation_result
Какая
из этих библиотек лучше — дело вкуса. Я рекомендую познакомиться со всеми и сформировать собственное мнение.
10.4.5. Интерфейс с Oracle
Oracle — одна из наиболее мощных и популярных СУБД в мире. Понятно, что было много попыток реализовать интерфейс с этой базой данных из Ruby. На сегодняшний день лучшей считается библиотека OCI8, которую написал Кубо Такехиро (Kubo Takehiro).
Вопреки названию, библиотека OCI8 работает и с версиями Oracle младше 8. Но она еще не вполне зрелая, поэтому не позволяет воспользоваться некоторыми средствами, появившимися в последних версиях.
API состоит из двух уровней: тонкая обертка (низкоуровневый API, довольно точно повторяющий интерфейс вызовов Oracle — Call Level Interface). Но в большинстве случаев вы будете работать с высокоуровневым API. Не исключено, что в будущем низкоуровневый API станет недокументированным.
Модуль OCI8 включает классы
Cursor
и
Blob
. Класс
OCIException
служит предком всех классов исключений, которые могут возникнуть при работе с базой данных:
OCIError
,
OCIBreak
и
OCIInvalidHandle
.
Чтобы установить соединение с сервером, вызывается метод
OCI8.new
, которому нужно передать как минимум имя и пароль пользователя. В ответ возвращается описатель, который можно использовать для выполнения запросов. Пример:
require 'oci8'
session = OCI8.new('user', 'password')
query = "SELECT TO_CHAR(SYSDATE, 'YYYY/MM/DD') FROM DUAL"
cursor = session.exec(query)
result = cursor.fetch # В данном случае всего одна итерация.
cursor.close
session.logoff
В примере выше показано, как манипулировать курсором, хотя в данном случае перед закрытием выполняется всего одна операция
fetch
. Конечно, можно выбрать и несколько строк:
query = 'select * from some_table'
cursor = session.exec(query)
while row = cursor.fetch
puts row.join(",")
end
cursor.close
# Или с помощью блока:
nrows = session.exec(query) do |row|
puts row.join(",")
end
Связанные
переменные в запросе напоминают символы. Есть несколько способов связать переменные со значениями:
session = OCI8.new("user","password")
query = "select * from people where name = :name"
# Первый способ...
session.exec(query,'John Smith')
# Второй...
cursor = session.parse(query)
cursor.exec('John Smith')
# Третий...
cursor = session.parse(query)
cursor.bind_param(':name','John Smith') # Связывание по имени.
cursor.exec
# И четвертый.
cursor = session.parse(query)
cursor.bind_param(1,'John Smith') # Связывание по номеру.
cursor.exec
Для тех, кто предпочитает интерфейс DBI, имеется соответствующий адаптер. Дополнительную информацию можно найти в документации по OCI8
10.4.6. Обертка вокруг DBI
Теоретически интерфейс DBI обеспечивает доступ к любым базам данных. Иными словами, один и тот же код должен работать и с Oracle, и с MySQL, и с PostgreSQL, и с любой другой СУБД, стоит лишь изменить одну строку, в которой указан нужный адаптер. Иногда эта идеология не срабатывает для сложных операций, специфичных для конкретной СУБД, но для рутинных задач она вполне годится.
Пусть имеется база данных под управлением Oracle и используется драйвер (он же адаптер), поставляемый вместе с библиотекой OCI8. Методу
connect
следует передать достаточно информации для успешного соединения с базой данных. Все более или менее интуитивно очевидно.
require "dbi"
db = DBI.connect("dbi:OCI8:mydb", "user", "password")
query = "select * from people"
stmt = db.prepare(query)
stmt.execute
while row = stmt.fetch do
puts row.join(",")
end
stmt.finish
db.disconnect
Здесь метод
prepare
— это некий вариант компиляции или синтаксического анализа запроса, который позже исполняется. Метод
fetch
извлекает одну строку из результирующего набора и возвращает
nil
, если строк не осталось (поэтому мы и воспользовались циклом
while
). Метод
finish
можно считать вариантом закрытия или освобождения ресурсов.