module MetaDb # FIXME Why on earth did I do this? # class Connection # In derived classes, no initialization may take place after the call to # super because otherwise #initialize would call the user-supplied block # with a partial initialized object def initialize(options) @conn = self.class.connect(options) end def self.open(options, &block) if block_given? begin conn = self.new(options) return yield(conn) ensure conn&.close end else self.new(options) end end def host() raise end def port() raise end def database() raise end def user() raise end def password() raise end # Escapes s as a SQL string value def escape(s) raise end def execute(sql) raise end def select(sql, &block) raise end def close() raise end def closed?() raise end private def self.connect(options) raise end end class Result def initialize(result) @result = result end def size() raise end # Returns the value of the first field of the first record in the result # set def value() each_tuple.first.first end # Returns a hash of the first record in the result set def record() each_hash.first end # Returns an array of the first record in the result set def tuple() each_tupe.first end def each_record() each_hash end def each_tuple() each_array end def each_hash() raise end def each_array() raise end def to_a() each_array end end class PostgresResult < Result def size() @result.ntuples end def each_hash(&block) if block_given? each_hash.each(&block) else @result.map { |row| row.map { |field, value| [field.to_sym, value] }.to_h } end end def each_array(&block) if block_given? each_array.each(&block) else @result.each_row end end def to_a() @result.values end end class PostgresConnection < Connection def host() @conn.host end def port() @conn.port end def database() @conn.db end def user() @conn.user end def password() @conn.pass end def escape(s) @conn.escape_string(s) end def execute(sql) @conn.exec(sql) end def select(sql) PostgresResult.new(@conn.exec(sql)) end def close() @conn.finish end def closed?() @conn.finished? end private def self.connect(options) conn = PG::Connection.new(options) conn.type_map_for_results = PG::BasicTypeMapForResults.new conn conn end end end