|
@@ -0,0 +1,145 @@
|
|
|
+
|
|
|
+
|
|
|
+require "dbi"
|
|
|
+
|
|
|
+class WeaselDbQueryHandle
|
|
|
+ def initialize(sth)
|
|
|
+ @sth = sth
|
|
|
+ end
|
|
|
+
|
|
|
+ def next()
|
|
|
+ row = @sth.fetch_hash
|
|
|
+ if row
|
|
|
+ return row
|
|
|
+ else
|
|
|
+ @sth.finish
|
|
|
+ return nil
|
|
|
+ end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+class Db
|
|
|
+ def initialize(database, user, password)
|
|
|
+ @dbh = DBI.connect("dbi:Pg:#{database}:localhost", user, password);
|
|
|
+ @dbh['AutoCommit'] = false
|
|
|
+ @transaction = false
|
|
|
+ @pre_initial_transaction=true
|
|
|
+ end
|
|
|
+
|
|
|
+ def do(query,*args)
|
|
|
+ @dbh.do(query,*args)
|
|
|
+ end
|
|
|
+ def transaction_begin()
|
|
|
+ @dbh.do("BEGIN") unless @pre_initial_transaction
|
|
|
+ @transaction = true
|
|
|
+ @pre_initial_transaction=false
|
|
|
+ end
|
|
|
+ def transaction_commit()
|
|
|
+ @dbh.do("COMMIT")
|
|
|
+ @transaction = false
|
|
|
+ end
|
|
|
+ def transaction_rollback()
|
|
|
+ @dbh.do("ROLLBACK")
|
|
|
+ end
|
|
|
+ def get_primarykey_name(table);
|
|
|
+
|
|
|
+ return table+'_id';
|
|
|
+ end
|
|
|
+
|
|
|
+ def update(table, values, keys)
|
|
|
+ cols = []
|
|
|
+ vals = []
|
|
|
+ values.each_pair{ |k,v|
|
|
|
+ cols << "#{k}=?"
|
|
|
+ vals << v
|
|
|
+ }
|
|
|
+
|
|
|
+ wheres = []
|
|
|
+ keys.each_pair{ |k,v|
|
|
|
+ wheres << "#{k}=?"
|
|
|
+ vals << v
|
|
|
+ }
|
|
|
+
|
|
|
+ throw "update value set empty" unless cols.size > 0
|
|
|
+ throw "where clause empty" unless wheres.size > 0
|
|
|
+
|
|
|
+ query = "UPDATE #{table} SET #{cols.join(',')} WHERE #{wheres.join(' AND ')}"
|
|
|
+ transaction_begin unless transaction_before=@transaction
|
|
|
+ r = @dbh.do(query, *vals)
|
|
|
+ transaction_commit unless transaction_before
|
|
|
+ return r
|
|
|
+ end
|
|
|
+
|
|
|
+ def update_row(table, values)
|
|
|
+ pk_name = get_primarykey_name(table);
|
|
|
+ throw "Ref not defined" unless values[pk_name]
|
|
|
+ return update(table, values.clone.delete_if{|k,v| k == pk_name}, { pk_name => values[pk_name] });
|
|
|
+ end
|
|
|
+ def insert(table, values)
|
|
|
+ cols = values.keys
|
|
|
+ vals = values.values
|
|
|
+ qmarks = values.values.collect{ '?' }
|
|
|
+
|
|
|
+ query = "INSERT INTO #{table} (#{cols.join(',')}) VALUES (#{qmarks.join(',')})"
|
|
|
+ transaction_begin unless transaction_before=@transaction
|
|
|
+ @dbh.do(query, *vals)
|
|
|
+ transaction_commit unless transaction_before
|
|
|
+ end
|
|
|
+
|
|
|
+ def insert_row(table, values)
|
|
|
+ pk_name = get_primarykey_name(table);
|
|
|
+ if values[pk_name]
|
|
|
+ insert(table, values)
|
|
|
+ else
|
|
|
+ transaction_begin unless transaction_before=@transaction
|
|
|
+ row = query_row("SELECT nextval(pg_get_serial_sequence('#{table}', '#{pk_name}')) AS newref");
|
|
|
+ throw "No newref?" unless row['newref']
|
|
|
+ values[pk_name] = row['newref']
|
|
|
+ insert(table, values);
|
|
|
+ transaction_commit unless transaction_before
|
|
|
+ end
|
|
|
+ end
|
|
|
+ def delete_row(table, ref)
|
|
|
+ pk_name = get_primarykey_name(table);
|
|
|
+ query = "DELETE FROM #{table} WHERE #{pk_name}=?"
|
|
|
+ transaction_begin unless transaction_before=@transaction
|
|
|
+ @dbh.do(query, ref)
|
|
|
+ transaction_commit unless transaction_before
|
|
|
+ end
|
|
|
+ def query(query, *params)
|
|
|
+ sth = @dbh.execute(query, *params)
|
|
|
+ while row = sth.fetch_hash
|
|
|
+ yield row
|
|
|
+ end
|
|
|
+ sth.finish
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ def query_row(query, *params)
|
|
|
+ sth = @dbh.execute(query, *params)
|
|
|
+
|
|
|
+ row = sth.fetch_hash
|
|
|
+ if row == nil
|
|
|
+ sth.finish
|
|
|
+ return nil
|
|
|
+ elsif sth.fetch_hash != nil
|
|
|
+ sth.finish
|
|
|
+ throw "More than one result when querying for #{query}"
|
|
|
+ else
|
|
|
+ sth.finish
|
|
|
+ return row
|
|
|
+ end
|
|
|
+ end
|
|
|
+ def query_all(query, *params)
|
|
|
+ sth = @dbh.execute(query, *params)
|
|
|
+
|
|
|
+ rows = sth.fetch_all
|
|
|
+ return nil if rows.size == 0
|
|
|
+ return rows
|
|
|
+ end
|
|
|
+ def query2(query, *params)
|
|
|
+ sth = @dbh.execute(query, *params)
|
|
|
+ return WeaselDbQueryHandle.new(sth)
|
|
|
+ end
|
|
|
+end
|