Class: Mkxms::Mssql::QueryCursor

Inherits:
Object
  • Object
show all
Defined in:
lib/mkxms/mssql/query_cursor.rb

Defined Under Namespace

Classes: ExpectedRowTest

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(select_statement, variables, options = {}) ⇒ QueryCursor

Returns a new instance of QueryCursor.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/mkxms/mssql/query_cursor.rb', line 5

def initialize(select_statement, variables, options = {})
  @select_statement = select_statement
  @select_statement += ';' unless @select_statement =~ /;\s*\Z/
  @cursor = options[:cursor_name] || self.class.generated_cursor_name
  @out = options[:output_to] || $stdout
  @indented = @out.respond_to?(:indented) ? @out.method(:indented) : ->(&blk) {blk.call}
  @global = options[:global]
  @indent = options[:indent] || '  '
  
  @variable_decl = variables.gsub(/\s+/, ' ')
  @variable_names = variables.split(',').map do |vardecl|
    vardecl.chomp.split(nil, 2)[0]
  end
end

Instance Attribute Details

#cursor_nameObject (readonly)

Returns the value of attribute cursor_name.



20
21
22
# File 'lib/mkxms/mssql/query_cursor.rb', line 20

def cursor_name
  @cursor_name
end

Class Method Details

.generated_cursor_nameObject



114
115
116
117
# File 'lib/mkxms/mssql/query_cursor.rb', line 114

def self.generated_cursor_name
  @gensym_number ||= 0
  "gensym_cursor_#{@gensym_number += 1}"
end

Instance Method Details

#cursor_scope(explicit_local = true) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/mkxms/mssql/query_cursor.rb', line 87

def cursor_scope(explicit_local = true)
  case
  when @global then 'GLOBAL'
  when explicit_local then 'LOCAL'
  else ''
  end
end

#each_rowObject



22
23
24
25
26
27
28
29
30
# File 'lib/mkxms/mssql/query_cursor.rb', line 22

def each_row
  set_up_loop
  fetch_next
  @out.puts "WHILE @@FETCH_STATUS = 0"
  @out.puts "BEGIN"
  yield
  fetch_next(@indent)
  @out.puts "END;"
end

#expectation_failure_action(value) ⇒ Object



80
81
82
83
84
85
# File 'lib/mkxms/mssql/query_cursor.rb', line 80

def expectation_failure_action(value)
  case value
  when Proc then value
  when String then proc {@out.puts(@indent + value)}
  end
end

#expectations(opts = {}) {|ExpectedRowTest.new(test_entry_proc)| ... } ⇒ Object

Yields:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/mkxms/mssql/query_cursor.rb', line 42

def expectations(opts = {})
  extra_action = expectation_failure_action(opts[:on_extra])
  test_entry_proc = if missing_action = expectation_failure_action(opts[:on_missing])
    proc {|&blk| test_entry(on_missing: missing_action, &blk)}
  else
    method(:test_entry)
  end
  
  set_up_loop
  
  yield ExpectedRowTest.new(test_entry_proc)
  
  if extra_action
    fetch_next
    @out.puts "IF @@FETCH_STATUS = 0"
    @out.puts "BEGIN"
    indented {extra_action.call}
    @out.puts "END;"
  end
  
  tear_down_loop
end

#fetch_next(indent = '') ⇒ Object



102
103
104
# File 'lib/mkxms/mssql/query_cursor.rb', line 102

def fetch_next(indent = '')
  @out.puts(indent + "FETCH NEXT FROM #@cursor INTO #{@variable_names.join(', ')};")
end

#indented(&blk) ⇒ Object



110
111
112
# File 'lib/mkxms/mssql/query_cursor.rb', line 110

def indented(&blk)
  @indented.call(&blk)
end

#set_up_loopObject



95
96
97
98
99
100
# File 'lib/mkxms/mssql/query_cursor.rb', line 95

def set_up_loop
  @out.puts "DECLARE #@variable_decl;"
  @out.puts "DECLARE #@cursor CURSOR #{cursor_scope} FOR"
  @out.puts @select_statement
  @out.puts "OPEN #@cursor;"
end

#tear_down_loopObject



106
107
108
# File 'lib/mkxms/mssql/query_cursor.rb', line 106

def tear_down_loop
  @out.puts "CLOSE #{cursor_scope(false)} #@cursor; DEALLOCATE #{cursor_scope(false)} #@cursor;"
end

#test_entry(opts = {}) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/mkxms/mssql/query_cursor.rb', line 65

def test_entry(opts = {})
  opts = {} unless opts.kind_of? Hash
  missing_action = expectation_failure_action(opts[:on_missing]) || proc {}
  @out.puts
  fetch_next
  @out.puts "IF @@FETCH_STATUS <> 0"
  @out.puts "BEGIN"
  indented {missing_action.call}
  @out.puts "END ELSE BEGIN"
  indented {
    yield
  }
  @out.puts "END;"
end