knjrbfw 0.0.7 → 0.0.8

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 (65) hide show
  1. data/Gemfile +3 -1
  2. data/VERSION +1 -1
  3. data/knjrbfw.gemspec +14 -4
  4. data/lib/knj/amixer.rb +148 -0
  5. data/lib/knj/arrayext.rb +14 -5
  6. data/lib/knj/autoload.rb +63 -57
  7. data/lib/knj/autoload/backups/facets_dictionary.rb +2 -2
  8. data/lib/knj/autoload/erubis.rb +2 -0
  9. data/lib/knj/cmd_gen.rb +71 -0
  10. data/lib/knj/compiler.rb +2 -2
  11. data/lib/knj/datarow.rb +138 -38
  12. data/lib/knj/datestamp.rb +2 -2
  13. data/lib/knj/datet.rb +72 -17
  14. data/lib/knj/erb/include.rb +5 -5
  15. data/lib/knj/errors.rb +4 -1
  16. data/lib/knj/eruby.rb +25 -11
  17. data/lib/knj/event_filemod.rb +27 -26
  18. data/lib/knj/event_handler.rb +8 -8
  19. data/lib/knj/exchangerates.rb +1 -1
  20. data/lib/knj/facebook_connect.rb +37 -0
  21. data/lib/knj/gettext_threadded.rb +4 -3
  22. data/lib/knj/google_sitemap.rb +1 -1
  23. data/lib/knj/hash_methods.rb +1 -1
  24. data/lib/knj/http.rb +35 -19
  25. data/lib/knj/http2.rb +249 -0
  26. data/lib/knj/image.rb +128 -0
  27. data/lib/knj/jruby-gtk2/gtk2.rb +1 -1
  28. data/lib/knj/knj.rb +1 -1
  29. data/lib/knj/knj_controller.rb +0 -2
  30. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +3 -3
  31. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +11 -11
  32. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +2 -2
  33. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +71 -14
  34. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +17 -14
  35. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +5 -5
  36. data/lib/knj/knjdb/libknjdb.rb +33 -16
  37. data/lib/knj/knjdb/libknjdb_row.rb +8 -8
  38. data/lib/knj/maemo/fremantle-calendar/fremantle-calendar.rb +1 -1
  39. data/lib/knj/mount.rb +6 -6
  40. data/lib/knj/mutexcl.rb +2 -2
  41. data/lib/knj/objects.rb +286 -73
  42. data/lib/knj/opts.rb +11 -4
  43. data/lib/knj/os.rb +16 -3
  44. data/lib/knj/php.rb +73 -26
  45. data/lib/knj/php_parser/php_parser.rb +1 -77
  46. data/lib/knj/retry.rb +4 -4
  47. data/lib/knj/rhodes/rhodes.rb +106 -0
  48. data/lib/knj/sshrobot/sshrobot.rb +1 -1
  49. data/lib/knj/strings.rb +72 -0
  50. data/lib/knj/sysuser.rb +1 -1
  51. data/lib/knj/tests/test_http2.rb +18 -0
  52. data/lib/knj/thread.rb +1 -5
  53. data/lib/knj/thread2.rb +3 -3
  54. data/lib/knj/threadhandler.rb +2 -2
  55. data/lib/knj/threadpool.rb +4 -4
  56. data/lib/knj/translations.rb +2 -17
  57. data/lib/knj/unix_proc.rb +3 -3
  58. data/lib/knj/web.rb +156 -77
  59. data/lib/knj/webscripts/image.rhtml +22 -3
  60. data/lib/knj/x11vnc.rb +3 -3
  61. data/spec/amixer_spec.rb +27 -0
  62. data/spec/knjrbfw_spec.rb +70 -12
  63. data/testfiles/image.jpg +0 -0
  64. metadata +32 -14
  65. data/Gemfile.lock +0 -32
@@ -1,7 +1,7 @@
1
1
  class Knj::Mutexcl
2
2
  def initialize(args = {})
3
3
  @args = args
4
- raise "No ':modes' given in arguments." if !@args.has_key?(:modes)
4
+ raise "No ':modes' given in arguments." if !@args.key?(:modes)
5
5
  @mutex = Mutex.new
