1
我正在研究一些需要在現有MySQL數據庫表上創建主鍵的Ruby代碼。它需要檢測和修復重複,允許索引創建成功,以下算法:我可以FlexMock方法在第一次調用時引發異常,然後在第二次調用時返回有效的對象嗎?
# 1. Query
ALTER TABLE foo ADD PRIMARY KEY (id)
# 2. Handle exception:
Duplicate entry '3761290' for key 'PRIMARY' (Mysql::Error)
# 3. Query:
SELECT COUNT(1) FROM TABLE foo WHERE id = 3761290
# 4. (Assuming 5 rows were returned from the previous query) Query:
DELETE FROM TABLE foo WHERE id = 3761290 LIMIT 4 OFFSET 1
# 5. retry ALTER TABLE query
測試看起來是這樣的:
def test_create_primary_key
table = 'foo'
db = flexmock
db.should_receive(:prepare).
with("ALTER TABLE #{table} ADD PRIMARY KEY (id)").
twice.
and_raise(Mysql::Error, "Duplicate entry '3761290' for key 'PRIMARY'")
db.should_receive(:prepare).
with("SELECT COUNT(1) FROM #{table} WHERE id = ?").
once.
and_return(MockStatement.new [ [5] ])
db.should_receive(:prepare).
with("DELETE FROM #{table} WHERE id = ? LIMIT 4 OFFSET 1").
once.
and_return(MockStatement.new [ [5] ])
indexer = Indexer.new :database_handle => db
indexer.create_indexes table
end
的問題是,代碼將在運行無限循環(除非它有最大重試條件,它可能會這樣做),因爲它將繼續從FlexMock的db中獲得異常。
理想情況下,模擬應該能夠在第一次引發異常,然後第二次返回有效的語句句柄。 #with的塊形式可能在這裏工作,但我想盡可能以乾淨的方式來完成。
任何想法?