knjrbfw 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. data/VERSION +1 -1
  2. data/knjrbfw.gemspec +29 -8
  3. data/lib/knj/arrayext.rb +206 -153
  4. data/lib/knj/autoload/backups/ping.rb +2 -2
  5. data/lib/knj/autoload/erubis.rb +3 -3
  6. data/lib/knj/autoload/facets_dictionary.rb +2 -2
  7. data/lib/knj/autoload/gettext.rb +3 -3
  8. data/lib/knj/autoload/gtk2.rb +1 -1
  9. data/lib/knj/autoload/json.rb +14 -0
  10. data/lib/knj/autoload/magick.rb +3 -3
  11. data/lib/knj/autoload/mysql.rb +3 -3
  12. data/lib/knj/autoload/parsedate.rb +1 -1
  13. data/lib/knj/autoload/ping.rb +2 -2
  14. data/lib/knj/autoload/rexml.rb +5 -5
  15. data/lib/knj/autoload/soap.rb +1 -1
  16. data/lib/knj/autoload/sqlite3.rb +3 -3
  17. data/lib/knj/autoload/tmail.rb +3 -3
  18. data/lib/knj/autoload/xmlsimple.rb +3 -3
  19. data/lib/knj/autoload/zip.rb +3 -3
  20. data/lib/knj/autoload.rb +87 -81
  21. data/lib/knj/cmd_gen.rb +19 -19
  22. data/lib/knj/cmd_parser.rb +59 -0
  23. data/lib/knj/compiler.rb +34 -34
  24. data/lib/knj/cpufreq.rb +37 -37
  25. data/lib/knj/csv.rb +20 -0
  26. data/lib/knj/datarow.rb +406 -239
  27. data/lib/knj/datarow_custom.rb +124 -0
  28. data/lib/knj/datestamp.rb +89 -89
  29. data/lib/knj/datet.rb +550 -454
  30. data/lib/knj/db.rb +1 -0
  31. data/lib/knj/degulesider.rb +42 -44
  32. data/lib/knj/erb/erb.rb +5 -5
  33. data/lib/knj/erb/erb_cache_clean.rb +10 -10
  34. data/lib/knj/erb/erb_fcgi.rb +32 -32
  35. data/lib/knj/erb/erb_fcgi_1.9.rb +32 -32
  36. data/lib/knj/erb/erb_fcgi_jruby.rb +2 -2
  37. data/lib/knj/erb/erb_jruby.rb +5 -5
  38. data/lib/knj/erb/include.rb +243 -243
  39. data/lib/knj/errors.rb +19 -18
  40. data/lib/knj/eruby.rb +12 -10
  41. data/lib/knj/event_filemod.rb +31 -31
  42. data/lib/knj/event_handler.rb +73 -67
  43. data/lib/knj/exchangerates.rb +37 -37
  44. data/lib/knj/facebook_connect.rb +95 -18
  45. data/lib/knj/filesystem.rb +6 -6
  46. data/lib/knj/fs/drivers/filesystem.rb +12 -12
  47. data/lib/knj/fs/drivers/ftp.rb +31 -31
  48. data/lib/knj/fs/drivers/ssh.rb +26 -26
  49. data/lib/knj/fs/fs.rb +31 -31
  50. data/lib/knj/gettext_fallback.rb +15 -15
  51. data/lib/knj/gettext_threadded.rb +75 -75
  52. data/lib/knj/google_sitemap.rb +53 -53
  53. data/lib/knj/gtk2.rb +272 -272
  54. data/lib/knj/gtk2_cb.rb +80 -80
  55. data/lib/knj/gtk2_menu.rb +55 -55
  56. data/lib/knj/gtk2_statuswindow.rb +62 -62
  57. data/lib/knj/gtk2_tv.rb +58 -58
  58. data/lib/knj/hash_methods.rb +27 -36
  59. data/lib/knj/http.rb +189 -167
  60. data/lib/knj/http2.rb +259 -53
  61. data/lib/knj/image.rb +2 -2
  62. data/lib/knj/includes/appserver_cli.rb +18 -18
  63. data/lib/knj/includes/require_info.rb +15 -0
  64. data/lib/knj/ip2location.rb +20 -20
  65. data/lib/knj/ironruby-gtk2/button.rb +14 -14
  66. data/lib/knj/ironruby-gtk2/dialog.rb +42 -42
  67. data/lib/knj/ironruby-gtk2/entry.rb +4 -4
  68. data/lib/knj/ironruby-gtk2/gdk_event.rb +1 -1
  69. data/lib/knj/ironruby-gtk2/gdk_eventbutton.rb +11 -11
  70. data/lib/knj/ironruby-gtk2/gdk_pixbuf.rb +9 -9
  71. data/lib/knj/ironruby-gtk2/gladexml.rb +102 -102
  72. data/lib/knj/ironruby-gtk2/glib.rb +13 -13
  73. data/lib/knj/ironruby-gtk2/gtk2.rb +121 -121
  74. data/lib/knj/ironruby-gtk2/gtk_builder.rb +29 -29
  75. data/lib/knj/ironruby-gtk2/gtk_cellrenderertext.rb +3 -3
  76. data/lib/knj/ironruby-gtk2/gtk_combobox.rb +17 -17
  77. data/lib/knj/ironruby-gtk2/gtk_filechooserbutton.rb +3 -3
  78. data/lib/knj/ironruby-gtk2/gtk_liststore.rb +16 -16
  79. data/lib/knj/ironruby-gtk2/gtk_menu.rb +3 -3
  80. data/lib/knj/ironruby-gtk2/gtk_menuitem.rb +2 -2
  81. data/lib/knj/ironruby-gtk2/gtk_statusicon.rb +3 -3
  82. data/lib/knj/ironruby-gtk2/gtk_treeiter.rb +22 -22
  83. data/lib/knj/ironruby-gtk2/gtk_treeselection.rb +11 -11
  84. data/lib/knj/ironruby-gtk2/gtk_treeview.rb +17 -17
  85. data/lib/knj/ironruby-gtk2/gtk_treeviewcolumn.rb +30 -30
  86. data/lib/knj/ironruby-gtk2/iconsize.rb +1 -1
  87. data/lib/knj/ironruby-gtk2/image.rb +13 -13
  88. data/lib/knj/ironruby-gtk2/label.rb +17 -17
  89. data/lib/knj/ironruby-gtk2/stock.rb +2 -2
  90. data/lib/knj/ironruby-gtk2/tests/test_2.rb +14 -14
  91. data/lib/knj/ironruby-gtk2/tests/test_ironruby_window.rb +37 -37
  92. data/lib/knj/ironruby-gtk2/vbox.rb +3 -3
  93. data/lib/knj/ironruby-gtk2/window.rb +18 -18
  94. data/lib/knj/jruby-gtk2/builder/test_builder.rb +11 -11
  95. data/lib/knj/jruby-gtk2/builder.rb +25 -25
  96. data/lib/knj/jruby-gtk2/cellrenderertext.rb +10 -10
  97. data/lib/knj/jruby-gtk2/checkbutton.rb +1 -1
  98. data/lib/knj/jruby-gtk2/combobox.rb +27 -27
  99. data/lib/knj/jruby-gtk2/dialog.rb +40 -40
  100. data/lib/knj/jruby-gtk2/eventbutton.rb +19 -19
  101. data/lib/knj/jruby-gtk2/gladexml.rb +97 -97
  102. data/lib/knj/jruby-gtk2/gtk2.rb +203 -203
  103. data/lib/knj/jruby-gtk2/hbox.rb +8 -8
  104. data/lib/knj/jruby-gtk2/iconsize.rb +3 -3
  105. data/lib/knj/jruby-gtk2/image.rb +8 -8
  106. data/lib/knj/jruby-gtk2/liststore.rb +54 -54
  107. data/lib/knj/jruby-gtk2/menu.rb +35 -35
  108. data/lib/knj/jruby-gtk2/progressbar.rb +10 -10
  109. data/lib/knj/jruby-gtk2/statusicon.rb +3 -3
  110. data/lib/knj/jruby-gtk2/stock.rb +6 -6
  111. data/lib/knj/jruby-gtk2/tests/test_glade_window.rb +36 -36
  112. data/lib/knj/jruby-gtk2/tests/test_normal_window.rb +3 -3
  113. data/lib/knj/jruby-gtk2/tests/test_trayicon.rb +2 -2
  114. data/lib/knj/jruby-gtk2/treeview.rb +88 -88
  115. data/lib/knj/jruby-gtk2/vbox.rb +10 -10
  116. data/lib/knj/jruby-gtk2/window.rb +7 -7
  117. data/lib/knj/jruby_compiler.rb +12 -12
  118. data/lib/knj/knj.rb +12 -11
  119. data/lib/knj/knj_controller.rb +13 -8
  120. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +499 -316
  121. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +127 -125
  122. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +43 -25
  123. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +316 -241
  124. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +12 -0
  125. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +146 -146
  126. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_indexes.rb +24 -24
  127. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +283 -283
  128. data/lib/knj/knjdb/libknjdb.rb +96 -52
  129. data/lib/knj/knjdb/libknjdb_java_sqlite3.rb +78 -78
  130. data/lib/knj/knjdb/libknjdb_row.rb +147 -147
  131. data/lib/knj/knjdb/libknjdb_sqlite3_ironruby.rb +61 -61
  132. data/lib/knj/knjdb/revision.rb +262 -0
  133. data/lib/knj/libqt.rb +69 -69
  134. data/lib/knj/libqt_window.rb +8 -8
  135. data/lib/knj/locales.rb +62 -52
  136. data/lib/knj/maemo/fremantle-calendar/fremantle-calendar.rb +54 -54
  137. data/lib/knj/mail.rb +73 -73
  138. data/lib/knj/mailobj.rb +82 -80
  139. data/lib/knj/mount.rb +113 -113
  140. data/lib/knj/notify.rb +11 -11
  141. data/lib/knj/nvidia_settings.rb +43 -43
  142. data/lib/knj/objects/objects_sqlhelper.rb +474 -0
  143. data/lib/knj/objects.rb +569 -793
  144. data/lib/knj/opts.rb +38 -38
  145. data/lib/knj/os.rb +176 -158
  146. data/lib/knj/php.rb +853 -683
  147. data/lib/knj/php_parser/arguments.rb +3 -3
  148. data/lib/knj/php_parser/functions.rb +95 -95
  149. data/lib/knj/php_parser/php_parser.rb +16 -16
  150. data/lib/knj/php_parser/tests/test.rb +6 -6
  151. data/lib/knj/php_parser/tests/test_function_run.rb +6 -6
  152. data/lib/knj/power_manager.rb +29 -29
  153. data/lib/knj/process.rb +457 -0
  154. data/lib/knj/process_meta.rb +400 -0
  155. data/lib/knj/rand.rb +8 -8
  156. data/lib/knj/retry.rb +69 -69
  157. data/lib/knj/rhodes/delegate.rb +414 -0
  158. data/lib/knj/rhodes/rhodes.rb +114 -40
  159. data/lib/knj/rhodes/weakref.rb +80 -0
  160. data/lib/knj/rsvgbin.rb +18 -18
  161. data/lib/knj/scripts/degulesider.rb +2 -2
  162. data/lib/knj/scripts/filesearch.rb +35 -35
  163. data/lib/knj/scripts/ip2location.rb +2 -2
  164. data/lib/knj/scripts/keepalive.rb +2 -2
  165. data/lib/knj/scripts/php_to_rb_helper.rb +376 -0
  166. data/lib/knj/scripts/process_meta_exec.rb +104 -0
  167. data/lib/knj/scripts/svn_merge.rb +21 -21
  168. data/lib/knj/scripts/upgrade_knjrbfw_checker.rb +26 -26
  169. data/lib/knj/sms.rb +52 -52
  170. data/lib/knj/sshrobot/sshrobot.rb +90 -88
  171. data/lib/knj/sshrobot.rb +1 -0
  172. data/lib/knj/strings.rb +186 -74
  173. data/lib/knj/sysuser.rb +25 -25
  174. data/lib/knj/table_writer.rb +97 -0
  175. data/lib/knj/tests/compiler/compiler_test.rb +2 -2
  176. data/lib/knj/tests/test_degulesider.rb +1 -1
  177. data/lib/knj/tests/test_http2_proxy.rb +26 -0
  178. data/lib/knj/tests/test_mount.rb +9 -9
  179. data/lib/knj/tests/test_retry.rb +17 -17
  180. data/lib/knj/thread.rb +23 -24
  181. data/lib/knj/thread2.rb +45 -45
  182. data/lib/knj/threadhandler.rb +135 -102
  183. data/lib/knj/threadpool.rb +195 -145
  184. data/lib/knj/translations.rb +128 -119
  185. data/lib/knj/unix_proc.rb +80 -80
  186. data/lib/knj/web.rb +947 -881
  187. data/lib/knj/webscripts/image.rhtml +142 -67
  188. data/lib/knj/win.rb +2 -2
  189. data/lib/knj/win_registry.rb +58 -58
  190. data/lib/knj/win_tightvnc.rb +125 -125
  191. data/lib/knj/wref.rb +104 -0
  192. data/lib/knj/x11vnc.rb +46 -46
  193. data/lib/knj/youtube.rb +33 -36
  194. data/lib/knjrbfw.rb +1 -0
  195. data/spec/cmd_parser_spec.rb +25 -0
  196. data/spec/db_spec.rb +40 -0
  197. data/spec/db_spec_encoding_test_file.txt +1 -0
  198. data/spec/http2_spec.rb +37 -0
  199. data/spec/knjrbfw_spec.rb +17 -15
  200. data/spec/php_spec.rb +69 -0
  201. data/spec/process_meta_spec.rb +150 -0
  202. data/spec/process_spec.rb +107 -0
  203. data/spec/strings_spec.rb +21 -0
  204. data/spec/web_spec.rb +16 -0
  205. metadata +42 -21
  206. data/lib/knj/autoload/json_autoload.rb +0 -7
  207. data/lib/knj/autoload/twitter.rb +0 -2
  208. data/lib/knj/ext/webrick.rb +0 -31
  209. data/lib/knj/jruby-gtk2/gtk-4.0.jar +0 -0
  210. data/lib/knj/knjdb/mysql-connector-java-5.1.13-bin.jar +0 -0
  211. data/lib/knj/knjdb/sqlitejdbc-v056.jar +0 -0