6
6
  @blocked = {}
7
7
  @args[:modes].each do |mode, data|
@@ -24,7 +24,7 @@ class Knj::Mutexcl
24
24
  end
25
25
 
26
26
  def sync(mode)
27
- raise "No such mode: '#{mode}'." if !@args[:modes].has_key?(mode)
27
+ raise "No such mode: '#{mode}'." if !@args[:modes].key?(mode)
28
28
 
29
29
  while @blocked[mode][:count].to_i > 0
30
30
  STDOUT.print "Sleeping because blocked '#{mode}' (#{@blocked[mode][:count]}).\n"
@@ -1,5 +1,5 @@
1
1
  class Knj::Objects
2
- attr_reader :args, :events
2
+ attr_reader :args, :events, :data
3
3
 
4
4
  def initialize(args)
5
5
  @callbacks = {}
@@ -7,7 +7,11 @@ class Knj::Objects
7
7
  @args[:col_id] = :id if !@args[:col_id]
8
8
  @args[:class_pre] = "class_" if !@args[:class_pre]
9
9
  @args[:module] = Kernel if !@args[:module]
10
+ @args[:cache] = :weak if !@args.key?(:cache)
10
11
  @objects = {}
12
+ @data = {}
13
+
14
+ require "weakref" if @args[:cache] == :weak
11
15
 
12
16
  @events = Knj::Event_handler.new
13
17
  @events.add_event(
@@ -20,11 +24,30 @@ class Knj::Objects
20
24
  )
21
25
 
22
26
  raise "No DB given." if !@args[:db]
23
- raise "No class path given." if !@args[:class_path] and (@args[:require] or !@args.has_key?(:require))
27
+ raise "No class path given." if !@args[:class_path] and (@args[:require] or !@args.key?(:require))
28
+
29
+ if args[:require_all]
30
+ loads = []
31
+
32
+ Dir.foreach(@args[:class_path]) do |file|
33
+ next if file == "." or file == ".." or !file.match(/\.rb$/)
34
+ file_parsed = file
35
+ file_parsed.gsub!(@args[:class_pre], "") if @args.key?(:class_pre)
36
+ file_parsed.gsub!(/\.rb$/, "")
37
+ file_parsed = Knj::Php.ucwords(file_parsed)
38
+
39
+ loads << file_parsed
40
+ self.requireclass(file_parsed, {:load => false})
41
+ end
42
+
43
+ loads.each do |load_class|
44
+ self.load_class(load_class)
45
+ end
46
+ end
24
47
  end
25
48
 
26
49
  def init_class(classname)
27
- return false if @objects.has_key?(classname)
50
+ return false if @objects.key?(classname)
28
51
  @objects[classname] = {}
29
52
  end
30
53
 
@@ -54,7 +77,7 @@ class Knj::Objects
54
77
 
55
78
  def connect(args, &block)
56
79
  raise "No object given." if !args["object"]
57
- raise "No signals given." if !args.has_key?("signal") and !args.has_key?("signals")
80
+ raise "No signals given." if !args.key?("signal") and !args.key?("signals")
58
81
  args["block"] = block if block_given?
59
82
  @callbacks[args["object"]] = {} if !@callbacks[args["object"]]
60
83
  conn_id = @callbacks[args["object"]].length.to_s
@@ -64,11 +87,11 @@ class Knj::Objects
64
87
  def call(args, &block)
65
88
  classstr = args["object"].class.to_s
66
89
 
67
- if @callbacks[classstr]
90
+ if @callbacks.key?(classstr)
68
91
  @callbacks[classstr].clone.each do |callback_key, callback|
69
92
  docall = false
70
93
 
71
- if callback.has_key?("signal") and args.has_key?("signal") and callback["signal"] == args["signal"]
94
+ if callback.key?("signal") and args.key?("signal") and callback["signal"] == args["signal"]
72
95
  docall = true
73
96
  elsif callback["signals"] and args["signal"] and callback["signals"].index(args["signal"]) != nil
74
97
  docall = true
@@ -97,52 +120,103 @@ class Knj::Objects
97
120
  end
