gloo 3.4.1 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac56d6b0d2298092e23e0bf352b6b5c77bfbf0d231b060003a404bc8e313e269
4
- data.tar.gz: 9524d5e521c258dd5922c49c3c8dfcef2c52f57d0dff02306bfdb5ed3f1d0baa
3
+ metadata.gz: 6e79ebad69bd8325e6f1b09ecd7d32520e7f82d1e4181d74c31433e4ca159cda
4
+ data.tar.gz: 50cdd391fa4d96d0cb8897bf8b8fdb02b30aea567083343e5540b492399a9e93
5
5
  SHA512:
6
- metadata.gz: c6e81f7c12f73b7736c79be525c23a300b231fbb76884490ef1b0b87ff85f3e85533ef708edb4b1044d99e443b7fb0df3f39551dce69b6d6dd91a3d2692dc472
7
- data.tar.gz: 3c50b4ffba3590217bcd2641a190e196a472620321a5f23eeb07d8e5cf24d19ba81d675497143bf44ea4c389d308ae65446ceee8be50037e5dbbc26c13cfad8f
6
+ metadata.gz: 6712527d452fb8c73799f4e9829ffe58edb518aa6ed440e30fadb9211af0b899dce31453098f518b6310b693aec330d567b7ffb50713049c9abb3c27b7395eb8
7
+ data.tar.gz: ba4b513a0e8b587d7418d10a16cfed7ecd2df4a9ce85409cdd78c59a5d936b0714008bfd02baa8a66814be1855ece161d3a07a9b7b1f6e6783d1ef9cf5091835
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-3.2.5
1
+ 3.3.5
data/lib/VERSION CHANGED
@@ -1 +1 @@
1
- 3.4.1
1
+ 3.6.0
data/lib/VERSION_NOTES CHANGED
@@ -1,3 +1,18 @@
1
+ 3.6.0 - 2024.11.26
2
+ - Adds support for route parameters
3
+ - Updates iterators
4
+ - Clear results for SQL queries
5
+ - Bug fixes
6
+
7
+
8
+ 3.5.0 - 2024.10.18
9
+ - check obj for message alternate to tell
10
+ - new base object messages
11
+ - fixes issue with single row returned from query
12
+ - adds on_error event
13
+ - use aliases in pwd obj
14
+
15
+
1
16
  3.4.1 - 2024.09.23
2
17
  - Removes old, unused sound objects
3
18
  - Adds support for lib folder in gloo rather than in the project folder
data/lib/gloo/app/args.rb CHANGED
@@ -51,12 +51,12 @@ module Gloo
51
51
  return true unless app?
52
52
 
53
53
  if @app_path.nil?
54
- @engine.log.error "App Path required to run in App mode."
54
+ @engine.err "App Path required to run in App mode."
55
55
  return false
56
56
  end
57
57
 
58
58
  unless File.directory? @app_path
59
- @engine.log.error "'#{@app_path}' is not a valid directory."
59
+ @engine.err "'#{@app_path}' is not a valid directory."
60
60
  return false
61
61
  end
62
62
 
@@ -201,7 +201,7 @@ module Gloo
201
201
  begin
202
202
  @parser.run @last_cmd
203
203
  rescue => e
204
- err e.message
204
+ log_exception e
205
205
  end
206
206
  end
207
207
 
@@ -282,11 +282,30 @@ module Gloo
282
282
  # Report an error.
283
283
  # Write it to the log and set the heap error value.
284
284
  #
285
- def err( msg )
285
+ def err( msg, backtrace=nil )
286
286
  @log.error msg
287
287
  @heap.error.set_to msg
288
+
289
+ @event_manager.on_error( msg, backtrace)
288
290
  end
289
291
 
292
+ #
293
+ # Log an exception.
294
+ # This function does not log the full backtrace, but
295
+ # does write part of it to the log.
296
+ #
297
+ def log_exception ex
298
+ # Get the stack trace, and if needed truncate to fit.
299
+ msg_lines = ex.backtrace
300
+ if msg_lines.count > 27
301
+ msg_lines = msg_lines[0..13] + [ '... truncated ...' ] + msg_lines[-13..-1]
302
+ end
303
+ backtrace = msg_lines.join( "\n" )
304
+ @log.error backtrace
305
+
306
+ err( ex.message, backtrace)
307
+ end
308
+
290
309
  end
