gloo 3.4.1 → 3.6.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/lib/VERSION +1 -1
  4. data/lib/VERSION_NOTES +15 -0
  5. data/lib/gloo/app/args.rb +2 -2
  6. data/lib/gloo/app/engine.rb +21 -2
  7. data/lib/gloo/app/info.rb +0 -2
  8. data/lib/gloo/convert/converter.rb +1 -2
  9. data/lib/gloo/convert/string_to_integer.rb +2 -0
  10. data/lib/gloo/core/dictionary.rb +1 -1
  11. data/lib/gloo/core/event_manager.rb +19 -0
  12. data/lib/gloo/core/factory.rb +2 -2
  13. data/lib/gloo/core/gloo_system.rb +1 -1
  14. data/lib/gloo/core/here.rb +1 -1
  15. data/lib/gloo/core/obj.rb +61 -5
  16. data/lib/gloo/core/parser.rb +1 -1
  17. data/lib/gloo/core/pn.rb +1 -1
  18. data/lib/gloo/exec/dispatch.rb +19 -0
  19. data/lib/gloo/exec/runner.rb +1 -1
  20. data/lib/gloo/objs/basic/integer.rb +10 -1
  21. data/lib/gloo/objs/ctrl/each.rb +17 -184
  22. data/lib/gloo/objs/ctrl/each_child.rb +68 -0
  23. data/lib/gloo/objs/ctrl/each_file.rb +83 -0
  24. data/lib/gloo/objs/ctrl/each_line.rb +67 -0
  25. data/lib/gloo/objs/ctrl/each_repo.rb +84 -0
  26. data/lib/gloo/objs/ctrl/each_word.rb +67 -0
  27. data/lib/gloo/objs/data/mysql.rb +2 -2
  28. data/lib/gloo/objs/data/pg.rb +1 -1
  29. data/lib/gloo/objs/data/query.rb +54 -5
  30. data/lib/gloo/objs/data/query_result.rb +6 -1
  31. data/lib/gloo/objs/data/sqlite.rb +1 -1
  32. data/lib/gloo/objs/data/table.rb +2 -2
  33. data/lib/gloo/objs/ror/eval.rb +1 -1
  34. data/lib/gloo/objs/security/password.rb +5 -8
  35. data/lib/gloo/objs/system/file_handle.rb +39 -5
  36. data/lib/gloo/objs/web_svr/element.rb +2 -2
  37. data/lib/gloo/objs/web_svr/page.rb +16 -6
  38. data/lib/gloo/objs/web_svr/svr.rb +29 -13
  39. data/lib/gloo/persist/file_loader.rb +2 -2
  40. data/lib/gloo/persist/file_storage.rb +1 -1
  41. data/lib/gloo/persist/line_splitter.rb +1 -0
  42. data/lib/gloo/verbs/check.rb +54 -0
  43. data/lib/gloo/verbs/redirect.rb +34 -2
  44. data/lib/gloo/verbs/tell.rb +11 -36
  45. data/lib/gloo/web_svr/handler.rb +32 -5
  46. data/lib/gloo/web_svr/request.rb +11 -40
  47. data/lib/gloo/web_svr/request_params.rb +104 -0
  48. data/lib/gloo/web_svr/response.rb +25 -0
  49. data/lib/gloo/web_svr/response_code.rb +1 -1
  50. data/lib/gloo/web_svr/routing/router.rb +10 -2
  51. data/lib/gloo/web_svr/session.rb +18 -12
  52. metadata +10 -3