98
121
  end
99
122
 
100
- def requireclass(classname)
123
+ def requireclass(classname, args = {})
101
124
  classname = classname.to_sym
102
125
 
103
- if !@args[:require] and @args.has_key?(:require)
104
- @objects[classname] = {} if !@objects.has_key?(classname)
105
- return nil
106
- end
107
-
108
- if !@objects.has_key?(classname)
109
- filename = @args[:class_path] + "/#{@args[:class_pre]}#{classname.downcase}.rb"
110
- filename_req = @args[:class_path] + "/#{@args[:class_pre]}#{classname.downcase}"
111
- raise "Class file could not be found: #{filename}." if !File.exists?(filename)
112
- require filename_req
113
- @args[:module].const_get(classname).load_columns(Knj::Hash_methods.new(:args => args, :ob => self, :db => @args[:db]))
126
+ if !@objects.key?(classname)
127
+ if (@args[:require] or !@args.key?(:require)) and (!args.key?(:require) or args[:require])
128
+ filename = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}.rb"
129
+ filename_req = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}"
130
+ raise "Class file could not be found: #{filename}." if !File.exists?(filename)
131
+ require filename_req
132
+ end
133
+
134
+ if args[:class]
135
+ classob = args[:class]
136
+ else
137
+ classob = @args[:module].const_get(classname)
138
+ end
139
+
140
+ if (classob.respond_to?(:load_columns) or classob.respond_to?(:datarow_init)) and (!args.key?(:load) or args[:load])
141
+ self.load_class(classname, args)
142
+ end
143
+
114
144
  @objects[classname] = {}
115
145
  end
116
146
  end
117
147
 
148
+ def load_class(classname, args = {})
149
+ if args[:class]
150
+ classob = args[:class]
151
+ else
152
+ classob = @args[:module].const_get(classname)
153
+ end
154
+
155
+ pass_arg = Knj::Hash_methods.new(:ob => self, :db => @args[:db])
156
+ classob.load_columns(pass_arg) if classob.respond_to?(:load_columns)
157
+ classob.datarow_init(pass_arg) if classob.respond_to?(:datarow_init)
158
+ end
159
+
118
160
  def get(classname, data)
119
161
  classname = classname.to_sym
120
162
 
121
- if data.is_a?(Hash) and data[@args[:col_id].to_sym]
163
+ if data.is_a?(Integer) or data.is_a?(String) or data.is_a?(Fixnum)
164
+ id = data.to_i
165
+ elsif data.is_a?(Hash) and data[@args[:col_id].to_sym]
122
166
  id = data[@args[:col_id].to_sym].to_i
123
167
  elsif data.is_a?(Hash) and data[@args[:col_id].to_s]
124
168
  id = data[@args[:col_id].to_s].to_i
125
- elsif data.is_a?(Integer) or data.is_a?(String) or data.is_a?(Fixnum)
126
- id = data.to_i
127
169
  elsif
128
170
  raise Knj::Errors::InvalidData, "Unknown data: '#{data.class.to_s}'."
129
171
  end
130
172
 
131
- return @objects[classname][id] if @objects.has_key?(classname) and @objects[classname].has_key?(id)
132
- self.requireclass(classname) if !@objects.has_key?(classname)
173
+ if @objects.key?(classname) and @objects[classname].key?(id)
174
+ case @args[:cache]
175
+ when :weak
176
+ begin
177
+ obj = @objects[classname][id]
178
+ obj = obj.__getobj__ if obj.is_a?(WeakRef)
179
+
180
+ #This actually happens sometimes... WTF!? - knj
181
+ if obj.is_a?(Knj::Datarow) and obj.respond_to?(:table) and obj.respond_to?(:id) and obj.table.to_sym == classname and obj.id.to_i == id
182
+ return obj
183
+ else
184
+ raise WeakRef::RefError
185
+ end
186
+ rescue WeakRef::RefError
187
+ @objects[classname].delete(id)
188
+ end
189
+ else
190
+ return @objects[classname][id]
191
+ end
192
+ end
193
+
194
+ self.requireclass(classname) if !@objects.key?(classname)
133
195
 
