-
Notifications
You must be signed in to change notification settings - Fork 88
/
db_mock.cr
95 lines (75 loc) · 1.96 KB
/
db_mock.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class FakeStatement < DB::Statement
protected def perform_query(args : Enumerable) : DB::ResultSet
FieldEmitter.new
end
protected def perform_exec(args : Enumerable) : DB::ExecResult
DB::ExecResult.new 0_i64, 0_i64
end
end
class FakeContext
include DB::ConnectionContext
def uri : URI
URI.new ""
end
def prepared_statements? : Bool
false
end
def discard(connection); end
def release(connection); end
end
class FakeConnection < DB::Connection
def initialize
@context = FakeContext.new
@prepared_statements = false
end
def build_unprepared_statement(query) : FakeStatement
FakeStatement.new self, query
end
def build_prepared_statement(query) : FakeStatement
FakeStatement.new self, query
end
end
alias EmitterType = DB::Any | PG::Numeric | JSON::Any | Int16
# FieldEmitter emulates the subtle and uninformed way that
# DB::ResultSet emits data. To be used in testing interactions
# with raw data sets.
class FieldEmitter < DB::ResultSet
# 1. Override `#move_next` to move to the next row.
# 2. Override `#read` returning the next value in the row.
# 3. (Optional) Override `#read(t)` for some types `t` for which custom logic other than a simple cast is needed.
# 4. Override `#column_count`, `#column_name`.
@position = 0
@field_position = 0
@values = [] of EmitterType
def initialize
@statement = FakeStatement.new FakeConnection.new, ""
end
def _set_values(values : Array(EmitterType))
@values = [] of EmitterType
values.each do |v|
@values << v
end
end
def move_next : Bool
@position += 1
@field_position = 0
@position < @values.size
end
def read
if @position >= @values.size
raise "Overread"
end
@values[@position].tap do
@position += 1
end
end
def column_count : Int32
@values.size
end
def column_name(index : Int32) : String
"Column #{index}"
end
def next_column_index : Int32
@field_position
end
end