291
310
  end
292
311
  end
data/lib/gloo/app/info.rb CHANGED
@@ -4,8 +4,6 @@
4
4
  # Application information such as Version and public name.
5
5
  #
6
6
 
7
- # require 'gloo-lang'
8
-
9
7
  module Gloo
10
8
  module App
11
9
  class Info
@@ -30,8 +30,7 @@ module Gloo
30
30
  o = clazz.new
31
31
  return o.convert( value )
32
32
  rescue => e
33
- @engine.log.error e.message
34
- @engine.heap.error.set_to e.message
33
+ @engine.log_exception e
35
34
  end
36
35
 
37
36
  return default
@@ -12,6 +12,8 @@ module Gloo
12
12
  # Convert the given string value to an integer.
13
13
  #
14
14
  def convert( value )
15
+ return nil if value.blank?
16
+
15
17
  return value.to_i
16
18
  end
17
19
 
@@ -190,7 +190,7 @@ module Gloo
190
190
  #
191
191
  def add_key( keyword )
192
192
  if @keywords.include?( keyword )
193
- # @engine.log.error "duplicate keyword '#{keyword}'"
193
+ # @engine.err "duplicate keyword '#{keyword}'"
194
194
  return
195
195
  end
196
196
 
@@ -72,6 +72,25 @@ module Gloo
72
72
  arr.each { |o| Gloo::Exec::Dispatch.message( @engine, 'run', o ) }
73
73
  end
74
74
 
75
+ #
76
+ # Run the on_error scripts in any open objects.
77
+ # For each on_error script found, look for the error_data container
78
+ # and set the error message and backtrace.
79
+ #
80
+ def on_error msg, backtrace
81
+ @engine.log.debug 'on_error event'
82
+ arr = Gloo::Core::ObjFinder.by_name( @engine, 'on_error' )
83
+ arr.each do |o|
84
+ data = o.parent.find_child 'error_data'
85
+ if data
86
+ data.find_child( 'message' ).set_value msg
87
+ data.find_child( 'backtrace' ).set_value backtrace
88
+ end
89
+
90
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
91
+ end
92
+ end
93
+
75
94
  end
76
95
  end
77
96
  end
@@ -164,7 +164,7 @@ module Gloo
164
164
  #
165
165
  def create_new( name, value, type, parent )
166
166
  unless parent
167
- @engine.log.error "Could not create object. Bad path: #{name}"
167
+ @engine.err "Could not create object. Bad path: #{name}"
168
168
  return nil
169
169
  end
170
170
 
@@ -202,7 +202,7 @@ module Gloo
202
202
  end
203
203
 
204
204
  unless t.can_create?
205
- @engine.log.error "'#{type_name}' cannot be created."
205
+ @engine.err "'#{type_name}' cannot be created."
206
206
  return nil
207
207
  end
208
208
 
@@ -138,7 +138,7 @@ module Gloo
138
138
  o = "msg_#{msg}"
139
139
  return self.public_send( o ) if self.respond_to? o
140
140
 
141
- @engine.log.error "Message #{msg} not implemented"
141
+ @engine.err "Message #{msg} not implemented"
142
142
  return false
143
143
  end
144
144
 
@@ -15,7 +15,7 @@ module Gloo
15
15
  # Does the pathname start with here reference?
16
16
  #
17
17
  def self.includes_here_ref?( elements )
18
- return elements.first.start_with?( HERE )
18
+ return elements.first&.start_with?( HERE )
19
19
  end
20
20
 
21
21
  #
data/lib/gloo/core/obj.rb CHANGED
@@ -137,6 +137,13 @@ module Gloo
137
137
  return self.value.to_s.strip.empty?
138
138
  end
139
139
 
140
+ #
141
+ # Value for a SQL query.
142
+ #
143
+ def sql_value
144
+ return self.value
145
+ end
146
+
140
147
  #
141
148
  # Is this an alias to another object?
142
149
  #
@@ -144,6 +151,13 @@ module Gloo
144
151
  return self.type_display == Gloo::Objs::Alias.typename
145
152
  end
146
153
 