data/lib/knj/objects.rb CHANGED
@@ -1,32 +1,42 @@
1
1
  class Knj::Objects
2
- attr_reader :args, :events, :data
3
-
4
- def initialize(args)
5
- @callbacks = {}
6
- @args = Knj::ArrayExt.hash_sym(args)
7
- @args[:col_id] = :id if !@args[:col_id]
8
- @args[:class_pre] = "class_" if !@args[:class_pre]
9
- @args[:module] = Kernel if !@args[:module]
10
- @args[:cache] = :weak if !@args.key?(:cache)
11
- @objects = {}
12
- @data = {}
13
-
14
- require "weakref" if @args[:cache] == :weak
15
-
16
- @events = Knj::Event_handler.new
17
- @events.add_event(
2
+ attr_reader :args, :events, :data
3
+
4
+ def initialize(args)
5
+ require "#{$knjpath}arrayext"
6
+ require "#{$knjpath}event_handler"
7
+ require "#{$knjpath}hash_methods"
8
+
9
+ @callbacks = {}
10
+ @args = Knj::ArrayExt.hash_sym(args)
11
+ @args[:col_id] = :id if !@args[:col_id]
12
+ @args[:class_pre] = "class_" if !@args[:class_pre]
13
+ @args[:module] = Kernel if !@args[:module]
14
+ @args[:cache] = :weak if !@args.key?(:cache)
15
+ @objects = {}
16
+ @data = {}
17
+ @mutex_require = Mutex.new
18
+
19
+ require "weakref" if @args[:cache] == :weak and !Kernel.const_defined?(:WeakRef)
20
+
21
+ @events = Knj::Event_handler.new
22
+ @events.add_event(
18
23
  :name => :no_html,
19
24
  :connections_max => 1
20
- )
21
- @events.add_event(
25
+ )
26
+ @events.add_event(
22
27
  :name => :no_date,
23
28
  :connections_max => 1
24
- )
25
-
26
- raise "No DB given." if !@args[:db]
27
- raise "No class path given." if !@args[:class_path] and (@args[:require] or !@args.key?(:require))
28
-
29
- if args[:require_all]
29
+ )
30
+ @events.add_event(
31
+ :name => :missing_class,
32
+ :connections_max => 1
33
+ )
34
+
35
+ raise "No DB given." if !@args[:db] and !@args[:custom]
36
+ raise "No class path given." if !@args[:class_path] and (@args[:require] or !@args.key?(:require))
37
+
38
+ if args[:require_all]
39
+ require "#{$knjpath}php"
30
40
  loads = []
