Class: Rooq::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/rooq/context.rb

Overview

Context is the main entry point for executing queries. It wraps a Configuration and provides methods for query execution.

Inspired by jOOQ's DSLContext.

Examples:

Using a single connection

connection = PG.connect(dbname: 'myapp')
ctx = Rooq::Context.using(connection)

books = Schema::BOOKS
result = ctx.fetch_all(
  Rooq::DSL.select(books.TITLE, books.AUTHOR)
           .from(books)
           .where(books.PUBLISHED_YEAR.gte(2020))
)
result.each { |row| puts row[:title] }  # Symbol keys

Using a connection pool

pool = ConnectionPool.new { PG.connect(dbname: 'myapp') }
ctx = Rooq::Context.using_pool(pool)

# Connection is automatically acquired and released per query
result = ctx.fetch_one(
  Rooq::DSL.select(books.ID).from(books).where(books.ID.eq(1))
)

Transactions

ctx.transaction do
  ctx.execute(Rooq::DSL.insert_into(books).columns(books.TITLE).values("New Book"))
  ctx.execute(Rooq::DSL.update(books).set(books.TITLE, "Updated").where(books.ID.eq(1)))
end

See Also:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ Context

Create a context with the given configuration.

Parameters:



41
42
43
# File 'lib/rooq/context.rb', line 41

def initialize(configuration)
  @configuration = configuration
end

Instance Attribute Details

#configurationObject (readonly)

Returns the value of attribute configuration.



37
38
39
# File 'lib/rooq/context.rb', line 37

def configuration
  @configuration
end

Class Method Details

.using(connection, dialect: nil) ⇒ Context

Create a context from a single connection.

Parameters:

  • connection (Object)

    a database connection

  • dialect (Dialect::Base) (defaults to: nil)

    the SQL dialect (optional)

Returns:



49
50
51
# File 'lib/rooq/context.rb', line 49

def self.using(connection, dialect: nil)
  new(Configuration.from_connection(connection, dialect: dialect))
end

.using_pool(pool, dialect: nil) ⇒ Context

Create a context from a connection pool.

Parameters:

Returns:



57
58
59
# File 'lib/rooq/context.rb', line 57

def self.using_pool(pool, dialect: nil)
  new(Configuration.from_pool(pool, dialect: dialect))
end

Instance Method Details

#execute(query) ⇒ Result

Execute a query and return a Result object.

Parameters:

Returns:

  • (Result)

    the result with symbol keys and type coercion



64
65
66
67
68
69
70
71
72
73
# File 'lib/rooq/context.rb', line 64

def execute(query)
  rendered = render_query(query)
  converted_params = parameter_converter.convert_all(rendered.params)

  raw_result = @configuration.connection_provider.with_connection do |connection|
    connection.exec_params(rendered.sql, converted_params)
  end

  Result.new(raw_result)
end

#fetch_all(query) ⇒ Array<Hash>

Execute a query and return all rows as an array with symbol keys.

Parameters:

Returns:

  • (Array<Hash>)

    the rows with symbol keys



88
89
90
# File 'lib/rooq/context.rb', line 88

def fetch_all(query)
  execute(query).to_a
end

#fetch_one(query) ⇒ Hash?

Execute a query and return a single row with symbol keys.

Parameters:

Returns:

  • (Hash, nil)

    the first row or nil if no results



78
79
80
81
82
83
# File 'lib/rooq/context.rb', line 78

def fetch_one(query)
  result = execute(query)
  return nil if result.empty?

  result.first
end

#transaction { ... } ⇒ Object

Execute a block within a transaction. Commits on success, rolls back on error.

Yields:

  • the block to execute within the transaction

Returns:

  • (Object)

    the result of the block



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rooq/context.rb', line 96

def transaction(&block)
  @configuration.connection_provider.with_connection do |connection|
    if connection.respond_to?(:transaction)
      connection.transaction(&block)
    else
      begin
        connection.exec("BEGIN")
        result = yield
        connection.exec("COMMIT")
        result
      rescue StandardError
        connection.exec("ROLLBACK")
        raise
      end
    end
  end
end