knjrbfw 0.0.110 → 0.0.111

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +2 -2
  4. data/VERSION +1 -1
  5. data/knjrbfw.gemspec +8 -36
  6. data/lib/knj/autoload.rb +1 -2
  7. data/lib/knj/gtk2_window.rb +7 -7
  8. data/lib/knj/unix_proc.rb +35 -35
  9. metadata +33 -62
  10. data/lib/knj/db.rb +0 -1
  11. data/lib/knj/knjdb/dbtime.rb +0 -35
  12. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +0 -604
  13. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +0 -155
  14. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +0 -69
  15. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_sqlspecs.rb +0 -5
  16. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +0 -443
  17. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +0 -184
  18. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +0 -177
  19. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_indexes.rb +0 -29
  20. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_sqlspecs.rb +0 -5
  21. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +0 -449
  22. data/lib/knj/knjdb/dump.rb +0 -122
  23. data/lib/knj/knjdb/idquery.rb +0 -109
  24. data/lib/knj/knjdb/libknjdb.rb +0 -797
  25. data/lib/knj/knjdb/libknjdb_java_sqlite3.rb +0 -83
  26. data/lib/knj/knjdb/libknjdb_row.rb +0 -153
  27. data/lib/knj/knjdb/libknjdb_sqlite3_ironruby.rb +0 -69
  28. data/lib/knj/knjdb/query_buffer.rb +0 -87
  29. data/lib/knj/knjdb/revision.rb +0 -342
  30. data/lib/knj/knjdb/sqlspecs.rb +0 -5
  31. data/lib/knj/objects.rb +0 -957
  32. data/lib/knj/process.rb +0 -480
  33. data/lib/knj/process_meta.rb +0 -569
  34. data/spec/db_spec.rb +0 -282
  35. data/spec/db_spec_encoding_test_file.txt +0 -1
  36. data/spec/objects_spec.rb +0 -394
  37. data/spec/process_meta_spec.rb +0 -172
  38. data/spec/process_spec.rb +0 -115