134
196
  if @args[:datarow]
135
- @objects[classname][id] = @args[:module].const_get(classname).new(Knj::Hash_methods.new(
136
- :ob => self,
137
- :data => data
138
- ))
197
+ obj = @args[:module].const_get(classname).new(Knj::Hash_methods.new(:ob => self, :data => data))
139
198
  else
140
199
  args = [data]
141
200
  args = args | @args[:extra_args] if @args[:extra_args]
142
- @objects[classname][id] = @args[:module].const_get(classname).new(*args)
201
+ obj = @args[:module].const_get(classname).new(*args)
143
202
  end
144
203
 
145
- return @objects[classname][id]
204
+ case @args[:cache]
205
+ when :weak
206
+ @objects[classname][id] = WeakRef.new(obj)
207
+ else
208
+ @objects[classname][id] = obj
209
+ end
210
+
211
+ return obj
212
+ end
213
+
214
+ def object_finalizer(id)
215
+ classname = @objects_idclass[id]
216
+ if classname
217
+ @objects[classname].delete(id)
218
+ @objects_idclass.delete(id)
219
+ end
146
220
  end
147
221
 
148
222
  def get_by(classname, args = {})
@@ -245,9 +319,9 @@ class Knj::Objects
245
319
  elsif object.respond_to?(:data)
246
320
  obj_data = object.data
247
321
 
248
- if obj_data.has_key?(:name)
322
+ if obj_data.key?(:name)
249
323
  objhtml = obj_data[:name]
250
- elsif obj_data.has_key?(:title)
324
+ elsif obj_data.key?(:title)
251
325
  objhtml = obj_data[:title]
252
326
  end
253
327
  else
@@ -333,7 +407,7 @@ class Knj::Objects
333
407
 
334
408
  required_data = classobj.required_data
335
409
  required_data.each do |req_data|
336
- if !data.has_key?(req_data[:col])
410
+ if !data.key?(req_data[:col])
337
411
  raise "No '#{req_data[:class]}' given by the data '#{req_data[:col]}'."
338
412
  end
339
413
 
@@ -419,9 +493,9 @@ class Knj::Objects
419
493
 
420
494
  classname = classname.to_sym
421
495
 
422
- #if !@objects.has_key?(classname)
496
+ #if !@objects.key?(classname)
423
497
  #raise "Could not find object class in cache: #{classname}."
424
- #elsif !@objects[classname].has_key?(object.id.to_i)
498
+ #elsif !@objects[classname].key?(object.id.to_i)
425
499
  #errstr = ""
426
500
  #errstr += "Could not unset object from cache.\n"
427
501
  #errstr += "Class: #{object.class.name}.\n"
@@ -444,7 +518,7 @@ class Knj::Objects
444
518
 
445
519
  classname = classname.to_sym
446
520
 
447
- return false if !@objects.has_key?(classname)
521
+ return false if !@objects.key?(classname)
448
522
  @objects[classname] = {}
449
523
  end
450
524
 
@@ -497,18 +571,22 @@ class Knj::Objects
497
571
 
498
572
  # Try to clean up objects by unsetting everything, start the garbagecollector, get all the remaining objects via ObjectSpace and set them again. Some (if not all) should be cleaned up and our cache should still be safe... dirty but works.
499
573
  def clean(classn)
574
+ return false if @args[:cache] == :weak
575
+
500
576
  if classn.is_a?(Array)
501
577
  classn.each do |realclassn|
502
578
  self.clean(realclassn)
503
579
  end
504
580
  else
505
- return false if !@objects.has_key?(classn)
581
+ return false if !@objects.key?(classn)
506
582
  @objects[classn] = {}
507
583
  GC.start
508
584
  end
509
585
  end
510
586
 
511
587
  def clean_all
588
+ return false if @args[:cache] == :weak
589
+
512
590
  classnames = []
513
591
  @objects.keys.each do |classn|
514
592
  classnames << classn
@@ -522,55 +600,65 @@ class Knj::Objects
522
600
  end
523
601
 
524
602
  def clean_recover