31
41
 
32
42
  Dir.foreach(@args[:class_path]) do |file|
@@ -43,87 +53,89 @@ class Knj::Objects
43
53
  loads.each do |load_class|
44
54
  self.load_class(load_class)
45
55
  end
46
- end
47
- end
48
-
49
- def init_class(classname)
56
+ end
57
+ end
58
+
59
+ def init_class(classname)
50
60
  return false if @objects.key?(classname)
51
61
  @objects[classname] = {}
52
- end
53
-
54
- #Returns a cloned version of the @objects variable. Cloned because iteration on it may crash some of the other methods in Ruby 1.9+
55
- def objects
56
- objs_cloned = {}
57
-
62
+ end
63
+
64
+ #Returns a cloned version of the @objects variable. Cloned because iteration on it may crash some of the other methods in Ruby 1.9+
65
+ def objects
66
+ objs_cloned = {}
67
+
58
68
  @objects.keys.each do |key|
59
69
  objs_cloned[key] = @objects[key].clone
60
70
  end
61
-
62
- return objs_cloned
63
- end
64
-
65
- def db
66
- return @args[:db]
67
- end
68
-
69
- def count_objects
70
- count = 0
71
+
72
+ return objs_cloned
73
+ end
74
+
75
+ def db
76
+ return @args[:db]
77
+ end
78
+
79
+ def count_objects
80
+ count = 0
71
81
  @objects.keys.each do |key|
72
82
  count += @objects[key].length
73
83
  end
74
-
75
- return count
76
- end
77
-
78
- def connect(args, &block)
79
- raise "No object given." if !args["object"]
80
- raise "No signals given." if !args.key?("signal") and !args.key?("signals")
81
- args["block"] = block if block_given?
82
- @callbacks[args["object"]] = {} if !@callbacks[args["object"]]
83
- conn_id = @callbacks[args["object"]].length.to_s
84
- @callbacks[args["object"]][conn_id] = args
85
- end
86
-
87
- def call(args, &block)
88
- classstr = args["object"].class.to_s
89
-
90
- if @callbacks.key?(classstr)
91
- @callbacks[classstr].clone.each do |callback_key, callback|
92
- docall = false
93
-
94
- if callback.key?("signal") and args.key?("signal") and callback["signal"] == args["signal"]
95
- docall = true
96
- elsif callback["signals"] and args["signal"] and callback["signals"].index(args["signal"]) != nil
97
- docall = true
98
- end
99
-
100
- next if !docall
101
-
102
- if callback["block"]
103
- callargs = []
104
- arity = callback["block"].arity
105
- if arity <= 0
106
- #do nothing
107
- elsif arity == 1
108
- callargs << args["object"]
109
- else
110
- raise "Unknown number of arguments: #{arity}"
111
- end
112
-
113
- callback["block"].call(*callargs)
114
- elsif callback["callback"]
115
- Knj::Php.call_user_func(callback["callback"], args)
116
- else
117
- raise "No valid callback given."
118
- end
119
- end
120
- end
121
- end
122
-
123
- def requireclass(classname, args = {})
84
+
85
+ return count
86
+ end
87
+
88
+ def connect(args, &block)
89
+ raise "No object given." if !args["object"]
90
+ raise "No signals given." if !args.key?("signal") and !args.key?("signals")
91
+ args["block"] = block if block_given?
92
+ @callbacks[args["object"]] = {} if !@callbacks[args["object"]]
93
+ conn_id = @callbacks[args["object"]].length.to_s
94
+ @callbacks[args["object"]][conn_id] = args
95
+ end
96
+
97
+ def call(args, &block)
98
+ classstr = args["object"].class.to_s
99
+
100
+ if @callbacks.key?(classstr)
101
+ @callbacks[classstr].clone.each do |callback_key, callback|
102
+ docall = false
103
+
104
+ if callback.key?("signal") and args.key?("signal") and callback["signal"] == args["signal"]
105
+ docall = true
106
+ elsif callback["signals"] and args["signal"] and callback["signals"].index(args["signal"]) != nil
107
+ docall = true
108
+ end
109
+
110
+ next if !docall
111
+
112
+ if callback["block"]
113
+ callargs = []
114
+ arity = callback["block"].arity
115
+ if arity <= 0
116
+ #do nothing
117
+ elsif arity == 1
118
+ callargs << args["object"]
119
+ else
120
+ raise "Unknown number of arguments: #{arity}"
121
+ end
122
+
123
+ callback["block"].call(*callargs)
124
+ elsif callback["callback"]
125
+ Knj::Php.call_user_func(callback["callback"], args)
126
+ else
127
+ raise "No valid callback given."
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ def requireclass(classname, args = {})
124
134
  classname = classname.to_sym
125
135
 
126
- if !@objects.key?(classname)
136
+ return false if @objects.key?(classname)
137
+
138
+ @mutex_require.synchronize do
127
139
  if (@args[:require] or !@args.key?(:require)) and (!args.key?(:require) or args[:require])
128
140
  filename = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}.rb"
129
141
  filename_req = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}"
@@ -134,18 +146,30 @@ class Knj::Objects
134
146
  if args[:class]
135
147
  classob = args[:class]
136
148
  else
137
- classob = @args[:module].const_get(classname)
149
+ begin
150
+ classob = @args[:module].const_get(classname)
151
+ rescue NameError => e
152
+ if @events.connected?(:missing_class)
153
+ @events.call(:missing_class, {
154
+ :class => classname
155
+ })
156
+ classob = @args[:module].const_get(classname)
157
+ else
158
+ raise e
159
+ end
160
+ end
138
161
  end