154
+ #
155
+ # Is this a container object?
156
+ #
157
+ def is_container?
158
+ return self.type_display == Gloo::Objs::Container.typename
159
+ end
160
+
147
161
  #
148
162
  # Is this a function object?
149
163
  #
@@ -216,6 +230,30 @@ module Gloo
216
230
  return nil
217
231
  end
218
232
 
233
+ #
234
+ # Find a child, resolve any alias references.
235
+ # This returns the object, not the value.
236
+ #
237
+ def find_child_resolve_alias( name )
238
+ o = find_child name
239
+ return nil unless o
240
+
241
+ o = Gloo::Objs::Alias.resolve_alias( @engine, o )
242
+ return o
243
+ end
244
+
245
+ #
246
+ # Find a child, resolve any alias references,
247
+ # and return the object's value.
248
+ #
249
+ def find_child_value( name )
250
+ o = find_child name
251
+ return nil unless o
252
+
253
+ o = Gloo::Objs::Alias.resolve_alias( @engine, o )
254
+ return o&.value
255
+ end
256
+
219
257
  #
220
258
  # Get the index of the child with the given name.
221
259
  #
@@ -264,7 +302,7 @@ module Gloo
264
302
  # Get a list of message names that this object receives.
265
303
  #
266
304
  def self.messages
267
- return %w[reload unload]
305
+ return %w[reload unload blank? contains?]
268
306
  end
269
307
 
270
308
  #
@@ -282,7 +320,7 @@ module Gloo
282
320
  @params = params
283
321
  return self.dispatch msg if self.can_receive_message? msg
284
322
 
285
- @engine.log.error "Object #{self.name} cannot receive message #{msg}"
323
+ @engine.err "Object #{self.name} cannot receive message #{msg}"
286
324
  return false
287
325
  end
288
326
 
@@ -295,7 +333,7 @@ module Gloo
295
333
  self.public_send( o )
296
334
  return true
297
335
  else
298
- @engine.log.error "Message #{msg} not implemented"
336
+ @engine.err "Message #{msg} not implemented"
299
337
  return false
300
338
  end
301
339
  end
@@ -305,7 +343,7 @@ module Gloo
305
343
  #
306
344
  def msg_unload
307
345
  if self.root?
308
- @engine.log.error 'Cannot unload the root object.'
346
+ @engine.err 'Cannot unload the root object.'
309
347
  return
310
348
  end
311
349
 
@@ -318,13 +356,31 @@ module Gloo
318
356
  #
319
357
  def msg_reload
320
358
  if self.root?
321
- @engine.log.error 'Cannot reload the root object.'
359
+ @engine.err 'Cannot reload the root object.'
322
360
  return
323
361
  end
324
362
 
325
363
  @engine.persist_man.reload self
326
364
  end
327
365
 
366
+ #
367
+ # Check to see if the value is blank.
368
+ #
369
+ def msg_blank?
370
+ val_blank = value.blank?
371
+ @engine.heap.it.set_to val_blank
372
+ return val_blank
373
+ end
374
+
375
+ #
376
+ # Check to see if there are children.
377
+ #
378
+ def msg_contains?
379
+ has_children = child_count.positive?
380
+ @engine.heap.it.set_to has_children
381
+ return has_children
382
+ end
383
+
328
384
 
329
385
  # ---------------------------------------------------------------------
330
386
  # Render
@@ -31,7 +31,7 @@ module Gloo
31
31
  verb = dic.find_verb( tokens.verb )
32
32
  return verb.new( @engine, tokens, params ) if verb
33
33
 
34
- @engine.log.error "Verb '#{tokens.verb}' was not found."
34
+ @engine.err "Verb '#{tokens.verb}' was not found."
35
35
  return nil
36
36
  end
37
37
 
data/lib/gloo/core/pn.rb CHANGED
@@ -150,7 +150,7 @@ module Gloo
150
150
  @elements[ 0..-2 ].each do |e|
151
151
  o = o.find_child( e )
152
152
  if o.nil?
153
- @engine.log.error "Object '#{e}' was not found."
153
+ @engine.err "Object '#{e}' was not found."
154
154
  return nil
155
155
  end
156
156
  end
@@ -12,10 +12,29 @@ module Gloo
12
12
  module Exec
13
13
  class Dispatch
14
14
 
