gloo-db 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/gloo-db.rb +23 -0
- data/lib/query.rb +265 -0
- data/lib/query_result.rb +152 -0
- data/lib/table.rb +263 -0
- metadata +48 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8103ee6d8fd76866fec307a477c10bc663ab8a4ec22630d7c6a7ac84a504ffc7
|
|
4
|
+
data.tar.gz: de20b8674829888238469725e8243ab78427fb1019ae6769546c38214bf3a094
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c358924ba730e80f0ee3102db7edae06e4efd9e20a67029fd2687dfe170583ee3229857c90b897d447cf276f6a5d45b1f5b1e1c756058be855968ef9708dd90f
|
|
7
|
+
data.tar.gz: 62bed0c0675a00d55f28e830795a65f47653534002b9a1cfe87d456b395e9ecdd0912b0c8d20d76f939d523036f2bdcb98ce3cf99a05ab3133e6ffee110a7599
|
data/lib/gloo-db.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Shim to allow `require 'gloo-mysql'`
|
|
3
|
+
#
|
|
4
|
+
# This file is loaded when someone does `require 'gloo-mysql'`
|
|
5
|
+
#
|
|
6
|
+
require 'query'
|
|
7
|
+
require 'query_result'
|
|
8
|
+
require 'table'
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Registers the extension.
|
|
12
|
+
#
|
|
13
|
+
class DbInit < Gloo::Plugin::Base
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Register verbs and objects.
|
|
17
|
+
#
|
|
18
|
+
def register( callback )
|
|
19
|
+
callback.register_obj( Query )
|
|
20
|
+
callback.register_obj( Table )
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
data/lib/query.rb
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# A SQL database query.
|
|
5
|
+
# Relies on a database connection object.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
class Query < Gloo::Core::Obj
|
|
9
|
+
|
|
10
|
+
KEYWORD = 'query'.freeze
|
|
11
|
+
KEYWORD_SHORT = 'sql'.freeze
|
|
12
|
+
|
|
13
|
+
DB = 'database'.freeze
|
|
14
|
+
SQL = 'sql'.freeze
|
|
15
|
+
RESULT = 'result'.freeze
|
|
16
|
+
PARAMS = 'params'.freeze
|
|
17
|
+
SIMPLE_LIST = 'simple_list'.freeze
|
|
18
|
+
|
|
19
|
+
DB_MISSING_ERR = 'The database connection is missing!'.freeze
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# The name of the object type.
|
|
23
|
+
#
|
|
24
|
+
def self.typename
|
|
25
|
+
return KEYWORD
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
# The short name of the object type.
|
|
30
|
+
#
|
|
31
|
+
def self.short_typename
|
|
32
|
+
return KEYWORD_SHORT
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Get the result container if it exists.
|
|
37
|
+
#
|
|
38
|
+
def get_result_can
|
|
39
|
+
result_can = find_child RESULT
|
|
40
|
+
result_can = Gloo::Objs::Alias.resolve_alias( @engine, result_can )
|
|
41
|
+
return result_can
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# ---------------------------------------------------------------------
|
|
45
|
+
# Children
|
|
46
|
+
# ---------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
#
|
|
49
|
+
# Does this object have children to add when an object
|
|
50
|
+
# is created in interactive mode?
|
|
51
|
+
# This does not apply during obj load, etc.
|
|
52
|
+
#
|
|
53
|
+
def add_children_on_create?
|
|
54
|
+
return true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Add children to this object.
|
|
59
|
+
# This is used by containers to add children needed
|
|
60
|
+
# for default configurations.
|
|
61
|
+
#
|
|
62
|
+
def add_default_children
|
|
63
|
+
fac = @engine.factory
|
|
64
|
+
fac.create_alias DB, nil, self
|
|
65
|
+
fac.create_string SQL, nil, self
|
|
66
|
+
fac.create_can RESULT, self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# ---------------------------------------------------------------------
|
|
70
|
+
# Messages
|
|
71
|
+
# ---------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Get a list of message names that this object receives.
|
|
75
|
+
#
|
|
76
|
+
def self.messages
|
|
77
|
+
return super + [ 'run' ]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
# Run the query and process the results.
|
|
82
|
+
#
|
|
83
|
+
def msg_run
|
|
84
|
+
db = db_obj
|
|
85
|
+
return unless db
|
|
86
|
+
|
|
87
|
+
begin
|
|
88
|
+
clear_results
|
|
89
|
+
|
|
90
|
+
log_query sql_value, param_array
|
|
91
|
+
result = db.query( sql_value, param_array )
|
|
92
|
+
process_result( result, db )
|
|
93
|
+
rescue => e
|
|
94
|
+
@engine.log_exception e
|
|
95
|
+
return
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Run the query and return the results.
|
|
101
|
+
#
|
|
102
|
+
def run_query
|
|
103
|
+
db = db_obj
|
|
104
|
+
return unless db
|
|
105
|
+
|
|
106
|
+
begin
|
|
107
|
+
log_query sql_value, param_array
|
|
108
|
+
|
|
109
|
+
db_start = ::Time.now
|
|
110
|
+
result = db.query( sql_value, param_array )
|
|
111
|
+
db_done = ::Time.now
|
|
112
|
+
elapsed = ( ( db_done - db_start ) * 1000.0 ).round(2)
|
|
113
|
+
|
|
114
|
+
app = @engine.running_app
|
|
115
|
+
app.add_db_time elapsed if app
|
|
116
|
+
return result
|
|
117
|
+
rescue => e
|
|
118
|
+
@engine.log_exception e
|
|
119
|
+
return
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
#
|
|
124
|
+
# Write the query to the log.
|
|
125
|
+
#
|
|
126
|
+
def log_query sql, params
|
|
127
|
+
@engine.log.info "SQL PARAMS: #{params}" if params
|
|
128
|
+
@engine.log.info "SQL: #{sql}"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# ---------------------------------------------------------------------
|
|
133
|
+
# Output as simple list
|
|
134
|
+
# ---------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
#
|
|
137
|
+
# Should the output be put in a simple list?
|
|
138
|
+
#
|
|
139
|
+
def simple_list?
|
|
140
|
+
o = find_child SIMPLE_LIST
|
|
141
|
+
return false unless o
|
|
142
|
+
|
|
143
|
+
return o.value
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# ---------------------------------------------------------------------
|
|
148
|
+
# Private functions
|
|
149
|
+
# ---------------------------------------------------------------------
|
|
150
|
+
|
|
151
|
+
private
|
|
152
|
+
|
|
153
|
+
#
|
|
154
|
+
# Get the database connection.
|
|
155
|
+
#
|
|
156
|
+
def db_obj
|
|
157
|
+
o = find_child DB
|
|
158
|
+
|
|
159
|
+
unless o
|
|
160
|
+
@engine.err DB_MISSING_ERR
|
|
161
|
+
return nil
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
return Gloo::Objs::Alias.resolve_alias( @engine, o )
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
#
|
|
168
|
+
# Get the SQL from the child object.
|
|
169
|
+
# Returns nil if there is none.
|
|
170
|
+
#
|
|
171
|
+
def sql_value
|
|
172
|
+
o = find_child SQL
|
|
173
|
+
return nil unless o
|
|
174
|
+
|
|
175
|
+
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
|
176
|
+
return o.value
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
#
|
|
180
|
+
# Do something with the result of the SQL Query call.
|
|
181
|
+
# If there's a result container, we'll create objects in it.
|
|
182
|
+
# If not, we'll just show the output in the console.
|
|
183
|
+
#
|
|
184
|
+
def process_result( result, db )
|
|
185
|
+
return if result.nil?
|
|
186
|
+
|
|
187
|
+
query_result = db.get_query_result( result )
|
|
188
|
+
return unless query_result
|
|
189
|
+
return unless query_result.has_data_to_show?
|
|
190
|
+
|
|
191
|
+
result_can = get_result_can
|
|
192
|
+
|
|
193
|
+
if result_can
|
|
194
|
+
if simple_list?
|
|
195
|
+
query_result.update_result_container_simple result_can
|
|
196
|
+
else
|
|
197
|
+
query_result.update_result_container result_can
|
|
198
|
+
end
|
|
199
|
+
else
|
|
200
|
+
query_result.show
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
#
|
|
205
|
+
# Get the array of parameters.
|
|
206
|
+
# If there is no PARAM container of if it is empty,
|
|
207
|
+
# we'll return a nil value.
|
|
208
|
+
#
|
|
209
|
+
def param_array
|
|
210
|
+
o = find_child PARAMS
|
|
211
|
+
return nil unless o
|
|
212
|
+
|
|
213
|
+
return nil if o.child_count.zero?
|
|
214
|
+
|
|
215
|
+
params = []
|
|
216
|
+
o.children.each do |p|
|
|
217
|
+
p = Gloo::Objs::Alias.resolve_alias( @engine, p )
|
|
218
|
+
params << p.sql_value
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
return params
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
#
|
|
225
|
+
# Clear out results container.
|
|
226
|
+
# Prevents data from the last use being used in this
|
|
227
|
+
# one if no data was found.
|
|
228
|
+
#
|
|
229
|
+
def clear_results
|
|
230
|
+
result_can = get_result_can
|
|
231
|
+
return unless result_can
|
|
232
|
+
return unless result_can.child_count.positive?
|
|
233
|
+
|
|
234
|
+
if result_is_values?
|
|
235
|
+
clear_values
|
|
236
|
+
else
|
|
237
|
+
get_result_can.delete_children
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
#
|
|
242
|
+
# Is the result container a list of values?
|
|
243
|
+
# If not it is a list of rows.
|
|
244
|
+
#
|
|
245
|
+
def result_is_values?
|
|
246
|
+
first_child = get_result_can.children.first
|
|
247
|
+
|
|
248
|
+
if first_child && first_child&.is_container?
|
|
249
|
+
return false
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
return true
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
#
|
|
256
|
+
# Clear out the values in the results container.
|
|
257
|
+
#
|
|
258
|
+
def clear_values
|
|
259
|
+
get_result_can.children.each do |c|
|
|
260
|
+
c = Gloo::Objs::Alias.resolve_alias( @engine, c )
|
|
261
|
+
c.value = nil
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
end
|
data/lib/query_result.rb
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2022 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# The result of a SQL database query.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
class QueryResult
|
|
8
|
+
|
|
9
|
+
DB = 'database'.freeze
|
|
10
|
+
SQL = 'sql'.freeze
|
|
11
|
+
RESULT = 'result'.freeze
|
|
12
|
+
PARAMS = 'params'.freeze
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# ---------------------------------------------------------------------
|
|
16
|
+
# Set up the Result
|
|
17
|
+
# ---------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Create the Result object
|
|
21
|
+
def initialize( heads, data, engine=nil )
|
|
22
|
+
@heads = heads
|
|
23
|
+
@data = data
|
|
24
|
+
@engine = engine
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------
|
|
29
|
+
# Helper Functions
|
|
30
|
+
# ---------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Does the data contain a single row?
|
|
34
|
+
# OR, if the result is empty, return false.
|
|
35
|
+
#
|
|
36
|
+
def single_row_result?
|
|
37
|
+
if @result_can && ( @result_can.child_count == 0 )
|
|
38
|
+
return false
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
return @data.count == 1
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# Does this query result have data to show?
|
|
46
|
+
#
|
|
47
|
+
def has_data_to_show?
|
|
48
|
+
return false unless @heads
|
|
49
|
+
return false unless @data
|
|
50
|
+
return false if @heads.count == 0
|
|
51
|
+
return false if @data.count == 0
|
|
52
|
+
|
|
53
|
+
return true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# ---------------------------------------------------------------------
|
|
58
|
+
# Show Results
|
|
59
|
+
# ---------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Show the result of the query
|
|
63
|
+
#
|
|
64
|
+
def show
|
|
65
|
+
single_row_result? ? show_single_row : show_rows
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# Show a single row in a vertical, form style view.
|
|
70
|
+
#
|
|
71
|
+
def show_single_row
|
|
72
|
+
arr = []
|
|
73
|
+
row = @data[0]
|
|
74
|
+
@heads.each_with_index do |h, i|
|
|
75
|
+
arr << [ h, row[i] ]
|
|
76
|
+
end
|
|
77
|
+
@engine.platform.table.show [ 'Field', 'Value' ], arr
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
# Show multiple rows in a table view.
|
|
82
|
+
#
|
|
83
|
+
def show_rows
|
|
84
|
+
@engine.platform.table.show @heads, @data
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# ---------------------------------------------------------------------
|
|
88
|
+
# Update results in object(s)
|
|
89
|
+
# ---------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
#
|
|
92
|
+
# Update the result container with the data from the query.
|
|
93
|
+
#
|
|
94
|
+
def update_result_container( in_can )
|
|
95
|
+
@result_can = in_can
|
|
96
|
+
single_row_result? ? update_single_row : update_rows
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Update the result container with the data from the query.
|
|
101
|
+
#
|
|
102
|
+
def update_result_container_simple( in_can )
|
|
103
|
+
@result_can = in_can
|
|
104
|
+
single_row_result? ? update_single_row : update_rows_simple
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
# The result has a single row.
|
|
109
|
+
# Map values from the result set to objects that are present.
|
|
110
|
+
#
|
|
111
|
+
def update_single_row
|
|
112
|
+
row = @data[0]
|
|
113
|
+
@heads.each_with_index do |h, i|
|
|
114
|
+
child = @result_can.find_child h
|
|
115
|
+
child = Gloo::Objs::Alias.resolve_alias( @engine, child )
|
|
116
|
+
child.set_value row[i] if child
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
#
|
|
121
|
+
# Put all rows in the result object.
|
|
122
|
+
#
|
|
123
|
+
def update_rows
|
|
124
|
+
@data.each_with_index do |row, i|
|
|
125
|
+
can = @result_can.find_add_child( i.to_s, 'can' )
|
|
126
|
+
row.each_with_index do |v, i|
|
|
127
|
+
o = can.find_add_child( @heads[i], 'untyped' )
|
|
128
|
+
o.set_value v
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
# Put all rows in the result object.
|
|
135
|
+
#
|
|
136
|
+
def update_rows_simple
|
|
137
|
+
@data.each do |row|
|
|
138
|
+
row.each do |val|
|
|
139
|
+
o = @result_can.find_add_child( val, 'untyped' )
|
|
140
|
+
o.set_value val
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# ---------------------------------------------------------------------
|
|
147
|
+
# Private functions
|
|
148
|
+
# ---------------------------------------------------------------------
|
|
149
|
+
|
|
150
|
+
private
|
|
151
|
+
|
|
152
|
+
end
|
data/lib/table.rb
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# A data table.
|
|
5
|
+
# The table container headers and data.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
class Table < Gloo::Core::Obj
|
|
9
|
+
|
|
10
|
+
KEYWORD = 'table'.freeze
|
|
11
|
+
KEYWORD_SHORT = 'tbl'.freeze
|
|
12
|
+
HEADERS = 'headers'.freeze
|
|
13
|
+
DATA = 'data'.freeze
|
|
14
|
+
CELLS = 'cells'.freeze
|
|
15
|
+
STYLES = 'styles'.freeze
|
|
16
|
+
ALWAYS_ROWS = 'always_rows'.freeze
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# The name of the object type.
|
|
20
|
+
#
|
|
21
|
+
def self.typename
|
|
22
|
+
return KEYWORD
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# The short name of the object type.
|
|
27
|
+
#
|
|
28
|
+
def self.short_typename
|
|
29
|
+
return KEYWORD_SHORT
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Get the list of headers.
|
|
34
|
+
# Returns nil if there is none.
|
|
35
|
+
#
|
|
36
|
+
def headers
|
|
37
|
+
o = find_child HEADERS
|
|
38
|
+
return [] unless o
|
|
39
|
+
|
|
40
|
+
return o.children.map( &:value )
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#
|
|
44
|
+
# Always show rows, even if only 1 row is found.
|
|
45
|
+
#
|
|
46
|
+
def always_rows
|
|
47
|
+
o = find_child ALWAYS_ROWS
|
|
48
|
+
|
|
49
|
+
return false unless o
|
|
50
|
+
return o.value
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Get the list of column names.
|
|
55
|
+
# Returns nil if there is none.
|
|
56
|
+
#
|
|
57
|
+
def columns
|
|
58
|
+
o = find_child HEADERS
|
|
59
|
+
return [] unless o
|
|
60
|
+
|
|
61
|
+
return o.children.map( &:name )
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Get the list of data elements.
|
|
66
|
+
#
|
|
67
|
+
def data
|
|
68
|
+
o = find_child DATA
|
|
69
|
+
return [] unless o
|
|
70
|
+
|
|
71
|
+
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
|
72
|
+
return [] unless o
|
|
73
|
+
|
|
74
|
+
if o.is_a? Query
|
|
75
|
+
@engine.log.debug "Table getting data from query."
|
|
76
|
+
begin
|
|
77
|
+
result = o.run_query
|
|
78
|
+
return result
|
|
79
|
+
rescue => e
|
|
80
|
+
@engine.log_exception e
|
|
81
|
+
return nil
|
|
82
|
+
end
|
|
83
|
+
else
|
|
84
|
+
cols = self.columns
|
|
85
|
+
|
|
86
|
+
if o.children&.first.children.empty?
|
|
87
|
+
# It is a simgle row table.
|
|
88
|
+
rows = [ cols.map { |h| o.find_child( h )&.value } ]
|
|
89
|
+
else
|
|
90
|
+
rows = o.children.map do |e|
|
|
91
|
+
cols.map { |h| e.find_child( h )&.value }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
return [ cols, rows ]
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Get the styles for the table, if any.
|
|
101
|
+
#
|
|
102
|
+
def styles
|
|
103
|
+
style_h = {}
|
|
104
|
+
o = find_child STYLES
|
|
105
|
+
return style_h unless o
|
|
106
|
+
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
|
107
|
+
|
|
108
|
+
o.children.each do |c|
|
|
109
|
+
style_h[ c.name ] = c.value
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
return style_h
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# Get cell renderer hash keyed by column name.
|
|
117
|
+
#
|
|
118
|
+
def cell_renderers
|
|
119
|
+
h = {}
|
|
120
|
+
o = find_child CELLS
|
|
121
|
+
return h unless o
|
|
122
|
+
|
|
123
|
+
o.children.each do |c|
|
|
124
|
+
h[ c.name ] = c.value
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
return h
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# ---------------------------------------------------------------------
|
|
132
|
+
# Children
|
|
133
|
+
# ---------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# Does this object have children to add when an object
|
|
137
|
+
# is created in interactive mode?
|
|
138
|
+
# This does not apply during obj load, etc.
|
|
139
|
+
#
|
|
140
|
+
def add_children_on_create?
|
|
141
|
+
return true
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
#
|
|
145
|
+
# Add children to this object.
|
|
146
|
+
# This is used by containers to add children needed
|
|
147
|
+
# for default configurations.
|
|
148
|
+
#
|
|
149
|
+
def add_default_children
|
|
150
|
+
fac = @engine.factory
|
|
151
|
+
fac.create_can HEADERS, self
|
|
152
|
+
fac.create_can DATA, self
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# ---------------------------------------------------------------------
|
|
157
|
+
# Messages
|
|
158
|
+
# ---------------------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
#
|
|
161
|
+
# Get a list of message names that this object receives.
|
|
162
|
+
#
|
|
163
|
+
def self.messages
|
|
164
|
+
return super + %w[show render]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
#
|
|
168
|
+
# Show the table in the CLI.
|
|
169
|
+
#
|
|
170
|
+
def msg_show
|
|
171
|
+
title = self.value
|
|
172
|
+
@engine.platform.table.show headers, data[1], title
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def msg_render
|
|
176
|
+
return render
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# ---------------------------------------------------------------------
|
|
181
|
+
# Render
|
|
182
|
+
# ---------------------------------------------------------------------
|
|
183
|
+
|
|
184
|
+
#
|
|
185
|
+
# Render the table.
|
|
186
|
+
# The render_ƒ is 'render_html', 'render_text', 'render_json', etc.
|
|
187
|
+
#
|
|
188
|
+
def render render_ƒ
|
|
189
|
+
begin
|
|
190
|
+
result = self.data
|
|
191
|
+
head = self.headers
|
|
192
|
+
head = result[0] if head.empty?
|
|
193
|
+
rows = result[1]
|
|
194
|
+
|
|
195
|
+
columns = build_columns result[0]
|
|
196
|
+
|
|
197
|
+
params = {
|
|
198
|
+
head: head,
|
|
199
|
+
cols: result[0],
|
|
200
|
+
columns: columns,
|
|
201
|
+
rows: rows,
|
|
202
|
+
styles: self.styles,
|
|
203
|
+
cell_renderers: self.cell_renderers
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if self.always_rows
|
|
207
|
+
params[ :always_rows ] = true
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
helper = Gloo::WebSvr::TableRenderer.new( @engine )
|
|
211
|
+
return helper.data_to_table params
|
|
212
|
+
rescue => e
|
|
213
|
+
@engine.log_exception e
|
|
214
|
+
return nil
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
#
|
|
219
|
+
# Build the column list based on the result data and
|
|
220
|
+
# the headers defined in the table object.
|
|
221
|
+
#
|
|
222
|
+
def build_columns result_data
|
|
223
|
+
head_children = find_child HEADERS
|
|
224
|
+
cell_renderers = find_child CELLS
|
|
225
|
+
|
|
226
|
+
columns = []
|
|
227
|
+
return columns unless result_data
|
|
228
|
+
|
|
229
|
+
result_data.each_with_index do |c,index|
|
|
230
|
+
visible = true
|
|
231
|
+
name = c
|
|
232
|
+
title = c
|
|
233
|
+
display_index = index
|
|
234
|
+
|
|
235
|
+
if head_children
|
|
236
|
+
child = head_children.find_child c
|
|
237
|
+
if child
|
|
238
|
+
title = child.value
|
|
239
|
+
display_index = head_children.child_index( c )
|
|
240
|
+
else
|
|
241
|
+
visible = false
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
cell_renderer = nil
|
|
246
|
+
if cell_renderers
|
|
247
|
+
this_cr = cell_renderers.find_child( c )
|
|
248
|
+
cell_renderer = this_cr.value if this_cr
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
columns << {
|
|
252
|
+
name: name,
|
|
253
|
+
title: title,
|
|
254
|
+
visible: visible,
|
|
255
|
+
data_index: index,
|
|
256
|
+
display_index: display_index,
|
|
257
|
+
cell_renderer: cell_renderer
|
|
258
|
+
}
|
|
259
|
+
end
|
|
260
|
+
return columns.sort_by { |hsh| hsh[ :display_index ] }
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: gloo-db
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: '1.0'
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Eric Crane
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-02-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Adds database support to Gloo.
|
|
14
|
+
email:
|
|
15
|
+
- eric.crane@mac.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- lib/gloo-db.rb
|
|
21
|
+
- lib/query.rb
|
|
22
|
+
- lib/query_result.rb
|
|
23
|
+
- lib/table.rb
|
|
24
|
+
homepage: https://gloo.ecrane.us/
|
|
25
|
+
licenses:
|
|
26
|
+
- MIT
|
|
27
|
+
metadata:
|
|
28
|
+
gloo.type: core-library
|
|
29
|
+
post_install_message:
|
|
30
|
+
rdoc_options: []
|
|
31
|
+
require_paths:
|
|
32
|
+
- lib
|
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
34
|
+
requirements:
|
|
35
|
+
- - ">="
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0'
|
|
43
|
+
requirements: []
|
|
44
|
+
rubygems_version: 3.5.16
|
|
45
|
+
signing_key:
|
|
46
|
+
specification_version: 4
|
|
47
|
+
summary: Gloo core library. Database support.
|
|
48
|
+
test_files: []
|