603
+ return false if @args[:cache] == :weak
604
+ return false if RUBY_ENGINE == "jruby" and !JRuby.objectspace
605
+
525
606
  @objects.keys.each do |classn|
526
607
  data = @objects[classn]
527
- classobj = Kernel.const_get(classn)
608
+ classobj = @args[:module].const_get(classn)
528
609
  ObjectSpace.each_object(classobj) do |obj|
529
- data[obj.id] = obj
610
+ begin
611
+ data[obj.id.to_i] = obj
612
+ rescue => e
613
+ if e.message == "No data on object."
614
+ #Object has been unset - skip it.
615
+ next
616
+ end
617
+
618
+ raise e
619
+ end
530
620
  end
531
621
  end
532
622
  end
533
623
 
534
- def sqlhelper(list_args, args)
624
+ def sqlhelper(list_args, args_def)
535
625
  if args[:db]
536
626
  db = args[:db]
537
627
  else
538
628
  db = @args[:db]
539
629
  end
540
630
 
631
+ args = args_def
632
+
541
633
  if args[:table]
542
- table = "`#{db.esc_table(args[:table])}`."
634
+ table_def = "`#{db.esc_table(args[:table])}`."
543
635
  else
544
- table = ""
636
+ table_def = ""
545
637
  end
546
638
 
639
+ sql_joins = ""
547
640
  sql_where = ""
548
641
  sql_order = ""
549
642
  sql_limit = ""
550
643
 
644
+ do_joins = {}
645
+
551
646
  limit_from = nil
552
647
  limit_to = nil
553
648
 
554
- cols_str_has = args.has_key?(:cols_str)
555
- cols_num_has = args.has_key?(:cols_num)
556
- cols_date_has = args.has_key?(:cols_date)
557
- cols_dbrows_has = args.has_key?(:cols_dbrows)
558
- cols_bools_has = args.has_key?(:cols_bools)
559
-
560
- if list_args.has_key?("orderby")
649
+ if list_args.key?("orderby")
561
650
  orders = []
562
651
  orderstr = list_args["orderby"]
652
+ list_args["orderby"] = [list_args["orderby"]] if list_args["orderby"].is_a?(Hash)
563
653
 
564
654
  if list_args["orderby"].is_a?(String)
565
655
  found = false
566
- found = true if !found and cols_str_has and args[:cols_str].index(orderstr) != nil
567
- found = true if !found and cols_date_has and args[:cols_date].index(orderstr) != nil
568
- found = true if !found and cols_num_has and args[:cols_num].index(orderstr) != nil
656
+ found = true if args[:cols].key?(orderstr)
569
657
 
570
658
  if found
571
659
  sql_order += " ORDER BY "
572
660
  ordermode = " ASC"
573
- if list_args.has_key?("ordermode")
661
+ if list_args.key?("ordermode")
574
662
  if list_args["ordermode"] == "desc"
575
663
  ordermode = " DESC"
576
664
  elsif list_args["ordermode"] == "asc"
@@ -581,16 +669,20 @@ class Knj::Objects
581
669
  list_args.delete("ordermode")
582
670
  end
583
671
 
584
- sql_order += "#{table}`#{db.esc_col(list_args["orderby"])}`#{ordermode}"
672
+ sql_order += "#{table_def}`#{db.esc_col(list_args["orderby"])}`#{ordermode}"
585
673
  list_args.delete("orderby")
586
674
  end
587
675
  elsif list_args["orderby"].is_a?(Array)
588
676
  sql_order += " ORDER BY "
589
677
 
590
678
  list_args["orderby"].each do |val|
679
+ ordermode = nil
680
+ orderstr = nil
681
+ found = false
682
+
591
683
  if val.is_a?(Array)
592
684
  orderstr = val[0]
593
-
685
+
594
686
  if val[1] == "asc"
595
687
  ordermode = " ASC"
596
688
  elsif val[1] == "desc"
@@ -599,18 +691,32 @@ class Knj::Objects
599
691
  elsif val.is_a?(String)
600
692
  orderstr = val
601
693
  ordermode = " ASC"