@@ -0,0 +1,68 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Iterate over each child in an object container.
5
+ #
6
+
7
+ module Gloo
8
+ module Objs
9
+ class EachChild
10
+
11
+ CHILD = 'child'.freeze
12
+ IN = 'IN'.freeze
13
+
14
+ # ---------------------------------------------------------------------
15
+ # Create Iterator
16
+ # ---------------------------------------------------------------------
17
+
18
+ def initialize( engine, iterator_obj )
19
+ @engine = engine
20
+ @iterator_obj = iterator_obj
21
+ end
22
+
23
+
24
+ # ---------------------------------------------------------------------
25
+ # Check if this is the right iterator
26
+ # ---------------------------------------------------------------------
27
+
28
+ #
29
+ # Use this iterator for each loop?
30
+ #
31
+ def self.use_for?( iterator_obj )
32
+ return true if iterator_obj.find_child CHILD
33
+
34
+ return false
35
+ end
36
+
37
+
38
+ # ---------------------------------------------------------------------
39
+ # Iterate
40
+ # ---------------------------------------------------------------------
41
+
42
+ #
43
+ # Run for each child.
44
+ #
45
+ def run
46
+ o = @iterator_obj.find_child IN
47
+ return unless o
48
+
49
+ o = Gloo::Objs::Alias.resolve_alias( @engine, o )
50
+ o.children.each do |child|
51
+ set_child child
52
+ @iterator_obj.run_do
53
+ end
54
+ end
55
+
56
+ #
57
+ # Set the child alias.
58
+ #
59
+ def set_child( obj )
60
+ o = @iterator_obj.find_child CHILD
61
+ return unless o
62
+
63
+ o.set_value obj.pn
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,83 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Iterate over each file in a folder.
5
+ #
6
+
7
+ module Gloo
8
+ module Objs
9
+ class EachFile
10
+
11
+ FILE = 'file'.freeze
12
+ EXT = 'ext'.freeze
13
+ WILD = '*'.freeze
14
+
15
+
16
+ # ---------------------------------------------------------------------
17
+ # Create Iterator
18
+ # ---------------------------------------------------------------------
19
+
20
+ def initialize( engine, iterator_obj )
21
+ @engine = engine
22
+ @iterator_obj = iterator_obj
23
+ end
24
+
25
+
26
+ # ---------------------------------------------------------------------
27
+ # Check if this is the right iterator
28
+ # ---------------------------------------------------------------------
29
+
30
+ #
31
+ # Use this iterator for each loop?
32
+ #
33
+ def self.use_for?( iterator_obj )
34
+ return true if iterator_obj.find_child FILE
35
+
36
+ return false
37
+ end
38
+
39
+
40
+ # ---------------------------------------------------------------------
41
+ # Iterate
42
+ # ---------------------------------------------------------------------
43
+
44
+ #
45
+ # Run for each file.
46
+ #
47
+ def run
48
+ folder = @iterator_obj.in_value
49
+ return unless folder
50
+
51
+ unless Dir.exist?( folder )
52
+ @engine.err "Folder does not exist: #{folder}"
53
+ end
54
+
55
+ Dir.glob( "#{folder}#{wildcard}" ).each do |f|
56
+ set_file f
57
+ @iterator_obj.run_do
58
+ end
59
+ end
60
+
61
+ #
62
+ # Get the wildcard for the glob.
63
+ #
64
+ def wildcard
65
+ o = @iterator_obj.find_child EXT
66
+ return WILD unless o
67
+
68
+ return "#{WILD}.#{o.value}"
69
+ end
70
+
71
+ #
72
+ # Set the value of the word.
73
+ #
74
+ def set_file( f )
75
+ o = @iterator_obj.find_child FILE
76
+ return unless o
77
+
78
+ o.set_value f
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,67 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Iterate over each line in a text block.
5
+ #
6
+
7
+ module Gloo
8
+ module Objs
9
+ class EachLine
10
+
11
+ LINE = 'line'.freeze
12
+
13
+
14
+ # ---------------------------------------------------------------------
15
+ # Create Iterator
16
+ # ---------------------------------------------------------------------
17
+
18
+ def initialize( engine, iterator_obj )
19
+ @engine = engine
20
+ @iterator_obj = iterator_obj
21
+ end
22
+
23
+
24
+ # ---------------------------------------------------------------------
25
+ # Check if this is the right iterator
26
+ # ---------------------------------------------------------------------
27
+
28
+ #
29
+ # Use this iterator for each loop?
30
+ #
31
+ def self.use_for?( iterator_obj )
32
+ return true if iterator_obj.find_child LINE
33
+
34
+ return false
35
+ end
36
+
37
+
38
+ # ---------------------------------------------------------------------
39
+ # Iterate
40
+ # ---------------------------------------------------------------------
41
+
42
+ #
43
+ # Run for each line.
44
+ #
45
+ def run
46
+ str = @iterator_obj.in_value
47
+ return unless str
48
+
49
+ str.each_line do |line|
50
+ set_line line
51
+ @iterator_obj.run_do
52
+ end
53
+ end
54
+
55
+ #
56
+ # Set the value of the word.
57
+ #
58
+ def set_line( line )
59
+ o = @iterator_obj.find_child LINE
60
+ return unless o
61
+
62
+ o.set_value line
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,84 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Iterate over each repo in a directory.
5
+ #
6
+
7
+ module Gloo
8
+ module Objs
9
+ class EachRepo
10
+
11
+ FILE = 'file'.freeze
12
+ REPO = 'repo'.freeze
13
+
14
+
15
+ # ---------------------------------------------------------------------
16
+ # Create Iterator
17
+ # ---------------------------------------------------------------------
18
+
19
+ def initialize( engine, iterator_obj )
20
+ @engine = engine
21
+ @iterator_obj = iterator_obj
22
+ end
23
+
24
+
25
+ # ---------------------------------------------------------------------
26
+ # Check if this is the right iterator
27
+ # ---------------------------------------------------------------------
28
+
29
+ #
30
+ # Use this iterator for each loop?
31
+ #
32
+ def self.use_for?( iterator_obj )
33
+ return true if iterator_obj.find_child REPO
34
+
35
+ return false
36
+ end
37
+
38
+
39
+ # ---------------------------------------------------------------------
40
+ # Iterate
41
+ # ---------------------------------------------------------------------
42
+
43
+ #
44
+ # Find all git projects in a path.
45
+ #
46
+ def find_all_git_projects( path )
47
+ path.children.collect do |f|
48
+ if f.directory? && ( File.basename( f ) == '.git' )
49
+ File.dirname( f )
50
+ elsif f.directory?
51
+ find_all_git_projects( f )
52
+ end
53
+ end.flatten.compact
54
+ end
55
+
56
+ #
57
+ # Run for repo.
58
+ #
59
+ def run
60
+ path = @iterator_obj.in_value
61
+ return unless path
62
+
63
+ path = Pathname.new( path )
64
+ repos = find_all_git_projects( path )
65
+ repos.each do |o|
66
+ set_repo o
67
+ @iterator_obj.run_do
68
+ end
69
+ end
70
+
71
+ #
72
+ # Set the value of the repo.
73
+ # This is a path to the repo.
74
+ #
75
+ def set_repo( path )
76
+ o = @iterator_obj.find_child REPO
77
+ return unless o
78
+
79
+ o.set_value path
80
+ end
81
+
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,67 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Iterate over each word in a string.
5
+ #
6
+
7
+ module Gloo
8
+ module Objs
9
+ class EachWord
10
+
11
+ WORD = 'word'.freeze
12
+
13
+
14
+ # ---------------------------------------------------------------------
15
+ # Create Iterator
16
+ # ---------------------------------------------------------------------
17
+
18
+ def initialize( engine, iterator_obj )
19
+ @engine = engine
20
+ @iterator_obj = iterator_obj
21
+ end
22
+
23
+
24
+ # ---------------------------------------------------------------------
25
+ # Check if this is the right iterator
26
+ # ---------------------------------------------------------------------
27
+
28
+ #
29
+ # Use this iterator for each loop?
30
+ #
31
+ def self.use_for?( iterator_obj )
32
+ return true if iterator_obj.find_child WORD
33
+
34
+ return false
35
+ end
36
+
37
+
38
+ # ---------------------------------------------------------------------
39
+ # Iterate
40
+ # ---------------------------------------------------------------------
41
+
42
+ #
43
+ # Run for each word.
44
+ #
45
+ def run
46
+ str = @iterator_obj.in_value
47
+ return unless str
48
+
49
+ str.split( ' ' ).each do |word|
50
+ set_word word
51
+ @iterator_obj.run_do
52
+ end
53
+ end
54
+
55
+ #
56
+ # Set the value of the word.
57
+ #
58
+ def set_word( word )
59
+ o = @iterator_obj.find_child WORD
60
+ return unless o
61
+
62
+ o.set_value word
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -160,7 +160,7 @@ module Gloo
160
160
 