139
-
140
- if (classob.respond_to?(:load_columns) or classob.respond_to?(:datarow_init)) and (!args.key?(:load) or args[:load])
162
+
163
+ if (classob.respond_to?(:load_columns) or classob.respond_to?(:datarow_init)) and (!args.key?(:load) or args[:load])
141
164
  self.load_class(classname, args)
142
- end
143
-
144
- @objects[classname] = {}
145
- end
146
- end
147
-
148
- def load_class(classname, args = {})
165
+ end
166
+
167
+ @objects[classname] = {}
168
+ end
169
+ end
170
+
171
+ #Loads a Datarow-class by calling various static methods.
172
+ def load_class(classname, args = {})
149
173
  if args[:class]
150
174
  classob = args[:class]
151
175
  else
@@ -155,36 +179,39 @@ class Knj::Objects
155
179
  pass_arg = Knj::Hash_methods.new(:ob => self, :db => @args[:db])
156
180
  classob.load_columns(pass_arg) if classob.respond_to?(:load_columns)
157
181
  classob.datarow_init(pass_arg) if classob.respond_to?(:datarow_init)
158
- end
159
-
160
- def get(classname, data)
161
- classname = classname.to_sym
162
-
163
- if data.is_a?(Integer) or data.is_a?(String) or data.is_a?(Fixnum)
182
+ end
183
+
184
+ #Gets an object from the ID or the full data-hash in the database.
185
+ def get(classname, data)
186
+ classname = classname.to_sym
187
+
188
+ if data.is_a?(Integer) or data.is_a?(String) or data.is_a?(Fixnum)
164
189
  id = data.to_i
165
- elsif data.is_a?(Hash) and data[@args[:col_id].to_sym]
166
- id = data[@args[:col_id].to_sym].to_i
167
- elsif data.is_a?(Hash) and data[@args[:col_id].to_s]
168
- id = data[@args[:col_id].to_s].to_i
169
- elsif
170
- raise Knj::Errors::InvalidData, "Unknown data: '#{data.class.to_s}'."
171
- end
172
-
173
- if @objects.key?(classname) and @objects[classname].key?(id)
190
+ elsif data.is_a?(Hash) and data.key?(@args[:col_id].to_sym)
191
+ id = data[@args[:col_id].to_sym].to_i
192
+ elsif data.is_a?(Hash) and data.key?(@args[:col_id].to_s)
193
+ id = data[@args[:col_id].to_s].to_i
194
+ elsif
195
+ raise Knj::Errors::InvalidData, "Unknown data: '#{data.class.to_s}'."
196
+ end
197
+
198
+ if @objects.key?(classname) and @objects[classname].key?(id)
174
199
  case @args[:cache]
175
200
  when :weak
176
201
  begin
177
- obj = @objects[classname][id]
178
- obj = obj.__getobj__ if obj.is_a?(WeakRef)
202
+ obj = @objects[classname][id].__getobj__
179
203
 
180
- #This actually happens sometimes... WTF!? - knj
181
204
  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
205
  return obj
183
206
  else
207
+ #This actually happens sometimes... WTF!? - knj
184
208
  raise WeakRef::RefError
185
209
  end
186
210
  rescue WeakRef::RefError
187
211
  @objects[classname].delete(id)
212
+ rescue NoMethodError => e
213
+ #NoMethodError because the object might have been deleted from the cache, and __getobj__ then throws it.
214
+ raise e if e.message != "undefined method `__getobj__' for nil:NilClass"
188
215
  end
189
216
  else
190
217
  return @objects[classname][id]
@@ -193,7 +220,7 @@ class Knj::Objects
193
220
 
194
221
  self.requireclass(classname) if !@objects.key?(classname)
195
222
 
196
- if @args[:datarow]
223
+ if @args[:datarow] or @args[:custom]
197
224
  obj = @args[:module].const_get(classname).new(Knj::Hash_methods.new(:ob => self, :data => data))
198
225
  else
199
226
  args = [data]
@@ -204,209 +231,227 @@ class Knj::Objects
204
231
  case @args[:cache]
205
232
  when :weak
206
233
  @objects[classname][id] = WeakRef.new(obj)
234
+ when :none
235
+ return obj
207
236
  else
208
237
  @objects[classname][id] = obj
209
238
  end
210
239
 
211
240
  return obj
212
- end
213
-
214
- def object_finalizer(id)
241
+ end
242
+
243
+ def object_finalizer(id)
215
244
  classname = @objects_idclass[id]
216
245
  if classname
217
246
  @objects[classname].delete(id)
218
247
  @objects_idclass.delete(id)
219
248
  end
