db.rb 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/usr/bin/ruby
  2. require "dbi"
  3. class WeaselDbQueryHandle
  4. def initialize(sth)
  5. @sth = sth
  6. end
  7. def next()
  8. row = @sth.fetch_hash
  9. if row
  10. return row
  11. else
  12. @sth.finish
  13. return nil
  14. end
  15. end
  16. end
  17. class Db
  18. def initialize(database, user, password)
  19. @dbh = DBI.connect("dbi:Pg:#{database}:localhost", user, password);
  20. @dbh['AutoCommit'] = false
  21. @transaction = false
  22. @pre_initial_transaction=true
  23. end
  24. def do(query,*args)
  25. @dbh.do(query,*args)
  26. end
  27. def transaction_begin()
  28. @dbh.do("BEGIN") unless @pre_initial_transaction
  29. @transaction = true
  30. @pre_initial_transaction=false
  31. end
  32. def transaction_commit()
  33. @dbh.do("COMMIT")
  34. @transaction = false
  35. end
  36. def transaction_rollback()
  37. @dbh.do("ROLLBACK")
  38. end
  39. def get_primarykey_name(table);
  40. #return 'ref';
  41. return table+'_id';
  42. end
  43. def update(table, values, keys)
  44. cols = []
  45. vals = []
  46. values.each_pair{ |k,v|
  47. cols << "#{k}=?"
  48. vals << v
  49. }
  50. wheres = []
  51. keys.each_pair{ |k,v|
  52. wheres << "#{k}=?"
  53. vals << v
  54. }
  55. throw "update value set empty" unless cols.size > 0
  56. throw "where clause empty" unless wheres.size > 0
  57. query = "UPDATE #{table} SET #{cols.join(',')} WHERE #{wheres.join(' AND ')}"
  58. transaction_begin unless transaction_before=@transaction
  59. r = @dbh.do(query, *vals)
  60. transaction_commit unless transaction_before
  61. return r
  62. end
  63. def update_row(table, values)
  64. pk_name = get_primarykey_name(table);
  65. throw "Ref not defined" unless values[pk_name]
  66. return update(table, values.clone.delete_if{|k,v| k == pk_name}, { pk_name => values[pk_name] });
  67. end
  68. def insert(table, values)
  69. cols = values.keys
  70. vals = values.values
  71. qmarks = values.values.collect{ '?' }
  72. query = "INSERT INTO #{table} (#{cols.join(',')}) VALUES (#{qmarks.join(',')})"
  73. transaction_begin unless transaction_before=@transaction
  74. @dbh.do(query, *vals)
  75. transaction_commit unless transaction_before
  76. end
  77. def insert_row(table, values)
  78. pk_name = get_primarykey_name(table);
  79. if values[pk_name]
  80. insert(table, values)
  81. else
  82. transaction_begin unless transaction_before=@transaction
  83. row = query_row("SELECT nextval(pg_get_serial_sequence('#{table}', '#{pk_name}')) AS newref");
  84. throw "No newref?" unless row['newref']
  85. values[pk_name] = row['newref']
  86. insert(table, values);
  87. transaction_commit unless transaction_before
  88. end
  89. end
  90. def delete_row(table, ref)
  91. pk_name = get_primarykey_name(table);
  92. query = "DELETE FROM #{table} WHERE #{pk_name}=?"
  93. transaction_begin unless transaction_before=@transaction
  94. @dbh.do(query, ref)
  95. transaction_commit unless transaction_before
  96. end
  97. def query(query, *params)
  98. sth = @dbh.execute(query, *params)
  99. while row = sth.fetch_hash
  100. yield row
  101. end
  102. sth.finish
  103. end
  104. # nil if no results
  105. # hash if one match
  106. # throw otherwise
  107. def query_row(query, *params)
  108. sth = @dbh.execute(query, *params)
  109. row = sth.fetch_hash
  110. if row == nil
  111. sth.finish
  112. return nil
  113. elsif sth.fetch_hash != nil
  114. sth.finish
  115. throw "More than one result when querying for #{query}"
  116. else
  117. sth.finish
  118. return row
  119. end
  120. end
  121. def query_all(query, *params)
  122. sth = @dbh.execute(query, *params)
  123. rows = sth.fetch_all
  124. return nil if rows.size == 0
  125. return rows
  126. end
  127. def query2(query, *params)
  128. sth = @dbh.execute(query, *params)
  129. return WeaselDbQueryHandle.new(sth)
  130. end
  131. end