694
+ elsif val.is_a?(Hash)
695
+ raise "No joined tables." if !args.key?(:joined_tables)
696
+
697
+ if val[:mode] == "asc"
698
+ ordermode = " ASC"
699
+ elsif val[:mode] == "desc"
700
+ ordermode = " DESC"
701
+ end
702
+
703
+ if args[:joined_tables]
704
+ args[:joined_tables].each do |table_name, table_data|
705
+ if table_name.to_s == val[:table]
706
+ do_joins[table_name] = true
707
+ orders << "`#{db.esc_table(table_name)}`.`#{db.esc_col(val[:col])}`#{ordermode}"
708
+ found = true
709
+ break
710
+ end
711
+ end
712
+ end
602
713
  else
603
714
  raise "Unknown object: #{val.class.name}"
604
715
  end
605
716
 
606
- found = false
607
- found = true if !found and cols_str_has and args[:cols_str].index(orderstr) != nil
608
- found = true if !found and cols_date_has and args[:cols_date].index(orderstr) != nil
609
- found = true if !found and cols_num_has and args[:cols_num].index(orderstr) != nil
610
- found = true if !found and cols_bools_has and args[:cols_bools].index(orderstr) != nil
611
-
717
+ found = true if args[:cols].key?(orderstr)
612
718
  raise "Column not found for ordering: #{orderstr}." if !found
613
- orders << "#{table}`#{db.esc_col(orderstr)}`#{ordermode}"
719
+ orders << "#{table_def}`#{db.esc_col(orderstr)}`#{ordermode}" if orderstr
614
720
  end
615
721
 
616
722
  sql_order += orders.join(", ")
@@ -620,10 +726,27 @@ class Knj::Objects
620
726
  end
621
727
  end
622
728
 
623
- list_args.each do |key, val|
729
+ list_args.each do |realkey, val|
624
730
  found = false
625
731
 
626
- if (cols_str_has and args[:cols_str].index(key) != nil) or (cols_num_has and args[:cols_num].index(key) != nil) or (cols_dbrows_has and args[:cols_dbrows].index(key) != nil)
732
+ if realkey.is_a?(Array)
733
+ if !args[:joins_skip]
734
+ datarow_obj = self.datarow_obj_from_args(args_def, list_args, realkey[0])
735
+ args = datarow_obj.columns_sqlhelper_args
736
+ else
737
+ args = args_def
738
+ end
739
+
740
+ do_joins[realkey[0].to_sym] = true
741
+ table = "`#{db.esc_table(realkey[0])}`."
742
+ key = realkey[1]
743
+ else
744
+ table = table_def
745
+ args = args_def
746
+ key = realkey
747
+ end
748
+
749
+ if args[:cols].key?(key)
627
750
  if val.is_a?(Array)
628
751
  escape_sql = Knj::ArrayExt.join(
629
752
  :arr => val,
@@ -633,12 +756,23 @@ class Knj::Objects
633
756
  :sep => ",",
634
757
  :surr => "'")
635
758
  sql_where += " AND #{table}`#{db.esc_col(key)}` IN (#{escape_sql})"
759
+ elsif val.is_a?(Hash) and val[:type] == "col"
760
+ if !val.key?(:table)
761
+ Knj::Php.print_r(val)
762
+ raise "No table was given for join."
763
+ end
764
+
765
+ do_joins[val[:table].to_sym] = true
766
+ sql_where += " AND #{table}`#{db.esc_col(key)}` = `#{db.esc_table(val[:table])}`.`#{db.esc_col(val[:name])}`"
767
+ elsif val.is_a?(Proc)
768
+ call_args = Knj::Hash_methods.new(:ob => self, :db => db)
769
+ sql_where += " AND #{table}`#{db.esc_col(key)}` = '#{db.esc(val.call(call_args))}'"
636
770
  else
637
771
  sql_where += " AND #{table}`#{db.esc_col(key)}` = '#{db.esc(val)}'"
638
772
  end
639
773
 
640
774
  found = true
641
- elsif cols_bools_has and args[:cols_bools].index(key) != nil
775
+ elsif args.key?(:cols_bools) and args[:cols_bools].index(key) != nil
642
776
  if val.is_a?(TrueClass) or (val.is_a?(Integer) and val.to_i == 1) or (val.is_a?(String) and (val == "true" or val == "1"))