220
- end
221
-
222
- def get_by(classname, args = {})
223
- classname = classname.to_sym
224
- self.requireclass(classname)
225
- classob = @args[:module].const_get(classname)
226
-
227
- raise "list-function has not been implemented for #{classname}" if !classob.respond_to?("list")
228
-
229
- args[:limit_from] = 0
230
- args[:limit_to] = 1
231
-
232
- self.list(classname, args) do |obj|
233
- return obj
234
- end
235
-
236
- return false
237
- end
238
-
239
- def get_try(obj, col_name, obj_name = nil)
240
- if !obj_name
241
- if match = col_name.to_s.match(/^(.+)_id$/)
242
- obj_name = Knj::Php.ucwords(match[1]).to_sym
243
- else
244
- raise "Could not figure out objectname for: #{col_name}."
245
- end
246
- end
247
-
248
- id_data = obj[col_name].to_i
249
- return false if !id_data
250
-
251
- begin
252
- return self.get(obj_name, id_data)
253
- rescue Knj::Errors::NotFound
254
- return false
255
- end
256
- end
257
-
258
- def list(classname, args = {}, &block)
259
- classname = classname.to_sym
260
- self.requireclass(classname)
261
- classob = @args[:module].const_get(classname)
262
-
263
- raise "list-function has not been implemented for #{classname}" if !classob.respond_to?("list")
264
-
265
- if @args[:datarow]
266
- ret = classob.list(Knj::Hash_methods.new(:args => args, :ob => self, :db => @args[:db]))
267
- else
268
- realargs = [args]
269
- realargs = realargs | @args[:extra_args] if @args[:extra_args]
270
- ret = classob.list(*realargs)
271
- end
272
-
273
- if block_given?
274
- ret.each do |obj|
275
- yield(obj)
276
- end
277
- else
278
- return ret
279
- end
280
- end
281
-
282
- def list_opts(classname, args = {})
283
- Knj::ArrayExt.hash_sym(args)
284
- classname = classname.to_sym
285
-
286
- if args[:list_args]
287
- obs = self.list(classname, args[:list_args])
288
- else
289
- obs = self.list(classname)
290
- end
291
-
292
- html = ""
293
-
294
- if args[:addnew] or args[:add]
295
- html += "<option"
296
- html += " selected=\"selected\"" if !args[:selected]
297
- html += " value=\"\">#{_("Add new")}</option>"
298
- end
299
-
300
- obs.each do |object|
301
- html += "<option value=\"#{object.id.html}\""
302
-
303
- selected = false
304
- if args[:selected].is_a?(Array) and args[:selected].index(object) != nil
305
- selected = true
306
- elsif args[:selected] and args[:selected].respond_to?("is_knj?") and args[:selected].id.to_s == object.id.to_s
307
- selected = true
308
- end
309
-
310
- html += " selected=\"selected\"" if selected
311
-
312
- obj_methods = object.class.instance_methods(false)
313
-
314
- begin
315
- if obj_methods.index("name") != nil or obj_methods.index(:name) != nil
316
- objhtml = object.name.html
317
- elsif obj_methods.index("title") != nil or obj_methods.index(:title) != nil
318
- objhtml = object.title.html
319
- elsif object.respond_to?(:data)
320
- obj_data = object.data
321
-
322
- if obj_data.key?(:name)
323
- objhtml = obj_data[:name]
324
- elsif obj_data.key?(:title)
325
- objhtml = obj_data[:title]
326
- end
327
- else
249
+ end
250
+
251
+ def get_by(classname, args = {})
252
+ classname = classname.to_sym
253
+ self.requireclass(classname)
254
+ classob = @args[:module].const_get(classname)
255
+
256
+ raise "list-function has not been implemented for #{classname}" if !classob.respond_to?("list")
257
+
258
+ args["limit"] = 1
259
+ self.list(classname, args) do |obj|
260
+ return obj
261
+ end
262
+
263
+ return false
264
+ end
265
+
266
+ def get_try(obj, col_name, obj_name = nil)
267
+ if !obj_name
268
+ if match = col_name.to_s.match(/^(.+)_id$/)
269
+ obj_name = Knj::Php.ucwords(match[1]).to_sym
270
+ else
271
+ raise "Could not figure out objectname for: #{col_name}."
272
+ end
273
+ end
274
+
275
+ id_data = obj[col_name].to_i
276
+ return false if id_data.to_i <= 0
277
+
278
+ begin
279
+ return self.get(obj_name, id_data)
280
+ rescue Knj::Errors::NotFound
281
+ return false
282
+ end
283
+ end
284
+
285
+ #Returns an array-list of objects. If given a block the block will be called for each element and memory will be spared if running weak-link-mode.
286
+ def list(classname, args = {}, &block)
287
+ args = {} if args == nil
288
+ classname = classname.to_sym
289
+ self.requireclass(classname)
290
+ classob = @args[:module].const_get(classname)
291
+
292
+ raise "list-function has not been implemented for '#{classname}'." if !classob.respond_to?("list")
293
+
294
+ if @args[:datarow] or @args[:custom]
295
+ ret = classob.list(Knj::Hash_methods.new(:args => args, :ob => self, :db => @args[:db]), &block)
296
+ else
297
+ realargs = [args]
298
+ realargs = realargs | @args[:extra_args] if @args[:extra_args]
299
+ ret = classob.list(*realargs, &block)
300
+ end
301
+
302
+ #If 'ret' is an array and a block is given then the list-method didnt return blocks. We emulate it instead with the following code.
303
+ if block and ret.is_a?(Array)
304
+ ret.each do |obj|
305
+ block.call(obj)
306
+ end
307
+ return nil
308
+ elsif block and ret != nil
309
+ raise "Return should return nil because of block but didnt. It wasnt an array either..."
310
+ elsif block
311
+ return nil
312
+ else
313
+ return ret
314
+ end
315
+ end
316
+
317
+ #Returns select-options-HTML for inserting into a HTML-select-element.
318
+ def list_opts(classname, args = {})
319
+ Knj::ArrayExt.hash_sym(args)
320
+ classname = classname.to_sym
321
+
322
+ if args[:list_args].is_a?(Hash)
323
+ list_args = args[:list_args]
324
+ else
325
+ list_args = {}
326
+ end
327
+
328
+ html = ""
329
+
330
+ if args[:addnew] or args[:add]
331
+ html << "<option"
332
+ html << " selected=\"selected\"" if !args[:selected]
333
+ html << " value=\"\">#{_("Add new")}</option>"
334
+ end
335
+
336
+ self.list(classname, args[:list_args]) do |object|
337
+ html << "<option value=\"#{object.id.html}\""
338
+
339
+ selected = false
340
+ if args[:selected].is_a?(Array) and args[:selected].index(object) != nil
341
+ selected = true
342
+ elsif args[:selected] and args[:selected].respond_to?("is_knj?") and args[:selected].id.to_s == object.id.to_s
343
+ selected = true
344
+ end
345
+
346
+ html << " selected=\"selected\"" if selected
347
+
348
+ obj_methods = object.class.instance_methods(false)
349
+
350
+ begin
351
+ if obj_methods.index("name") != nil or obj_methods.index(:name) != nil
352
+ objhtml = object.name.html
353
+ elsif obj_methods.index("title") != nil or obj_methods.index(:title) != nil
354
+ objhtml = object.title.html
355
+ elsif object.respond_to?(:data)
356
+ obj_data = object.data
357
+
358
+ if obj_data.key?(:name)
359
+ objhtml = obj_data[:name]
360
+ elsif obj_data.key?(:title)
361
+ objhtml = obj_data[:title]
362
+ end
363
+ else
328
364
  objhtml = ""
329
365
  end
330
-
331
- raise "Could not figure out which name-method to call?" if !objhtml
332
- html += ">#{objhtml}</option>"
333
- rescue Exception => e
334
- html += ">[#{object.class.name}: #{e.message}]</option>"
335
- end
336
- end
337
-
338
- return html
339
- end
340
-
341
- def list_optshash(classname, args = {})
342
- Knj::ArrayExt.hash_sym(args)
343
- classname = classname.to_sym
344
-
345
- if args[:list_args]
346
- obs = self.list(classname, args[:list_args])
347
- else
348
- obs = self.list(classname)
349
- end
350
-
351
- if RUBY_VERSION[0..2] == 1.8 and Knj::Php.class_exists("Dictionary")
352
- list = Dictionary.new
353
- else
354
- list = {}
355
- end
356
-
357
- if args[:addnew] or args[:add]
358
- list["0"] = _("Add new")
359
- elsif args[:choose]
360
- list["0"] = _("Choose") + ":"
361
- elsif args[:all]
362
- list["0"] = _("All")
363
- elsif args[:none]
364
- list["0"] = _("None")
365
- end
366
-
367
- obs.each do |object|
368
- list[object.id] = object.title
369
- end
370
-
371
- return list
372
- end
373
-
374
- # Returns a list of a specific object by running specific SQL against the database.
375
- def list_bysql(classname, sql)
376
- classname = classname.to_sym
377
-
378
- ret = [] if !block_given?
379
- @args[:db].q(sql) do |d_obs|
380
- if block_given?
381
- yield(self.get(classname, d_obs))
382
- else
383
- ret << self.get(classname, d_obs)
384
- end
385
- end
386
-
387
- return ret if !block_given?
388
- end
389
-
390
- # Add a new object to the database and to the cache.
391
- def add(classname, data = {})
392
- classname = classname.to_sym
393
- self.requireclass(classname)
394
-
395
- args = [data]
396
- args = args | @args[:extra_args] if @args[:extra_args]
397
-
398
- if @args[:datarow]
366
+
367
+ raise "Could not figure out which name-method to call?" if !objhtml
368
+ html << ">#{objhtml}</option>"
369
+ rescue Exception => e
370
+ html << ">[#{object.class.name}: #{e.message}]</option>"
371
+ end
372
+ end
373
+
374
+ return html
375
+ end
376
+
377
+ #Returns a hash which can be used to generate HTML-select-elements.
378
+ def list_optshash(classname, args = {})
379
+ Knj::ArrayExt.hash_sym(args)
380
+ classname = classname.to_sym
381
+
382
+ if args[:list_args].is_a?(Hash)
383
+ list_args = args[:list_args]
384
+ else
385
+ list_args = {}
386
+ end
387
+
388
+ if RUBY_VERSION[0..2] == 1.8 and Knj::Php.class_exists("Dictionary")
389
+ print "Spawning dictionary.\n" if args[:debug]
390
+ list = Dictionary.new
391
+ else
392
+ print "Spawning normal hash.\n" if args[:debug]
393
+ list = {}
394
+ end
395
+
396
+ if args[:addnew] or args[:add]
397
+ list["0"] = _("Add new")
398
+ elsif args[:choose]
399
+ list["0"] = _("Choose") + ":"
400
+ elsif args[:all]
401
+ list["0"] = _("All")
402
+ elsif args[:none]
403
+ list["0"] = _("None")
404
+ end
405
+
406
+ print "Doing loop\n" if args[:debug]
407
+ self.list(classname, args[:list_args]) do |object|
408
+ print "Object: #{object.id}\n" if args[:debug]
409
+
410
+ if object.respond_to?(:name)
411
+ list[object.id] = object.name
412
+ elsif object.respond_to?(:title)
413
+ list[object.id] = object.title
414
+ else
415
+ raise "Object of class '#{object.class.name}' doesnt support 'name' or 'title."
416
+ end
417
+ end
418
+
419
+ print "Returning...\n" if args[:debug]
420
+ return list
421
+ end
422
+
423
+ #Returns a list of a specific object by running specific SQL against the database.
424
+ def list_bysql(classname, sql, d = nil, &block)
425
+ classname = classname.to_sym
426
+ ret = [] if !block
427
+ @args[:db].q(sql) do |d_obs|
428
+ if block
429
+ block.call(self.get(classname, d_obs))
430
+ else
431
+ ret << self.get(classname, d_obs)
432
+ end
433
+ end
434
+
435
+ return ret if !block
436
+ end
437
+
438
+ # Add a new object to the database and to the cache.
439
+ def add(classname, data = {})
440
+ classname = classname.to_sym
441
+ self.requireclass(classname)
442
+
443
+ if @args[:datarow]
399
444
  classobj = @args[:module].const_get(classname)