15
+ OBJ_NOT_FOUND_ERR = 'Object was not found: '.freeze
16
+
17
+ #
18
+ # Send a message to an object of a given name (and path).
19
+ # Once the object is found, the message is dispatched.
20
+ #
21
+ def self.send_message( engine, msg, to_obj_pn, params = nil )
22
+ pn = Gloo::Core::Pn.new( engine, to_obj_pn )
23
+ target_obj = pn.resolve
24
+
25
+ unless target_obj
26
+ engine.err "#{OBJ_NOT_FOUND_ERR} #{to_obj_pn}"
27
+ return
28
+ end
29
+ Gloo::Exec::Dispatch.message( engine, msg, target_obj, params )
30
+ end
31
+
15
32
  #
16
33
  # Dispatch the given message to the given object.
17
34
  #
18
35
  def self.message( engine, msg, to_obj, params = nil )
36
+ return unless to_obj
37
+
19
38
  engine.log.debug "Dispatch message #{msg} to #{to_obj.name}"
20
39
  a = Gloo::Exec::Action.new msg, to_obj, params
21
40
  Gloo::Exec::Dispatch.action( engine, a )
@@ -36,7 +36,7 @@ module Gloo
36
36
  if o
37
37
  o.send_message 'run'
38
38
  else
39
- engine.log.error "Could not send message to object. Bad path: #{path_name}"
39
+ engine.err "Could not send message to object. Bad path: #{path_name}"
40
40
  end
41
41
  end
42
42
 
@@ -38,7 +38,16 @@ module Gloo
38
38
  self.value = new_value.to_i
39
39
  end
40
40
 
41
-
41
+ #
42
+ # Value for a SQL query.
43
+ #
44
+ def sql_value
45
+ return nil if self.value.blank?
46
+
47
+ return self.value
48
+ end
49
+
50
+
42
51
  # ---------------------------------------------------------------------
43
52
  # Messages
44
53
  # ---------------------------------------------------------------------
@@ -3,6 +3,7 @@
3
3
  #
4
4
  # A looping construct...do something for each whatever in something.
5
5
  # This object has several possible uses:
6
+ # - each child in a container
6
7
  # - each word in a string
7
8
  # - each line in a string
8
9
  # - each file in a directory
@@ -15,13 +16,9 @@ module Gloo
15
16
 
16
17
  KEYWORD = 'each'.freeze
17
18
  KEYWORD_SHORT = 'each'.freeze
18
- CHILD = 'child'.freeze
19
19
  WORD = 'word'.freeze
20
- LINE = 'line'.freeze
21
- FILE = 'file'.freeze
22
- REPO = 'repo'.freeze
23
- IN = 'IN'.freeze
24
20
  DO = 'do'.freeze
21
+ IN = 'IN'.freeze
25
22
 
26
23
  #
27
24
  # The name of the object type.
@@ -42,8 +39,7 @@ module Gloo
42
39
  # Returns nil if there is none.
43
40
  #
44
41
  def in_value
45
- o = find_child IN
46
- return o ? o.value : nil
42
+ return find_child_value IN
47
43
  end
48
44
 
49
45
  #
@@ -56,6 +52,7 @@ module Gloo
56
52
  Gloo::Exec::Dispatch.message( @engine, 'run', o )
57
53
  end
58
54
 
55
+
59
56
  # ---------------------------------------------------------------------
60
57
  # Children
61
58
  # ---------------------------------------------------------------------
@@ -81,6 +78,7 @@ module Gloo
81
78
  fac.create_script DO, '', self
82
79
  end
83
80
 
81
+
84
82
  # ---------------------------------------------------------------------
85
83
  # Messages
86
84
  # ---------------------------------------------------------------------
@@ -94,186 +92,21 @@ module Gloo
94
92
 
95
93
  # Run the system command.
96
94
  def msg_run
97
- if each_child?
98
- run_each_child
99
- elsif each_word?
100
- run_each_word
101
- elsif each_line?
102
- run_each_line
103
- elsif each_repo?
104
- run_each_repo
95
+ if EachChild.use_for?( self )
96
+ EachChild.new( @engine, self ).run
97
+ elsif EachWord.use_for?( self )
98
+ EachWord.new( @engine, self ).run
99
+ elsif EachLine.use_for?( self )
100
+ EachLine.new( @engine, self ).run
101
+ elsif EachFile.use_for?( self )
102
+ EachFile.new( @engine, self ).run
103
+ elsif EachRepo.use_for?( self )
104
+ EachRepo.new( @engine, self ).run
105
+ else
106
+ @engine.err "Not set up to run each for that target."
105
107
  end