161
161
  heads = rs.fields if rs
162
162
  rescue => e
163
- @engine.err e.message
163
+ @engine.log_exception e
164
164
  end
165
165
 
166
166
  return [ heads, data ]
@@ -242,7 +242,7 @@ module Gloo
242
242
  }
243
243
  Mysql2::Client.new( h )
244
244
  rescue => e
245
- @engine.err e.message
245
+ @engine.log_exception e
246
246
  @engine.heap.it.set_to false
247
247
  return false
248
248
  end
@@ -189,7 +189,7 @@ module Gloo
189
189
  begin
190
190
  result = pg_conn.exec( "SELECT NOW()" )
191
191
  rescue => e
192
- @engine.err e.message
192
+ @engine.log_exception e
193
193
  @engine.heap.it.set_to false
194
194
  return false
195
195
  end
@@ -34,6 +34,15 @@ module Gloo
34
34
  return KEYWORD_SHORT
35
35
  end
36
36
 
37
+ #
38
+ # Get the result container if it exists.
39
+ #
40
+ def get_result_can
41
+ result_can = find_child RESULT
42
+ result_can = Gloo::Objs::Alias.resolve_alias( @engine, result_can )
43
+ return result_can
44
+ end
45
+
37
46
  # ---------------------------------------------------------------------