400
- if classobj.respond_to?(:add)
401
- classobj.add(Knj::Hash_methods.new(
402
- :ob => self,
403
- :db => self.db,
404
- :data => data
405
- ))
406
- end
407
-
408
- required_data = classobj.required_data
409
- required_data.each do |req_data|
445
+ if classobj.respond_to?(:add)
446
+ classobj.add(Knj::Hash_methods.new(
447
+ :ob => self,
448
+ :db => self.db,
449
+ :data => data
450
+ ))
451
+ end
452
+
453
+ required_data = classobj.required_data
454
+ required_data.each do |req_data|
410
455
  if !data.key?(req_data[:col])
411
456
  raise "No '#{req_data[:class]}' given by the data '#{req_data[:col]}'."
412
457
  end
@@ -416,120 +461,133 @@ class Knj::Objects
416
461
  rescue Knj::Errors::NotFound
417
462
  raise "The '#{req_data[:class]}' by ID '#{data[req_data[:col]]}' could not be found with the data '#{req_data[:col]}'."
418
463
  end
419
- end
420
-
421
- ins_id = @args[:db].insert(classname, data, {:return_id => true})
422
- retob = self.get(classname, ins_id)
423
- else
424
- retob = @args[:module].const_get(classname).add(*args)
425
- end
426
-
427
- self.call("object" => retob, "signal" => "add")
428
- if retob.respond_to?(:add_after)
429
- retob.send(:add_after, {})
430
- end
431
-
432
- return retob
433
- end
434
-
435
- def adds(classname, datas)
436
- if !@args[:datarow]
437
- datas.each do |data|
438
- @args[:module].const_get(classname).add(*args)
439
- self.call("object" => retob, "signal" => "add")
440
- end
441
- else
442
- if @args[:module].const_get(classname).respond_to?(:add)
443
- datas.each do |data|
444
- @args[:module].const_get(classname).add(Knj::Hash_methods.new(
445
- :ob => self,
446
- :db => self.db,
447
- :data => data
448
- ))
449
- end
450
- end
451
-
452
- db.insert_multi(classname, datas)
453
- end
454
- end
455
-
456
- def static(class_name, method_name, *args)
457
- raise "Only available with datarow enabled." if !@args[:datarow]
458
- class_name = class_name.to_sym
459
- method_name = method_name.to_sym
460
-
461
- self.requireclass(class_name)
462
- class_obj = @args[:module].const_get(class_name)
463
- raise "The class '#{class_obj.name}' has no such method: '#{method_name}'." if !class_obj.respond_to?(method_name)
464
- method_obj = class_obj.method(method_name)
465
-
466
- pass_args = []
467
- pass_args << Knj::Hash_methods.new(
468
- :ob => self,
469
- :db => self.db
470
- )
471
-
472
- args.each do |arg|
473
- pass_args << arg
474
- end
475
-
476
- method_obj.call(*pass_args)
477
- end
478
-
479
- # Unset object. Do this if you are sure, that there are no more references left. This will be done automatically when deleting it.
480
- def unset(object)
481
- if object.is_a?(Array)
482
- object.each do |obj|
483
- unset(obj)
484
- end
485
- return nil
486
- end
487
-
488
- classname = object.class.name
489
-
490
- if @args[:module]
491
- classname = classname.gsub(@args[:module].name + "::", "")
492
- end
493
-
494
- classname = classname.to_sym
495
-
496
- #if !@objects.key?(classname)
497
- #raise "Could not find object class in cache: #{classname}."
498
- #elsif !@objects[classname].key?(object.id.to_i)
499
- #errstr = ""
500
- #errstr += "Could not unset object from cache.\n"
501
- #errstr += "Class: #{object.class.name}.\n"
502
- #errstr += "ID: #{object.id}.\n"
503
- #errstr += "Could not find object ID in cache."
504
- #raise errstr
505
- #else
464
+ end
465
+
466
+ ins_id = @args[:db].insert(classobj.table, data, {:return_id => true})
467
+ retob = self.get(classname, ins_id)
468
+ elsif @args[:custom]
469
+ classobj = @args[:module].const_get(classname)
470
+ retob = classobj.add(Knj::Hash_methods.new(
471
+ :ob => self,
472
+ :data => data
473
+ ))
474
+ else
475
+ args = [data]
476
+ args = args | @args[:extra_args] if @args[:extra_args]
477
+ retob = @args[:module].const_get(classname).add(*args)
478
+ end
479
+
480
+ self.call("object" => retob, "signal" => "add")
481
+ if retob.respond_to?(:add_after)
482
+ retob.send(:add_after, {})
483
+ end
484
+
485
+ return retob
486
+ end
487
+
488
+ #Adds several objects to the database at once. This is faster than adding every single object by itself, since this will do multi-inserts if supported by the database.
489
+ def adds(classname, datas)
490
+ if !@args[:datarow]
491
+ datas.each do |data|
492
+ @args[:module].const_get(classname).add(*args)
493
+ self.call("object" => retob, "signal" => "add")
494
+ end
495
+ else
496
+ if @args[:module].const_get(classname).respond_to?(:add)
497
+ datas.each do |data|
498
+ @args[:module].const_get(classname).add(Knj::Hash_methods.new(
499
+ :ob => self,
500
+ :db => self.db,
501
+ :data => data
502
+ ))
503
+ end
504
+ end
505
+
506
+ db.insert_multi(classname, datas)
507
+ end
508
+ end
509
+
510
+ #Calls a static method on a class. Passes the d-variable which contains the Objects-object, database-reference and more...
511
+ def static(class_name, method_name, *args, &block)
512
+ raise "Only available with datarow enabled." if !@args[:datarow] and !@args[:custom]
513
+ class_name = class_name
514
+ method_name = method_name
515
+
516
+ self.requireclass(class_name)
517
+ class_obj = @args[:module].const_get(class_name)
518
+
519
+ #Sometimes this raises the exception but actually responds to the class? Therefore commented out. - knj
520
+ #raise "The class '#{class_obj.name}' has no such method: '#{method_name}' (#{class_obj.methods.sort.join(", ")})." if !class_obj.respond_to?(method_name)
521
+
522
+ pass_args = []
523
+
524
+ if @args[:datarow]
525
+ pass_args << Knj::Hash_methods.new(:ob => self, :db => self.db)
526
+ else
527
+ pass_args << Knj::Hash_methods.new(:ob => self)
528
+ end
529
+
530
+ args.each do |arg|
531
+ pass_args << arg
532
+ end
533
+
534
+ class_obj.send(method_name, *pass_args, &block)
535
+ end
536
+
537
+ #Unset object. Do this if you are sure, that there are no more references left. This will be done automatically when deleting it.
538
+ def unset(object)
539
+ if object.is_a?(Array)
540
+ object.each do |obj|
541
+ unset(obj)
542
+ end
543
+ return nil
544
+ end
545
+
546
+ classname = object.class.name
547
+
548
+ if @args[:module]
549
+ classname = classname.gsub(@args[:module].name + "::", "")
550
+ end
551
+
552
+ classname = classname.to_sym
553
+
554
+ #if !@objects.key?(classname)
555
+ #raise "Could not find object class in cache: #{classname}."
556
+ #elsif !@objects[classname].key?(object.id.to_i)
557
+ #errstr = ""
558
+ #errstr << "Could not unset object from cache.\n"
559
+ #errstr << "Class: #{object.class.name}.\n"
560
+ #errstr << "ID: #{object.id}.\n"
561
+ #errstr << "Could not find object ID in cache."
562
+ #raise errstr
563
+ #else
506
564
  @objects[classname].delete(object.id.to_i)