643
777
  realval = "1"
644
778
  elsif val.is_a?(FalseClass) or (val.is_a?(Integer) and val.to_i == 0) or (val.is_a?(String) and (val == "false" or val == "0"))
@@ -659,10 +793,10 @@ class Knj::Objects
659
793
  limit_from = 0
660
794
  limit_to = val.to_i
661
795
  found = true
662
- elsif cols_dbrows_has and args[:cols_dbrows].index(key.to_s + "_id") != nil
796
+ elsif args.key?(:cols_dbrows) and args[:cols_dbrows].index("#{key.to_s}_id") != nil
663
797
  sql_where += " AND #{table}`#{db.esc_col(key.to_s + "_id")}` = '#{db.esc(val.id)}'"
664
798
  found = true
665
- elsif cols_str_has and match = key.match(/^([A-z_\d]+)_(search|has)$/) and args[:cols_str].index(match[1]) != nil
799
+ elsif args.key?(:cols_str) and match = key.match(/^([A-z_\d]+)_(search|has)$/) and args[:cols_str].index(match[1]) != nil
666
800
  if match[2] == "search"
667
801
  Knj::Strings.searchstring(val).each do |str|
668
802
  sql_where += " AND #{table}`#{db.esc_col(match[1])}` LIKE '%#{db.esc(str)}%'"
@@ -676,24 +810,33 @@ class Knj::Objects
676
810
  end
677
811
 
678
812
  found = true
679
- elsif match = key.match(/^([A-z_\d]+)_not$/) and ((cols_str_has and args[:cols_str].index(match[1]) != nil) or (cols_num_has and args[:cols_num].index(match[1]) != nil))
680
- sql_where += " AND #{table}`#{db.esc_col(match[1])}` != '#{db.esc(val)}'"
813
+ elsif match = key.match(/^([A-z_\d]+)_(not|lower)$/) and args[:cols].key?(match[1])
814
+ if match[2] == "not"
815
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` != '#{db.esc(val)}'"
816
+ elsif match[2] == "lower"
817
+ sql_where += " AND LOWER(#{table}`#{db.esc_col(match[1])}`) = LOWER('#{db.esc(val)}')"
818
+ else
819
+ raise "Unknown mode: '#{match[2]}'."
820
+ end
821
+
681
822
  found = true
682
- elsif cols_date_has and match = key.match(/^(.+)_(day|month|from|to)$/) and args[:cols_date].index(match[1]) != nil
823
+ elsif args.key?(:cols_date) and match = key.match(/^(.+)_(day|month|from|to|below|above)$/) and args[:cols_date].index(match[1]) != nil
824
+ val = Knj::Datet.in(val) if val.is_a?(Time)
825
+
683
826
  if match[2] == "day"
684
827
  sql_where += " AND DATE_FORMAT(#{table}`#{db.esc_col(match[1])}`, '%d %m %Y') = DATE_FORMAT('#{db.esc(val.dbstr)}', '%d %m %Y')"
685
828
  elsif match[2] == "month"
686
829
  sql_where += " AND DATE_FORMAT(#{table}`#{db.esc_col(match[1])}`, '%m %Y') = DATE_FORMAT('#{db.esc(val.dbstr)}', '%m %Y')"
687
- elsif match[2] == "from"
830
+ elsif match[2] == "from" or match[2] == "above"
688
831
  sql_where += " AND #{table}`#{db.esc_col(match[1])}` >= '#{db.esc(val.dbstr)}'"
689
- elsif match[2] == "to"
832
+ elsif match[2] == "to" or match[2] == "below"
690
833
  sql_where += " AND #{table}`#{db.esc_col(match[1])}` <= '#{db.esc(val.dbstr)}'"
691
834
  else
692
835
  raise "Unknown date-key: #{match[2]}."
693
836
  end
694
837
 
695
838
  found = true
696
- elsif cols_num_has and match = key.match(/^(.+)_(from|to)$/) and args[:cols_num].index(match[1]) != nil
839
+ elsif args.key?(:cols_num) and match = key.match(/^(.+)_(from|to)$/) and args[:cols_num].index(match[1]) != nil
697
840
  if match[2] == "from"