38
47
  # Children
39
48
  # ---------------------------------------------------------------------
@@ -78,10 +87,12 @@ module Gloo
78
87
  return unless db
79
88
 
80
89
  begin
90
+ clear_results
91
+
81
92
  result = db.query( sql_value, param_array )
82
93
  process_result( result, db )
83
94
  rescue => e
84
- @engine.err e.message
95
+ @engine.log_exception e
85
96
  return
86
97
  end
87
98
  end
@@ -105,7 +116,7 @@ module Gloo
105
116
  app.add_db_time elapsed if app
106
117
  return result
107
118
  rescue => e
108
- @engine.err e.message
119
+ @engine.log_exception e
109
120
  return
110
121
  end
111
122
  end
@@ -177,8 +188,7 @@ module Gloo
177
188
  return unless query_result
178
189
  return unless query_result.has_data_to_show?
179
190
 
180
- result_can = find_child RESULT
181
- result_can = Gloo::Objs::Alias.resolve_alias( @engine, result_can )
191
+ result_can = get_result_can
182
192
 
183
193
  if result_can
184
194
  if simple_list?
@@ -205,12 +215,51 @@ module Gloo
205
215
  params = []
206
216
  o.children.each do |p|
207
217
  p = Gloo::Objs::Alias.resolve_alias( @engine, p )
208
- params << p.value
218
+ params << p.sql_value
209
219
  end
210
220
 
211
221
  return params
212
222
  end
213
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.value = nil
261
+ end
262
+ end
214
263
 
215
264
  end
216
265
  end
@@ -33,8 +33,13 @@ module Gloo
33
33
 
34
34
  #
35
35
  # Does the data contain a single row?
36
+ # OR, if the result is empty, return false.
36
37
  #
37
38
  def single_row_result?
39
+ if @result_can && ( @result_can.child_count == 0 )
40
+ return false
41
+ end
42
+
38
43
  return @data.count == 1
39
44
  end
40
45
 
@@ -108,7 +113,7 @@ module Gloo
108
113
  def update_single_row
109
114
  row = @data[0]
110
115
  @heads.each_with_index do |h, i|
111
- child = @result_can.find_child h
116
+ child = @result_can.find_child h
112
117
  child.set_value row[i] if child
113
118
  end
114
119
  end
@@ -162,7 +162,7 @@ module Gloo
162
162
  sql = "SELECT COUNT(name) FROM sqlite_master WHERE type='table'"
163
163
  db.get_first_value sql
164
164
  rescue => e
165
- @engine.err e.message
165
+ @engine.log_exception e
166
166
  @engine.heap.it.set_to false
167
167
  return false
168
168
  end
@@ -67,7 +67,7 @@ module Gloo
67
67
  result = o.run_query
68
68
  return result
69
69
  rescue => e
70
- @engine.err e.message
70
+ @engine.log_exception e
71
71
  return nil
72
72
  end
73
73
  else
@@ -196,7 +196,7 @@ module Gloo
196
196
  helper = Gloo::WebSvr::TableRenderer.new( @engine )
197
197
  return helper.data_to_table params
198
198
  rescue => e
199
- @engine.err e.message
199
+ @engine.log_exception e
200
200
  return nil
201
201
  end
202
202
  end
@@ -98,7 +98,7 @@ module Gloo
98
98
  set_result result
99
99
  @engine.heap.it.set_to result
100
100
  rescue => e
101
- @engine.err e.message
101
+ @engine.log_exception e
102
102
  end
103
103
  end
104
104
 
@@ -39,8 +39,7 @@ module Gloo
39
39
  # Returns nil if there is none.
40
40
  #
41
41
  def salt
42
- o = find_child SALT
43
- return o&.value
42
+ return find_child_value SALT
44
43
  end