@@ -1,569 +0,0 @@
1
- require "#{$knjpath}process"
2
- require "#{$knjpath}os"
3
-
4
- #This class can spawn another Ruby-process and manipulate it to create objects, evaluate code, create proxy-objects and other stuff in that process.
5
- #===Examples
6
- # This will create another Ruby-process, spawn an integer with the value of 5, run upto(10) and return each block to the current block. In the end the subprocess is terminated.
7
- # Knj::Process_meta.new do |subproc|
8
- # proxy_int = subproc.new(:Integer, 5)
9
- # proxy_int.upto(10) do |i|
10
- # print "Number: #{i}\n"
11
- # end
12
- # end
13
- class Knj::Process_meta
14
- attr_reader :process, :pid
15
-
16
- #===Examples
17
- #Knj::Process_meta.new("id" => "my_subproc") #Will make this ID be shown in the command, so you can recocknize it from "ps aux".
18
- #Knj::Process_meta.new("exec_path" => "ruby1.9.1") #If you want a certain Ruby-command to be used when starting the subprocess, instead of detecting the current one.
19
- #Knj::Process_meta.new("debug" => true, "debug_err" => true) #Enables various debug-messages to be printed.
20
- def initialize(args = {})
21
- @args = args
22
- @objects = {}
23
-
24
- #These variables are used to free memory in the subprocess, by using ObjectSpace#define_finalizer. The Mutex is the avoid problems when writing to the finalize-array multithreadded.
25
- @finalize = []
26
- @finalize_mutex = Mutex.new
27
-
28
- if @args["exec_path"]
29
- exec_path = @args["exec_path"]
30
- else
31
- exec_path = Knj::Os.executed_executable
32
- end
33
-
34
- exec_file = "#{File.dirname(__FILE__)}/scripts/process_meta_exec.rb"
35
-
36
- if args["id"]
37
- id = args["id"]
38
- else
39
- id = caller[0].to_s.strip
40
- end
41
-
42
- cmd = "#{exec_path} \"#{exec_file}\" #{Knj::Strings.unixsafe(id)}"
43
-
44
- if RUBY_ENGINE == "jruby"
45
- pid, @stdin, @stdout, @stderr = IO.popen4("#{exec_path} --#{RUBY_VERSION[0, 3]} \"#{exec_file}\" \"#{id}\"")
46
- else
47
- require "open3"
48
- @stdin, @stdout, @stderr = Open3.popen3(cmd)
49
- end
50
-
51
- @stdout.sync = true
52
- @stdin.sync = true
53
-
54
- args = {
55
- :out => @stdin,
56
- :in => @stdout,
57
- :listen => true,
58
- :debug => @args["debug"]
59
- }
60
-
61
- if @args["debug"] or @args["debug_err"]
62
- args[:err] = @stderr
63
- args[:on_err] = proc{|line|
64
- $stderr.print "stderr: #{line}"
65
- }
66
- end
67
-
68
- #Wait for process to start and check that it is returning the expected output.
69
- start_line = @stdout.gets
70
- raise "Expected startline from process to be 'process_meta_started' but got: '#{start_line}'." if start_line != "process_meta_started\n"
71
-
72
- @process = Knj::Process.new(args)
73
-
74
- res = @process.send("obj" => {"type" => "process_data"})
75
- raise "Unexpected process-data: '#{res}'." if !res.is_a?(Hash) or res["type"] != "process_data_success"
76
- @pid = res["pid"]
77
-
78
- #If block is given then run block and destroy self.
79
- if block_given?
80
- begin
81
- yield(self)
82
- ensure
83
- self.destroy
84
- end
85
- end
86
- end
87
-
88
- #Finalizer for proxy-objects. Used for unsetting objects on the process-side.
89
- def proxy_finalizer(id)
90
- @finalize_mutex.synchronize do
91
- @finalize << id
92
- end
93
- end
94
-
95
- #Flushes all finalized objects on the process-side.
96
- def check_finalizers
97
- return nil if @finalize.empty?
98
-
99
- finalize = nil
100
- @finalize_mutex.synchronize do
101
- finalize = @finalize
102
- @finalize = []
103
-
104
- begin
105
- @process.send("obj" => {
106
- "type" => "unset_multiple",
107
- "var_names" => finalize
108
- })
109
- rescue => e
110
- if e.message.to_s.index("Var-name didnt exist when trying to unset:")
111
- #ignore.
112
- else
113
- raise e
114
- end
115
- end
116
- end
117
- end
118
-
119
- #Parses the arguments given. Proxy-object-arguments will be their natural objects in the subprocess.
120
- def self.args_parse(args)
121
- if args.is_a?(Array)
122
- newargs = []
123
- args.each do |val|
124
- if val.is_a?(Knj::Process_meta::Proxy_obj)
125
- newargs << {"type" => "proxy_obj", "var_name" => val._process_meta_args[:name]}
126
- else
127
- newargs << Knj::Process_meta.args_parse(val)
128
- end
129
- end
130
-
131
- return newargs
132
- elsif args.is_a?(Hash)
133
- newargs = {}
134
- args.each do |key, val|
135
- if key.is_a?(Knj::Process_meta::Proxy_obj)
136
- key = {"type" => "proxy_obj", "var_name" => key._process_meta_args[:name]}
137
- else
138
- key = Knj::Process_meta.args_parse(key)
139
- end
140
-
141
- if val.is_a?(Knj::Process_meta::Proxy_obj)
142
- val = {"type" => "proxy_obj", "var_name" => val._process_meta_args[:name]}
143
- else
144
- val = Knj::Process_meta.args_parse(val)
145
- end
146
-
147
- newargs[key] = val
148
- end
149
-
150
- return newargs
151
- else
152
- return args
153
- end
154
- end
155
-
156
- #Parses the special hashes to reflect the natural objects instead of proxy-objects.
157
- def self.args_parse_back(args, objects)
158
- if args.is_a?(Array)
159
- newargs = []
160
- args.each do |val|
161
- newargs << Knj::Process_meta.args_parse_back(val, objects)
162
- end
163
-
164
- return newargs
165
- elsif args.is_a?(Hash) and args["type"] == "proxy_obj" and args.key?("var_name")
166
- raise "No object by that var-name: '#{args["var_name"]}' in '#{objects}'." if !objects.key?(args["var_name"])
167
- return objects[args["var_name"]]
168
- elsif args.is_a?(Hash)
169
- newargs = {}
170
- args.each do |key, val|
171
- newargs[Knj::Process_meta.args_parse_back(key, objects)] = Knj::Process_meta.args_parse_back(val, objects)
172
- end
173
-
174
- return newargs
175
- else
176
- return args
177
- end
178
- end
179
-
180
- #Executes a static call in the subprocess but does not capture or return the result. Useful if the static method returns an object that would load a library after being un-marshaled.
181
- def static_noret(const, method_name, *args, &block)
182
- res = @process.send(
183
- "obj" => {
184
- "type" => "static",
185
- "const" => const,
186
- "method_name" => method_name,
187
- "capture_return" => false,
188
- "args" => Knj::Process_meta.args_parse(args),
189
- },
190
- &block
191
- )
192
-
193
- return res["result"] if res["type"] == "call_const_success"
194
- raise "Unknown result: '#{res}'."
195
- end
196
-
197
- #Executes a static method on a class in the sub-process.
198
- def static(const, method_name, *args, &block)
199
- res = @process.send(
200
- "obj" => {
201
- "type" => "static",
202
- "const" => const,
203
- "method_name" => method_name,
204
- "capture_return" => true,
205
- "args" => Knj::Process_meta.args_parse(args),
206
- },
207
- &block
208
- )
209
-
210
- return res["result"] if res["type"] == "call_const_success"
211
- raise "Unknown result: '#{res}'."
212
- end
213
-
214
- #Spawns a new object in the subprocess by that classname, with those arguments and with that block.
215
- def new(class_name, *args, &block)
216
- #We need to check finalizers first, so we wont accidently reuse an ID, which will then be unset in the process.
217
- self.check_finalizers
218
-
219
- #Spawn and return the object.
220
- return self.spawn_object(class_name, nil, *args, &block)
221
- end
222
-
223
- #Spawns a new object in the subprocess and returns a proxy-variable for that subprocess-object.
224
- def spawn_object(class_name, var_name = nil, *args, &block)
225
- proxy_obj = Knj::Process_meta::Proxy_obj.new(:process_meta => self, :name => var_name)
226
-
227
- if var_name == nil
228
- var_name = proxy_obj.__id__
229
- proxy_obj._process_meta_args[:name] = var_name
230
- end
231
-
232
- res = @process.send(
233
- {
234
- "obj" => {
235
- "type" => "spawn_object",
236
- "class_name" => class_name,
237
- "var_name" => var_name,
238
- "args" => Knj::Process_meta.args_parse(args)
239
- }
240
- },
241
- &block
242
- )
243
-
244
- return proxy_obj
245
- end
246
-
247
- #Evaluates a string in the sub-process.
248
- def str_eval(str)
249
- res = @process.send("obj" => {
250
- "type" => "str_eval",
251
- "str" => str
252
- })
253
-
254
- return res["result"] if res.is_a?(Hash) and res["type"] == "call_eval_success"
255
- return "Unknown result: '#{res}'."
256
- end
257
-
258
- #Calls a method on an object and returns the result.
259
- def call_object(args, &block)
260
- if args.key?("capture_return")
261
- capture_return = args["capture_return"]
262
- else
263
- capture_return = true
264
- end
265
-
266
- if args["buffered"]
267
- type = "call_object_buffered"
268
- else
269
- type = "call_object_block"
270
- end
271
-
272
- res = @process.send(
273
- {
274
- "buffer_use" => args["buffer_use"],
275
- "obj" => {
276
- "type" => type,
277
- "var_name" => args["var_name"],
278
- "method_name" => args["method_name"],
279
- "capture_return" => capture_return,
280
- "args" => Knj::Process_meta.args_parse(args["args"])
281
- }
282
- },
283
- &block
284
- )
285
-
286
- return res["result"] if res.is_a?(Hash) and res["type"] == "call_object_success"
287
- raise "Unknown result: '#{res}'."
288
- end
289
-
290
- def proxy_from_eval(eval_str)
291
- proxy_obj = Knj::Process_meta::Proxy_obj.new(:process_meta => self)
292
- var_name = proxy_obj.__id__
293
- proxy_obj._process_meta_args[:name] = var_name
294
-
295
- res = @process.send(
296
- "obj" => {
297
- "type" => "proxy_from_eval",
298
- "str" => eval_str,
299
- "var_name" => var_name
300
- }
301
- )
302
-
303
- return proxy_obj
304
- end
305
-
306
- def proxy_from_static(class_name, method_name, *args)
307
- proxy_obj = Knj::Process_meta::Proxy_obj.new(:process_meta => self)
308
- var_name = proxy_obj.__id__
309
- proxy_obj._process_meta_args[:name] = var_name
310
-
311
- res = @process.send(
312
- "obj" => {
313
- "type" => "proxy_from_static",
314
- "const" => class_name,
315
- "method_name" => method_name,
316
- "var_name" => var_name,
317
- "args" => Knj::Process_meta.args_parse(args)
318
- }
319
- )
320
-
321
- return proxy_obj
322
- end
323
-
324
- #Returns a proxy-object to a object given from a call.
325
- def proxy_from_call(proxy_obj_to_call, method_name, *args)
326
- proxy_obj = Knj::Process_meta::Proxy_obj.new(:process_meta => self)
327
- var_name = proxy_obj.__id__
328
- proxy_obj._process_meta_args[:name] = var_name
329
-
330
- res = @process.send(
331
- "obj" => {
332
- "type" => "proxy_from_call",
333
- "proxy_obj" => proxy_obj_to_call.__id__,
334
- "method_name" => method_name,
335
- "var_name" => var_name,
336
- "args" => Knj::Process_meta.args_parse(args)
337
- }
338
- )
339
-
340
- return proxy_obj
341
- end
342
-
343
- #Returns true if the given name exists in the subprocess-objects-hash.
344
- def proxy_has?(var_name)
345
- self.check_finalizers
346
-
347
- begin
348
- res = @process.send(
349
- "obj" => {
350
- "type" => "call_object_block",
351
- "var_name" => var_name,
352
- "method_name" => "__id__",
353
- "args" => []
354
- }
355
- )
356
- rescue => e
357
- return false if e.message.to_s.match(/^No object by that name/)
358
- raise e
359
- end
360
-
361
- return true
362
- end
363
-
364
- #Destroyes the project and unsets all variables on the Process_meta-object.
365
- def destroy
366
- @process.send("obj" => {"type" => "exit"})
367
- @err_thread.kill if @err_thread
368
- @process.destroy
369
-
370
- begin
371
- Process.kill("TERM", @pid)
372
- rescue Errno::ESRCH
373
- #Process is already dead - ignore.
374
- end
375
-
376
- begin
377
- sleep 0.1
378
- process_exists = Knj::Unix_proc.list("pids" => [@pid])
379
- raise "Process exists." if !process_exists.empty?
380
- rescue => e
381
- raise e if e.message != "Process exists."
382
-
383
- begin
384
- Process.kill(9, pid) if process_exists
385
- rescue Errno::ESRCH => e
386
- raise e if e.message.index("No such process") == nil
387
- end
388
-
389
- #$stderr.print "Try to kill again...\n"
390
- #retry
391
- end
392
-
393
- @process = nil
394
- @stdin = nil
395
- @stdout = nil
396
- @stderr = nil
397
- @objects = nil
398
- @args = nil
399
- end
400
- end
401
-
402
- #This proxies all events to the sub-process.
403
- class Knj::Process_meta::Proxy_obj
404
- #Overwrite internal methods some truly simulate the sub-process-methods.
405
- proxy_methods = ["to_s", "respond_to?"]
406
- proxy_methods.each do |method_name|
407
- define_method(method_name) do |*args|
408
- return self.method_missing(method_name, *args)
409
- end
410
- end
411
-
412
- def initialize(args)
413
- @args = args
414
- @_process_meta_block_buffer_use = false
415
- ObjectSpace.define_finalizer(self, @args[:process_meta].method(:proxy_finalizer))
416
- end
417
-
418
- #This proxies all method-calls through the process-handeler and returns the result as the object was precent inside the current process-memory, even though it is not.
419
- def method_missing(method_name, *args, &block)
420
- raise "No arguments on the object?" if !@args
421
- @args[:process_meta].call_object(
422
- {
423
- "var_name" => @args[:name],
424
- "method_name" => method_name,
425
- "args" => args,
426
- "buffer_use" => @_process_meta_block_buffer_use
427
- },
428
- &block
429
- )
430
- end
431
-
432
- def _process_meta_unset
433
- @args[:process_meta].process.send("obj" => {"type" => "unset", "var_name" => @args[:name]})
434
- end
435
-
436
- def _process_meta_args
437
- return @args
438
- end
439
-
440
- def _process_meta_block_buffer_use=(newval)
441
- @_process_meta_block_buffer_use = newval
442
- end
443
-
444
- def _pm_send_noret(method_name, *args, &block)
445
- @args[:process_meta].call_object(
446
- {
447
- "var_name" => @args[:name],
448
- "method_name" => method_name,
449
- "args" => args,
450
- "buffer_use" => @_process_meta_block_buffer_use,
451
- "capture_return" => false
452
- },
453
- &block
454
- )
455
- end
456
-
457
- def _pm_buffered_caller(args)
458
- return Knj::Process_meta::Proxy_obj::Buffered_caller.new({
459
- :name => @args[:name],
460
- :process_meta => @args[:process_meta]
461
- }.merge(args))
462
- end
463
- end
464
-
465
- class Knj::Process_meta::Proxy_obj::Buffered_caller
466
- def initialize(args)
467
- @args = args
468
- @buffer = []
469
- @mutex = Mutex.new
470
- @mutex_write = Mutex.new
471
- @count = 0
472
- @debug = @args[:debug] if @args[:debug]
473
-
474
- if @args[:count_to]
475
- @count_to = @args[:count_to]
476
- else
477
- @count_to = 1000
478
- end
479
-
480
- @buffer_max = @count_to * 2
481
- @threads = [] if @args[:async]
482
- end
483
-
484
- def method_missing(method_name, *args)
485
- if method_name.to_s == @args[:method_name].to_s
486
- self._pm_call(*args)
487
- else
488
- raise NoMethodError, "No such method: '#{method_name}'."
489
- end
490
- end
491
-
492
- def _pm_call(*args)
493
- raise @raise_error if @raise_error
494
-
495
- @mutex.synchronize do
496
- while @count >= @count_to and @buffer.length >= @buffer_max
497
- STDOUT.print "Waiting for write to complete...\n" if @debug
498
- sleep 0.1
499
- end
500
-
501
- STDOUT.print "Adding to buffer #{@buffer.length}...\n" if @debug
502
- @buffer << args
503
- @count += 1
504
- end
505
-
506
- self._pm_flush if @count >= @count_to and !@writing
507
- return nil
508
- end
509
-
510
- def _pm_flush(*args)
511
- raise @raise_error if @raise_error
512
-
513
- buffer = nil
514
- @mutex.synchronize do
515
- buffer = @buffer
516
- @buffer = []
517
- @count = 0
518
- end
519
-
520
- if @args[:async]
521
- begin
522
- @threads << Thread.new do
523
- self._pm_flush_real(buffer)
524
- end
525
- rescue => e
526
- @raise_error = e
527
- end
528
-
529
- return nil
530
- else
531
- return self._pm_flush_real(buffer)
532
- end
533
- end
534
-
535
- def _pm_flush_real(buffer)
536
- @mutex_write.synchronize do
537
- STDOUT.print "Writing...\n" if @debug
538
- @writing = true
539
-
540
- begin
541
- return @args[:process_meta].call_object(
542
- "var_name" => @args[:name],
543
- "method_name" => @args[:method_name],
544
- "args" => buffer,
545
- "buffered" => true,
546
- "capture_return" => false
547
- )
548
- ensure
549
- @writing = false
550
- end
551
- end
552
- end
553
-
554
- def _pm_close
555
- self._pm_flush
556
-
557
- if @args[:async]
558
- threads_remove = []
559
- @threads.each do |thread|
560
- thread.join
561
- threads_remove << thread
562
- end
563
-
564
- @threads -= threads_remove
565
- end
566
-
567
- raise @raise_error if @raise_error
568
- end
569
- end