2013-11-18 4 views
6

В настоящее время я беру курс баз данных, и один из лабораторных вопросов меня озадачил, как реализовать вышеизложенное и действительно, если это было возможно. Я попытался найти docs, но метод транзакции определен довольно неопределенно.Как условно отменить транзакцию с использованием PG Ruby Gem

Это первый раз, когда я попытался сделать любую манипуляцию с базой данных БЕЗ комфортного одеяла Rails, и поэтому я немного потерялся. Мне удалось создать соединение с моей базой данных postgresql и выполнить инструкции, последняя вещь, которую мне нужно сделать, - откат транзакции на основе простого условия.

Позвольте мне показать вам код:

require 'pg' 
@conn = PG::Connection.open(:dbname => 'db_15_11_labs') 
@conn.prepare('insert', 'INSERT INTO house (housenumber, street) VALUES ($1, $2) returning id') 
@words = ["Foo", "Bar", "Bash", "Bang"] 

def populate 
    100.times.each_with_index do |i| 
    # cycle through the @words array for street names, use i as house number 
    ins = @conn.exec_prepared('insert', [i, "#{@words1[i % 4]} street"]) 
    end 
end 

В принципе, условие, что если возвращаемый идентификатор (ins[0]['id']) четно, откатить транзакцию. Я полагаю, что если ins[0]['id'] % 2 == 0 Мне нужно выбросить какое-то исключение, но как это сделать и что еще более важно, как я могу кодировать эту информацию в синтаксис, указанный в docs?

Спасибо за ваше время.

EDIT 1

Теперь я сумел получить синтаксис, который позволит в условиях, которые будут размещены в пределах определенной операции следующим образом:

@conn.transaction do |conn| 
    ins = @conn.exec_prepared('insert', [i, "#{@words1[i % 100]} street"]) 
end 

и поэтому этот вопрос действительно становится все более «как я могу бросить и поймать исключение, когда ins[0]['id'] % 2 == 0

Я попытался выполнить несколько простых руководств по сборке исключений, но следующим образом:

throw :id_exception if (@ins[0]['id'].to_i % 2) == 0 
    catch :id_exception do 
    puts "caught :id_exception #{}" 
end 

в результатах транзакции в 'throw': uncaught throw :id_exception (ArgumentError)

ответ

-1

Вы могли бы попробовать обертывание Добавленного заявления в ActiveRecord::Base.transaction, то после того, как вы делаете вставку, проверьте значение ins[0]['id'] и если это даже бросить исключение отката ... Отъезд the documentation по телефону ActiveRecord::Base.transaction.

Моя единственная забота - я не уверен, что это сработает с exec_prepared - я угадывание это будет, но это стоит проверить, чтобы подтвердить это.

+0

Привет спасибо за помощь, но во-первых, как уже упоминалось, что я делаю это без рельсов. во-вторых, мне удалось использовать жемчужину PG аналогичным образом, не могли бы вы взглянуть на частичное решение, которое у меня есть, и посоветовать, как повысить/уловить исключение? Я никогда не использовал исключения с Ruby, поскольку они обычно обрабатываются рельсами – DazBaldwin

2

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

попробовать что-то вроде этого:

class MyLittleIdError < StandardError 
end 

begin 
    @conn.transaction do |conn| 
     ins = conn.exec_prepared('insert', [i, "#{@words1[i % 100]} street"]) 
     raise MyLittleIdError if (ins[0]['id'].to_i % 2) == 0 
    end 
rescue MyLittleIdError 
    puts "aha! we should have rolled back." 
end 
Смежные вопросы