698
841
  sql_where += " AND #{table}`#{db.esc_col(match[1])}` <= '#{db.esc(val)}'"
699
842
  elsif match[2] == "to"
@@ -703,19 +846,89 @@ class Knj::Objects
703
846
  end
704
847
 
705
848
  found = true
849
+ elsif match = key.match(/^(.+)_lookup$/) and args[:cols].key?("#{match[1]}_id") and args[:cols].key?("#{match[1]}_class")
850
+ sql_where += " AND #{table}`#{db.esc_col("#{match[1]}_class")}` = '#{db.esc(val.table)}'"
851
+ sql_where += " AND #{table}`#{db.esc_col("#{match[1]}_id")}` = '#{db.esc(val.id)}'"
852
+ found = true
706
853
  end
707
854
 
708
- list_args.delete(key) if found
855
+ list_args.delete(realkey) if found
709
856
  end
710
857
 
858
+ args = args_def
859
+
860
+ if !args[:joins_skip]
861
+ raise "No joins defined on '#{args[:table]}' for: '#{args[:table]}'." if !do_joins.empty? and !args[:joined_tables]
862
+
863
+ do_joins.each do |table_name, temp_val|
864
+ raise "No join defined on table '#{args[:table]}' for table '#{table_name}'." if !args[:joined_tables].key?(table_name)
865
+ table_data = args[:joined_tables][table_name]
866
+
867
+ if table_data.key?(:parent_table)
868
+ sql_joins += " LEFT JOIN `#{table_data[:parent_table]}` AS `#{table_name}` ON 1=1"
869
+ else
870
+ sql_joins += " LEFT JOIN `#{table_name}` ON 1=1"
871
+ end
872
+
873
+ if table_data[:ob]
874
+ ob = table_data[:ob]
875
+ else
876
+ ob = self
877
+ end
878
+
879
+ class_name = args[:table].to_sym
880
+
881
+ if table_data[:datarow]
882
+ datarow = table_data[:datarow]
883
+ else
884
+ self.requireclass(class_name) if @objects.key?(class_name)
885
+ datarow = @args[:module].const_get(class_name)
886
+ end
887
+
888
+ if !datarow.columns_sqlhelper_args
889
+ ob.requireclass(datarow.table.to_sym)
890
+ raise "No SQL-helper-args on class '#{datarow.table}' ???" if !datarow.columns_sqlhelper_args
891
+ end
892
+
893
+ newargs = datarow.columns_sqlhelper_args.clone
894
+ newargs[:table] = table_name
895
+ newargs[:joins_skip] = true
896
+
897
+ ret = self.sqlhelper(table_data[:where].clone, newargs)
898
+ sql_joins += ret[:sql_where]
899
+ end
900
+ end
901
+
711
902
  if limit_from and limit_to
712
903
  sql_limit = " LIMIT #{limit_from}, #{limit_to}"
713
904
  end
714
905
 
715
906
  return {
907
+ :sql_joins => sql_joins,
716
908
  :sql_where => sql_where,
717
909
  :sql_limit => sql_limit,
718
910
  :sql_order => sql_order
719
911
  }
720
912
  end
913
+
914
+ def datarow_obj_from_args(args, list_args, class_name)
915
+ class_name = class_name.to_sym
916
+
917
+ if !args.key?(:joined_tables)
918
+ Knj::Php.print_r(list_args)
919
+ Knj::Php.print_r(args)
920
+ raise "No joined tables on '#{args[:table]}' to find datarow for: '#{class_name}'."
921
+ end
922
+
923
+ args[:joined_tables].each do |table_name, table_data|
924
+ next if table_name.to_sym != class_name
925
+
926
+ return table_data[:datarow] if table_data[:datarow]
927
+
928
+ self.requireclass(class_name) if @objects.key?(class_name)
929
+ return @args[:module].const_get(class_name)
930
+ end
931
+
932
+ raise "Could not figure out datarow for: '#{class_name}'."
933
+ end
721
934
  end