507
- #end
508
- end
509
-
510
- def unset_class(classname)
511
- if classname.is_a?(Array)
512
- classname.each do |classn|
513
- self.unset_class(classn)
514
- end
515
-
516
- return false
517
- end
518
-
519
- classname = classname.to_sym
520
-
521
- return false if !@objects.key?(classname)
565
+ #end
566
+ end
567
+
568
+ def unset_class(classname)
569
+ if classname.is_a?(Array)
570
+ classname.each do |classn|
571
+ self.unset_class(classn)
572
+ end
573
+
574
+ return false
575
+ end
576
+
577
+ classname = classname.to_sym
578
+
579
+ return false if !@objects.key?(classname)
522
580
  @objects[classname] = {}
523
- end
524
-
525
- # Delete an object. Both from the database and from the cache.
526
- def delete(object)
527
- self.call("object" => object, "signal" => "delete_before")
528
- self.unset(object)
529
- obj_id = object.id
530
- object.delete if object.respond_to?(:delete)
531
-
532
- if @args[:datarow]
581
+ end
582
+
583
+ #Delete an object. Both from the database and from the cache.
584
+ def delete(object)
585
+ self.call("object" => object, "signal" => "delete_before")
586
+ self.unset(object)
587
+ obj_id = object.id
588
+ object.delete if object.respond_to?(:delete)
589
+
590
+ if @args[:datarow]
533
591
  object.class.depending_data.each do |dep_data|
534
592
  objs = self.list(dep_data[:classname], {dep_data[:colname].to_s => object.id, "limit" => 1})
535
593
  if !objs.empty?
@@ -537,57 +595,64 @@ class Knj::Objects
537
595
  end
538
596
  end
539
597
 
540
- @args[:db].delete(object.table, {:id => obj_id})
541
- end
542
-
543
- self.call("object" => object, "signal" => "delete")
544
- object.destroy
545
- end
546
-
547
- def deletes(objs)
548
- if !@args[:datarow]
549
- objs.each do |obj|
550
- self.delete(obj)
551
- end
552
- else
553
- arr_ids = []
554
- ids = []
555
- objs.each do |obj|
556
- ids << obj.id
557
- if ids.length >= 1000
558
- arr_ids << ids
559
- ids = []
560
- end
561
-
562
- obj.delete if obj.respond_to?(:delete)
563
- end
564
-
565
- arr_ids << ids if ids.length > 0
566
- arr_ids.each do |ids|
567
- @args[:db].delete(objs[0].table, {:id => ids})
568
- end
569
- end
570
- end
571
-
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.
573
- def clean(classn)
574
- return false if @args[:cache] == :weak
575
-
576
- if classn.is_a?(Array)
577
- classn.each do |realclassn|
578
- self.clean(realclassn)
579
- end
580
- else
581
- return false if !@objects.key?(classn)
598
+ if object.class.translations
599
+ _kas.trans_del(object)
600
+ end
601
+
602
+ @args[:db].delete(object.table, {:id => obj_id})
603
+ end
604
+
605
+ self.call("object" => object, "signal" => "delete")
606
+ object.destroy
607
+ end
608
+
609
+ #Deletes several objects as one. If running datarow-mode it checks all objects before it starts to actually delete them. Its faster than deleting every single object by itself...
610
+ def deletes(objs)
611
+ if !@args[:datarow]
612
+ objs.each do |obj|
613
+ self.delete(obj)
614
+ end
615
+ else
616
+ arr_ids = []
617
+ ids = []
618
+ objs.each do |obj|
619
+ ids << obj.id
620
+ if ids.length >= 1000
621
+ arr_ids << ids
622
+ ids = []
623
+ end
624
+
625
+ obj.delete if obj.respond_to?(:delete)
626
+ end
627
+
628
+ arr_ids << ids if ids.length > 0
629
+ arr_ids.each do |ids|
630
+ @args[:db].delete(objs[0].table, {:id => ids})
631
+ end
632
+ end
633
+ end
634
+
635
+ # 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.
636
+ def clean(classn)
637
+ return false if @args[:cache] == :weak or @args[:cache] == :none
638
+
639
+ if classn.is_a?(Array)
640
+ classn.each do |realclassn|
641
+ self.clean(realclassn)
642
+ end
643
+ else
644
+ return false if !@objects.key?(classn)
582
645
  @objects[classn] = {}
583
646
  GC.start
584
- end
585
- end
586
-
587
- def clean_all
588
- return false if @args[:cache] == :weak
647
+ end
648
+ end
649
+
650
+ #Erases the whole cache and regenerates is from ObjectSpace if not running weak-link-caching. If running weaklink-caching then only removes the dead links.
651
+ def clean_all
652
+ return self.clean_all_weak if @args[:cache] == :weak
653
+ return false if @args[:cache] == :none
589
654
 
590
- classnames = []
655
+ classnames = []
591
656
  @objects.keys.each do |classn|
592
657
  classnames << classn
593
658
  end
@@ -595,12 +660,32 @@ class Knj::Objects
595
660
  classnames.each do |classn|
596
661
  @objects[classn] = {}
597
662
  end
598
-
599
- GC.start
600
- end
601
-
602
- def clean_recover
603
- return false if @args[:cache] == :weak
663
+
664
+ GC.start
665
+ self.clean_recover
666
+ end
667
+
668
+ #Runs through all objects-weaklink-references and removes the weaklinks if the object has been recycled.
669
+ def clean_all_weak
670
+ @objects.keys.each do |classn|
671
+ @objects[classn].keys.each do |object_id|
672
+ object = @objects[classn][object_id]
673
+
674
+ begin
675
+ if !object or !object.weakref_alive?
676
+ @objects[classn].delete(object_id)
677
+ end
678
+ rescue WeakRef::RefError
679
+ #This happens if the object has been collected.
680
+ @objects[classn].delete(object_id)
681
+ end
682
+ end
683
+ end
684
+ end
685
+
686
+ #Regenerates cache from ObjectSpace. Its pretty dangerous but can be used in envs where WeakRef is not supported (did someone say Rhodes?).
687
+ def clean_recover
688
+ return false if @args[:cache] == :weak or @args[:cache] == :none
604
689
  return false if RUBY_ENGINE == "jruby" and !JRuby.objectspace
