Class: Sequel::Dataset
- Inherits:
-
Object
- Object
- Sequel::Dataset
- Defined in:
- lib/sequel_opal_runtime_patches.rb,
lib/sequel_opal_async_dataset_patches.rb
Overview
String-buffer overrides: Sequel’s Dataset#sql_string_origin and literal_append allocate plain String instances which Opal treats as immutable — the ‘<<` accumulator pattern raises NotImplementedError. Replace the allocation sites with HomuraSqlBuffer, which implements the Sequel-expected subset of String (from lib/sequel_opal_patches.rb).
Direct Known Subclasses
Instance Method Summary collapse
-
#__homura_orig_literal_append ⇒ Object
upstream literal_append Symbol branch: l = String.new literal_symbol_append(l, v) db.literal_symbol_set(v, l) homura: use Buffer for the append accumulator; cache the rendered String form on the db so subsequent calls hit the cache without re-creating a Buffer.
-
#_all(block) ⇒ Object
upstream: a = []; yield a; post_load(a); a.each(&block) if block; a homura: yield(a) returns a Promise when the caller block crosses the D1 adapter’s async boundary (Dataset#all’s block is async-compiled).
-
#each ⇒ Object
upstream each: if rp = row_proc; fetch_rows(select_sql){|r| yield rp.call®} else fetch_rows(select_sql){|r| yield r} end; self homura: fetch_rows is async (D1 adapter awaits the Promise chain).
- #literal_append(sql, v) ⇒ Object
-
#single_value ⇒ Object
upstream: single_value_ds.each{|r| r.each{|_, v| return v}}; nil homura: capture first value using sentinel flag.
- #sql_string_origin ⇒ Object
-
#with_sql_each(sql) ⇒ Object
upstream: with_sql_each(sql){|r| yield r}; self (sync, but fetch_rows returns a Promise under the D1 adapter, so the block body doesn’t run before the caller’s sync flow resumes — the Promise is dropped).
-
#with_sql_first(sql) ⇒ Object
upstream: with_sql_each(sql){|r| return r}; nil homura: capture first row without ‘return`; callers always clone with limit(1) so the no-break form is equivalent.
-
#with_sql_single_value(sql) ⇒ Object
upstream: if r = with_sql_first(sql); r.each{|_, v| return v}; end homura: same capture-first-value pattern via sentinel.
Instance Method Details
#__homura_orig_literal_append ⇒ Object
upstream literal_append Symbol branch:
l = String.new
literal_symbol_append(l, v)
db.literal_symbol_set(v, l)
homura: use Buffer for the append accumulator; cache the rendered String form on the db so subsequent calls hit the cache without re-creating a Buffer.
63 |
# File 'lib/sequel_opal_runtime_patches.rb', line 63 alias_method :__homura_orig_literal_append, :literal_append |
#_all(block) ⇒ Object
upstream: a = []; yield a; post_load(a); a.each(&block) if block; a homura: yield(a) returns a Promise when the caller block crosses the D1 adapter’s async boundary (Dataset#all’s block is async-compiled). Await so ‘a` is populated before post_load.
51 52 53 54 55 56 57 |
# File 'lib/sequel_opal_async_dataset_patches.rb', line 51 def _all(block) a = [] yield(a).__await__ post_load(a) a.each(&block) if block a end |
#each ⇒ Object
upstream each:
if rp = row_proc; fetch_rows(select_sql){|r| yield rp.call(r)}
else fetch_rows(select_sql){|r| yield r}
end; self
homura: fetch_rows is async (D1 adapter awaits the Promise chain). If we leave each sync, the block passed to fetch_rows never runs before each returns. Await fetch_rows to let the inner block fire first.
38 39 40 41 42 43 44 45 |
# File 'lib/sequel_opal_async_dataset_patches.rb', line 38 def each if rp = row_proc fetch_rows(select_sql){|r| yield rp.call(r)}.__await__ else fetch_rows(select_sql){|r| yield r}.__await__ end self end |
#literal_append(sql, v) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/sequel_opal_runtime_patches.rb', line 64 def literal_append(sql, v) if v.is_a?(Symbol) if skip_symbol_cache? literal_symbol_append(sql, v) else unless l = db.literal_symbol(v) l = sql_string_origin literal_symbol_append(l, v) db.literal_symbol_set(v, l.to_s) end sql << l end else __homura_orig_literal_append(sql, v) end end |
#single_value ⇒ Object
upstream: single_value_ds.each{|r| r.each{|_, v| return v}}; nil homura: capture first value using sentinel flag. Relies on each awaiting the D1 Promise chain.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/sequel_opal_async_dataset_patches.rb', line 91 def single_value value = nil found = false # each is async (patched in this file); must await. (single_value_ds.each do |r| next if found r.each do |_, v| next if found value = v found = true end end).__await__ found ? value : nil end |
#sql_string_origin ⇒ Object
52 53 54 |
# File 'lib/sequel_opal_runtime_patches.rb', line 52 def sql_string_origin ::HomuraSqlBuffer.new end |
#with_sql_each(sql) ⇒ Object
upstream: with_sql_each(sql){|r| yield r}; self (sync, but fetch_rows returns a Promise under the D1 adapter, so the block body doesn’t run before the caller’s sync flow resumes — the Promise is dropped). homura: reopen with ‘.__await__` so the async fetch_rows resolves before this method returns. Required for #first / #with_sql_first / #with_sql_single_value which expect the block to have fired.
65 66 67 68 69 70 71 72 |
# File 'lib/sequel_opal_async_dataset_patches.rb', line 65 def with_sql_each(sql) if rp = row_proc _with_sql_dataset.fetch_rows(sql){|r| yield rp.call(r)}.__await__ else _with_sql_dataset.fetch_rows(sql){|r| yield r}.__await__ end self end |
#with_sql_first(sql) ⇒ Object
upstream: with_sql_each(sql){|r| return r}; nil homura: capture first row without ‘return`; callers always clone with limit(1) so the no-break form is equivalent. Needs with_sql_each to actually await its fetch_rows (see above).
78 79 80 81 82 83 84 85 86 |
# File 'lib/sequel_opal_async_dataset_patches.rb', line 78 def with_sql_first(sql) result = nil # with_sql_each is async now (awaits fetch_rows internally); we must # await here so `result` is populated before returning. (with_sql_each(sql) do |r| result = r if result.nil? end).__await__ result end |
#with_sql_single_value(sql) ⇒ Object
upstream: if r = with_sql_first(sql); r.each{|_, v| return v}; end homura: same capture-first-value pattern via sentinel.
108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/sequel_opal_async_dataset_patches.rb', line 108 def with_sql_single_value(sql) if r = with_sql_first(sql) value = nil captured = false r.each do |_, v| next if captured value = v captured = true end value end end |