106
108
  end
107
109
 
108
- # ---------------------------------------------------------------------
109
- # Child Object
110
- # ---------------------------------------------------------------------
111
-
112
- #
113
- # Is it set up to run for each word?
114
- # If there is a child object by the name "word"
115
- # then we will loop for each word in the string.
116
- #
117
- def each_child?
118
- return true if contains_child? CHILD
119
-
120
- return false
121
- end
122
-
123
- #
124
- # Run for each word.
125
- #
126
- def run_each_child
127
- o = find_child IN
128
- return unless o
129
-
130
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
131
- o.children.each do |child|
132
- set_child child
133
- run_do
134
- end
135
- end
136
-
137
- #
138
- # Set the child alias.
139
- #
140
- def set_child( obj )
141
- o = find_child CHILD
142
- return unless o
143
-
144
- o.set_value obj.pn
145
- end
146
-
147
- # ---------------------------------------------------------------------
148
- # Word
149
- # ---------------------------------------------------------------------
150
-
151
- #
152
- # Is it set up to run for each word?
153
- # If there is a child object by the name "word"
154
- # then we will loop for each word in the string.
155
- #
156
- def each_word?
157
- return true if find_child WORD
158
-
159
- return false
160
- end
161
-
162
- #
163
- # Run for each word.
164
- #
165
- def run_each_word
166
- str = in_value
167
- return unless str
168
-
169
- str.split( ' ' ).each do |word|
170
- set_word word
171
- run_do
172
- end
173
- end
174
-
175
- #
176
- # Set the value of the word.
177
- #
178
- def set_word( word )
179
- o = find_child WORD
180
- return unless o
181
-
182
- o.set_value word
183
- end
184
-
185
- # ---------------------------------------------------------------------
186
- # Line
187
- # ---------------------------------------------------------------------
188
-
189
- #
190
- # Is it set up to run for each line?
191
- # If there is a child object by the name "line"
192
- # then we will loop for each line in the string.
193
- #
194
- def each_line?
195
- return true if find_child LINE
196
-
197
- return false
198
- end
199
-
200
- #
201
- # Run for each line.
202
- #
203
- def run_each_line
204
- str = in_value
205
- return unless str
206
-
207
- str.each_line do |line|
208
- set_line line
209
- run_do
210
- end
211
- end
212
-
213
- #
214
- # Set the value of the word.
215
- #
216
- def set_line( line )
217
- o = find_child LINE
218
- return unless o
219
-
220
- o.set_value line
221
- end
222
-
223
- # ---------------------------------------------------------------------
224
- # Git Repo
225
- # ---------------------------------------------------------------------
226
-
227
- #
228
- # Is it set up to run for each git repo?
229
- # If there is a child object by the name "repo"
230
- # then we will loop for each repo in the directory.
231
- #
232
- def each_repo?
233
- return true if find_child REPO
234
-
235
- return false
236
- end
237
-
238
- #
239
- # Find all git projects in a path.
240
- #
241
- def find_all_git_projects( path )
242
- path.children.collect do |f|
243
- if f.directory? && ( File.basename( f ) == '.git' )
244
- File.dirname( f )
245
- elsif f.directory?
246
- find_all_git_projects( f )
247
- end
248
- end.flatten.compact
249
- end
250
-
251
- #
252
- # Run for each line.
253
- #
254
- def run_each_repo
255
- path = in_value
256
- return unless path
257
-
258
- path = Pathname.new( path )
259
- repos = find_all_git_projects( path )
260
- repos.each do |o|
261
- set_repo o
262
- run_do
263
- end
264
- end
265
-
266
- #
267
- # Set the value of the repo.
268
- # This is a path to the repo.
269
- #
270
- def set_repo( path )
271
- o = find_child REPO
272
- return unless o
273
-
274
- o.set_value path
275
- end
276
-
277
110
  end
278
111
  end
279
112
  end