605
690
 
606
691
  @objects.keys.each do |classn|
@@ -619,316 +704,7 @@ class Knj::Objects
619
704
  end
620
705
  end
621
706
  end
622
- end
623
-
624
- def sqlhelper(list_args, args_def)
625
- if args[:db]
626
- db = args[:db]
627
- else
628
- db = @args[:db]
629
- end
630
-
631
- args = args_def
632
-
633
- if args[:table]
634
- table_def = "`#{db.esc_table(args[:table])}`."
635
- else
636
- table_def = ""
637
- end
638
-
639
- sql_joins = ""
640
- sql_where = ""
641
- sql_order = ""
642
- sql_limit = ""
643
-
644
- do_joins = {}
645
-
646
- limit_from = nil
647
- limit_to = nil
648
-
649
- if list_args.key?("orderby")
650
- orders = []
651
- orderstr = list_args["orderby"]
652
- list_args["orderby"] = [list_args["orderby"]] if list_args["orderby"].is_a?(Hash)
653
-
654
- if list_args["orderby"].is_a?(String)
655
- found = false
656
- found = true if args[:cols].key?(orderstr)
657
-
658
- if found
659
- sql_order += " ORDER BY "
660
- ordermode = " ASC"
661
- if list_args.key?("ordermode")
662
- if list_args["ordermode"] == "desc"
663
- ordermode = " DESC"
664
- elsif list_args["ordermode"] == "asc"
665
- ordermode = " ASC"
666
- raise "Unknown ordermode: #{list_args["ordermode"]}"
667
- end
668
-
669
- list_args.delete("ordermode")
670
- end
671
-
672
- sql_order += "#{table_def}`#{db.esc_col(list_args["orderby"])}`#{ordermode}"
673
- list_args.delete("orderby")
674
- end
675
- elsif list_args["orderby"].is_a?(Array)
676
- sql_order += " ORDER BY "
677
-
678
- list_args["orderby"].each do |val|
679
- ordermode = nil
680
- orderstr = nil
681
- found = false
682
-
683
- if val.is_a?(Array)
684
- orderstr = val[0]
685
-
686
- if val[1] == "asc"
687
- ordermode = " ASC"
688
- elsif val[1] == "desc"
689
- ordermode = "DESC"
690
- end
691
- elsif val.is_a?(String)
692
- orderstr = val
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
713
- else
714
- raise "Unknown object: #{val.class.name}"
715
- end
716
-
717
- found = true if args[:cols].key?(orderstr)
718
- raise "Column not found for ordering: #{orderstr}." if !found
719
- orders << "#{table_def}`#{db.esc_col(orderstr)}`#{ordermode}" if orderstr
720
- end
721
-
722
- sql_order += orders.join(", ")
723
- list_args.delete("orderby")
724
- else
725
- raise "Unknown orderby object: #{list_args["orderby"].class.name}."
726
- end
727
- end
728
-
729
- list_args.each do |realkey, val|
730
- found = false
731
-
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)
750
- if val.is_a?(Array)
751
- escape_sql = Knj::ArrayExt.join(
752
- :arr => val,
753
- :callback => proc{|value|
754
- db.escape(value)
755
- },
756
- :sep => ",",
757
- :surr => "'")
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))}'"
770
- else
771
- sql_where += " AND #{table}`#{db.esc_col(key)}` = '#{db.esc(val)}'"
772
- end
773
-
774
- found = true
775
- elsif args.key?(:cols_bools) and args[:cols_bools].index(key) != nil
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"))
777
- realval = "1"
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"))
779
- realval = "0"
780
- else
781
- raise "Could not make real value out of class: #{val.class.name} => #{val}."
782
- end
783
-
784
- sql_where += " AND #{table}`#{db.esc_col(key)}` = '#{db.esc(realval)}'"
785
- found = true
786
- elsif key.to_s == "limit_from"
787
- limit_from = val.to_i
788
- found = true
789
- elsif key.to_s == "limit_to"
790
- limit_to = val.to_i
791
- found = true
792
- elsif key.to_s == "limit"
793
- limit_from = 0
794
- limit_to = val.to_i
795
- found = true
796
- elsif args.key?(:cols_dbrows) and args[:cols_dbrows].index("#{key.to_s}_id") != nil
797
- sql_where += " AND #{table}`#{db.esc_col(key.to_s + "_id")}` = '#{db.esc(val.id)}'"
798
- found = true
799
- elsif args.key?(:cols_str) and match = key.match(/^([A-z_\d]+)_(search|has)$/) and args[:cols_str].index(match[1]) != nil
800
- if match[2] == "search"
801
- Knj::Strings.searchstring(val).each do |str|
802
- sql_where += " AND #{table}`#{db.esc_col(match[1])}` LIKE '%#{db.esc(str)}%'"
803
- end
804
- elsif match[2] == "has"
805
- if val
806
- sql_where += " AND #{table}`#{db.esc_col(match[1])}` != ''"
807
- else
808
- sql_where += " AND #{table}`#{db.esc_col(match[1])}` = ''"
809
- end
810
- end
811
-
812
- found = true
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
-
822
- found = true
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
-
826
- if match[2] == "day"
827
- sql_where += " AND DATE_FORMAT(#{table}`#{db.esc_col(match[1])}`, '%d %m %Y') = DATE_FORMAT('#{db.esc(val.dbstr)}', '%d %m %Y')"
828
- elsif match[2] == "month"
829
- sql_where += " AND DATE_FORMAT(#{table}`#{db.esc_col(match[1])}`, '%m %Y') = DATE_FORMAT('#{db.esc(val.dbstr)}', '%m %Y')"
830
- elsif match[2] == "from" or match[2] == "above"
831
- sql_where += " AND #{table}`#{db.esc_col(match[1])}` >= '#{db.esc(val.dbstr)}'"
832
- elsif match[2] == "to" or match[2] == "below"
833
- sql_where += " AND #{table}`#{db.esc_col(match[1])}` <= '#{db.esc(val.dbstr)}'"
834
- else
835
- raise "Unknown date-key: #{match[2]}."
836
- end
837
-
838
- found = true
839
- elsif args.key?(:cols_num) and match = key.match(/^(.+)_(from|to)$/) and args[:cols_num].index(match[1]) != nil
840
- if match[2] == "from"
841
- sql_where += " AND #{table}`#{db.esc_col(match[1])}` <= '#{db.esc(val)}'"
842
- elsif match[2] == "to"
843
- sql_where += " AND #{table}`#{db.esc_col(match[1])}` >= '#{db.esc(val)}'"
844
- else
845
- raise "Unknown method of treating cols-num-argument: #{match[2]}."
846
- end
847
-
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
853
- end
854
-
855
- list_args.delete(realkey) if found
856
- end
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
-
902
- if limit_from and limit_to
903
- sql_limit = " LIMIT #{limit_from}, #{limit_to}"
904
- end
905
-
906
- return {
907
- :sql_joins => sql_joins,
908
- :sql_where => sql_where,
909
- :sql_limit => sql_limit,
910
- :sql_order => sql_order
911
- }
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
934
- end
707
+ end
708
+ end
709
+
710
+ require "#{$knjpath}objects/objects_sqlhelper"