45
44
 
46
45
  #
@@ -48,15 +47,14 @@ module Gloo
48
47
  # Returns nil if there is none.
49
48
  #
50
49
  def password
51
- o = find_child PASSWORD
52
- return o&.value
50
+ return find_child_value PASSWORD
53
51
  end
54
52
 
55
53
  #
56
54
  # Update the password value.
57
55
  #
58
56
  def update_password( new_pwd )
59
- o = find_child PASSWORD
57
+ o = find_child_resolve_alias PASSWORD
60
58
  return unless o
61
59
 
62
60
  o.set_value new_pwd
@@ -74,15 +72,14 @@ module Gloo
74
72
  # Returns nil if there is none.
75
73
  #
76
74
  def hash
77
- o = find_child HASH
78
- return o&.value
75
+ return find_child_value HASH
79
76
  end
80
77
 
81
78
  #
82
79
  # Update the hashed password value.
83
80
  #
84
81
  def update_hash( new_hash )
85
- o = find_child HASH
82
+ o = find_child_resolve_alias HASH
86
83
  return unless o
87
84
 
88
85
  o.set_value new_hash
@@ -33,8 +33,8 @@ module Gloo
33
33
  # Get a list of message names that this object receives.
34
34
  #
35
35
  def self.messages
36
- basic = %w[read write]
37
- checks = %w[check_exists check_is_file check_is_dir]
36
+ basic = %w[read write get_name get_ext get_parent]
37
+ checks = %w[exists? is_file? is_dir?]
38
38
  search = %w[find_match]
39
39
  show = %w[show page open]
40
40
  return super + basic + show + checks + search
@@ -102,7 +102,7 @@ module Gloo
102
102
  #
103
103
  # Check to see if the file exists.
104
104
  #
105
- def msg_check_exists
105
+ def msg_exists?
106
106
  result = File.exist? value
107
107
  @engine.heap.it.set_to result
108
108
  end
@@ -110,7 +110,7 @@ module Gloo
110
110
  #
111
111
  # Check to see if the file is a file.
112
112
  #
113
- def msg_check_is_file
113
+ def msg_is_file?
114
114
  result = File.file? value
115
115
  @engine.heap.it.set_to result
116
116
  end
@@ -118,7 +118,7 @@ module Gloo
118
118
  #
119
119
  # Check to see if the file is a directory.
120
120
  #
121
- def msg_check_is_dir
121
+ def msg_is_dir?
122
122
  result = File.directory? value
123
123
  @engine.heap.it.set_to result
124
124
  end
@@ -131,6 +131,40 @@ module Gloo
131
131
  @engine.heap.it.set_to result
132
132
  end
133
133
 
134
+ #
135
+ # Get the name of the file.
136
+ #
137
+ def msg_get_name
138
+ if value.blank?
139
+ @engine.heap.it.set_to ''
140
+ else
141
+ file_name = File.basename( value, File.extname( value ) )
142
+ @engine.heap.it.set_to file_name
143
+ end
144
+ end
145
+
146
+ #
147
+ # Get the file's extension.
148
+ #
149
+ def msg_get_ext
150
+ if value.blank?
151
+ @engine.heap.it.set_to ''
152
+ else
153
+ @engine.heap.it.set_to File.extname( value )
154
+ end
155
+ end
156
+
157
+ #
158
+ # Get the parent directory of the file.
159
+ #
160
+ def msg_get_parent
161
+ if value.blank?
162
+ @engine.heap.it.set_to ''
163
+ else
164
+ @engine.heap.it.set_to File.dirname( value )
165
+ end
166
+ end
167
+
134
168
  end
135
169
  end
136
170
  end
@@ -226,7 +226,7 @@ module Gloo
226
226
  e = Gloo::Objs::Alias.resolve_alias( engine, e )
227
227
  if e.class == Element
228
228
  rendered_obj_content << e.send( render_ƒ )
229
- else
229
+ elsif e
230
230
  data = render_thing e, render_ƒ, engine
231
231
  ( rendered_obj_content << data ) if data # e.render( render_ƒ )
232
232
  end
@@ -242,7 +242,7 @@ module Gloo
242
242
  begin
243
243
  return e.render( render_ƒ )
244
244
  rescue => e
245
- engine.err e.message
245
+ engine.log_exception e
246
246
  return ''
247
247
  end
248
248
  end