knjrbfw 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (208) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +14 -0
  4. data/Gemfile.lock +32 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/lib/knj/.gitignore +1 -0
  10. data/lib/knj/arrayext.rb +157 -0
  11. data/lib/knj/autoload/activesupport.rb +2 -0
  12. data/lib/knj/autoload/backups/facets_dictionary.rb +430 -0
  13. data/lib/knj/autoload/backups/parsedate.rb +53 -0
  14. data/lib/knj/autoload/backups/ping.rb +64 -0
  15. data/lib/knj/autoload/cinch.rb +2 -0
  16. data/lib/knj/autoload/erubis.rb +6 -0
  17. data/lib/knj/autoload/facebooker.rb +3 -0
  18. data/lib/knj/autoload/facets_dictionary.rb +7 -0
  19. data/lib/knj/autoload/gd2.rb +2 -0
  20. data/lib/knj/autoload/gettext.rb +9 -0
  21. data/lib/knj/autoload/gtk2.rb +5 -0
  22. data/lib/knj/autoload/json_autoload.rb +7 -0
  23. data/lib/knj/autoload/magick.rb +6 -0
  24. data/lib/knj/autoload/mysql.rb +6 -0
  25. data/lib/knj/autoload/parsedate.rb +1 -0
  26. data/lib/knj/autoload/ping.rb +64 -0
  27. data/lib/knj/autoload/rexml.rb +12 -0
  28. data/lib/knj/autoload/soap.rb +3 -0
  29. data/lib/knj/autoload/sqlite3.rb +6 -0
  30. data/lib/knj/autoload/tmail.rb +6 -0
  31. data/lib/knj/autoload/twitter.rb +2 -0
  32. data/lib/knj/autoload/xmlsimple.rb +6 -0
  33. data/lib/knj/autoload/zip.rb +6 -0
  34. data/lib/knj/autoload.rb +136 -0
  35. data/lib/knj/compiler.rb +53 -0
  36. data/lib/knj/cpufreq.rb +40 -0
  37. data/lib/knj/datarow.rb +256 -0
  38. data/lib/knj/datestamp.rb +91 -0
  39. data/lib/knj/datet.rb +448 -0
  40. data/lib/knj/degulesider.rb +46 -0
  41. data/lib/knj/erb/apache_knjerb.conf +8 -0
  42. data/lib/knj/erb/cache/README +1 -0
  43. data/lib/knj/erb/erb.rb +21 -0
  44. data/lib/knj/erb/erb_1.9.rb +13 -0
  45. data/lib/knj/erb/erb_cache_clean.rb +20 -0
  46. data/lib/knj/erb/erb_fcgi.rb +44 -0
  47. data/lib/knj/erb/erb_fcgi_1.9.rb +44 -0
  48. data/lib/knj/erb/erb_fcgi_jruby.rb +7 -0
  49. data/lib/knj/erb/erb_jruby.rb +22 -0
  50. data/lib/knj/erb/include.rb +248 -0
  51. data/lib/knj/errors.rb +19 -0
  52. data/lib/knj/eruby.rb +224 -0
  53. data/lib/knj/event_filemod.rb +53 -0
  54. data/lib/knj/event_handler.rb +69 -0
  55. data/lib/knj/exchangerates.rb +39 -0
  56. data/lib/knj/ext/webrick.rb +31 -0
  57. data/lib/knj/filesystem.rb +8 -0
  58. data/lib/knj/fs/drivers/filesystem.rb +14 -0
  59. data/lib/knj/fs/drivers/ftp.rb +33 -0
  60. data/lib/knj/fs/drivers/ssh.rb +28 -0
  61. data/lib/knj/fs/fs.rb +36 -0
  62. data/lib/knj/gettext_fallback.rb +17 -0
  63. data/lib/knj/gettext_threadded.rb +77 -0
  64. data/lib/knj/google_sitemap.rb +59 -0
  65. data/lib/knj/gtk2.rb +277 -0
  66. data/lib/knj/gtk2_cb.rb +85 -0
  67. data/lib/knj/gtk2_menu.rb +57 -0
  68. data/lib/knj/gtk2_statuswindow.rb +64 -0
  69. data/lib/knj/gtk2_tv.rb +63 -0
  70. data/lib/knj/hash_methods.rb +37 -0
  71. data/lib/knj/http.rb +190 -0
  72. data/lib/knj/includes/appserver_cli.rb +39 -0
  73. data/lib/knj/ip2location.rb +22 -0
  74. data/lib/knj/ironruby-gtk2/button.rb +19 -0
  75. data/lib/knj/ironruby-gtk2/dialog.rb +44 -0
  76. data/lib/knj/ironruby-gtk2/entry.rb +9 -0
  77. data/lib/knj/ironruby-gtk2/gdk_event.rb +3 -0
  78. data/lib/knj/ironruby-gtk2/gdk_eventbutton.rb +13 -0
  79. data/lib/knj/ironruby-gtk2/gdk_pixbuf.rb +11 -0
  80. data/lib/knj/ironruby-gtk2/gladexml.rb +104 -0
  81. data/lib/knj/ironruby-gtk2/glib.rb +15 -0
  82. data/lib/knj/ironruby-gtk2/gtk2.rb +148 -0
  83. data/lib/knj/ironruby-gtk2/gtk_builder.rb +31 -0
  84. data/lib/knj/ironruby-gtk2/gtk_cellrenderertext.rb +5 -0
  85. data/lib/knj/ironruby-gtk2/gtk_combobox.rb +19 -0
  86. data/lib/knj/ironruby-gtk2/gtk_filechooserbutton.rb +5 -0
  87. data/lib/knj/ironruby-gtk2/gtk_liststore.rb +18 -0
  88. data/lib/knj/ironruby-gtk2/gtk_menu.rb +5 -0
  89. data/lib/knj/ironruby-gtk2/gtk_menuitem.rb +7 -0
  90. data/lib/knj/ironruby-gtk2/gtk_statusicon.rb +8 -0
  91. data/lib/knj/ironruby-gtk2/gtk_treeiter.rb +24 -0
  92. data/lib/knj/ironruby-gtk2/gtk_treeselection.rb +16 -0
  93. data/lib/knj/ironruby-gtk2/gtk_treeview.rb +19 -0
  94. data/lib/knj/ironruby-gtk2/gtk_treeviewcolumn.rb +32 -0
  95. data/lib/knj/ironruby-gtk2/iconsize.rb +3 -0
  96. data/lib/knj/ironruby-gtk2/image.rb +15 -0
  97. data/lib/knj/ironruby-gtk2/label.rb +19 -0
  98. data/lib/knj/ironruby-gtk2/stock.rb +4 -0
  99. data/lib/knj/ironruby-gtk2/tests/test.glade +15 -0
  100. data/lib/knj/ironruby-gtk2/tests/test_2.rb +22 -0
  101. data/lib/knj/ironruby-gtk2/tests/test_ironruby_window.rb +47 -0
  102. data/lib/knj/ironruby-gtk2/vbox.rb +5 -0
  103. data/lib/knj/ironruby-gtk2/window.rb +23 -0
  104. data/lib/knj/jruby-gtk2/builder/test_builder.glade +43 -0
  105. data/lib/knj/jruby-gtk2/builder/test_builder.rb +19 -0
  106. data/lib/knj/jruby-gtk2/builder/test_builder.ui +43 -0
  107. data/lib/knj/jruby-gtk2/builder.rb +27 -0
  108. data/lib/knj/jruby-gtk2/cellrenderertext.rb +12 -0
  109. data/lib/knj/jruby-gtk2/checkbutton.rb +3 -0
  110. data/lib/knj/jruby-gtk2/combobox.rb +29 -0
  111. data/lib/knj/jruby-gtk2/dialog.rb +44 -0
  112. data/lib/knj/jruby-gtk2/eventbutton.rb +21 -0
  113. data/lib/knj/jruby-gtk2/gladexml.rb +99 -0
  114. data/lib/knj/jruby-gtk2/gtk-4.0.jar +0 -0
  115. data/lib/knj/jruby-gtk2/gtk2.rb +246 -0
  116. data/lib/knj/jruby-gtk2/hbox.rb +10 -0
  117. data/lib/knj/jruby-gtk2/iconsize.rb +5 -0
  118. data/lib/knj/jruby-gtk2/image.rb +10 -0
  119. data/lib/knj/jruby-gtk2/liststore.rb +56 -0
  120. data/lib/knj/jruby-gtk2/menu.rb +40 -0
  121. data/lib/knj/jruby-gtk2/progressbar.rb +12 -0
  122. data/lib/knj/jruby-gtk2/statusicon.rb +8 -0
  123. data/lib/knj/jruby-gtk2/stock.rb +8 -0
  124. data/lib/knj/jruby-gtk2/tests/test_glade_window.glade +163 -0
  125. data/lib/knj/jruby-gtk2/tests/test_glade_window.rb +47 -0
  126. data/lib/knj/jruby-gtk2/tests/test_normal_window.rb +17 -0
  127. data/lib/knj/jruby-gtk2/tests/test_trayicon.png +0 -0
  128. data/lib/knj/jruby-gtk2/tests/test_trayicon.rb +18 -0
  129. data/lib/knj/jruby-gtk2/treeview.rb +105 -0
  130. data/lib/knj/jruby-gtk2/vbox.rb +12 -0
  131. data/lib/knj/jruby-gtk2/window.rb +11 -0
  132. data/lib/knj/jruby_compiler.rb +14 -0
  133. data/lib/knj/knj.rb +19 -0
  134. data/lib/knj/knj_controller.rb +13 -0
  135. data/lib/knj/knjdb/dbtime.rb +30 -0
  136. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +327 -0
  137. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +130 -0
  138. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +30 -0
  139. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +255 -0
  140. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +93 -0
  141. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +151 -0
  142. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_indexes.rb +29 -0
  143. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +300 -0
  144. data/lib/knj/knjdb/libknjdb.rb +438 -0
  145. data/lib/knj/knjdb/libknjdb_java_sqlite3.rb +83 -0
  146. data/lib/knj/knjdb/libknjdb_row.rb +149 -0
  147. data/lib/knj/knjdb/libknjdb_sqlite3_ironruby.rb +69 -0
  148. data/lib/knj/knjdb/mysql-connector-java-5.1.13-bin.jar +0 -0
  149. data/lib/knj/knjdb/sqlitejdbc-v056.jar +0 -0
  150. data/lib/knj/libqt.rb +75 -0
  151. data/lib/knj/libqt_window.rb +10 -0
  152. data/lib/knj/locale_strings.rb +3 -0
  153. data/lib/knj/locales.rb +54 -0
  154. data/lib/knj/maemo/fremantle-calendar/fremantle-calendar.rb +56 -0
  155. data/lib/knj/mail.rb +75 -0
  156. data/lib/knj/mailobj.rb +82 -0
  157. data/lib/knj/mount.rb +115 -0
  158. data/lib/knj/notify.rb +13 -0
  159. data/lib/knj/nvidia_settings.rb +45 -0
  160. data/lib/knj/objects.rb +731 -0
  161. data/lib/knj/opts.rb +38 -0
  162. data/lib/knj/os.rb +158 -0
  163. data/lib/knj/php.rb +717 -0
  164. data/lib/knj/php_parser/arguments.rb +5 -0
  165. data/lib/knj/php_parser/functions.rb +97 -0
  166. data/lib/knj/php_parser/php_parser.rb +99 -0
  167. data/lib/knj/php_parser/tests/test.rb +12 -0
  168. data/lib/knj/php_parser/tests/test_function.php +8 -0
  169. data/lib/knj/php_parser/tests/test_function_run.rb +19 -0
  170. data/lib/knj/power_manager.rb +31 -0
  171. data/lib/knj/rand.rb +10 -0
  172. data/lib/knj/retry.rb +71 -0
  173. data/lib/knj/rhodes/mutex.rb +11 -0
  174. data/lib/knj/rhodes/rhodes.js +3 -0
  175. data/lib/knj/rhodes/rhodes.rb +11 -0
  176. data/lib/knj/rsvgbin.rb +20 -0
  177. data/lib/knj/scripts/degulesider.rb +12 -0
  178. data/lib/knj/scripts/filesearch.rb +51 -0
  179. data/lib/knj/scripts/ip2location.rb +12 -0
  180. data/lib/knj/scripts/keepalive.rb +6 -0
  181. data/lib/knj/scripts/svn_merge.rb +29 -0
  182. data/lib/knj/scripts/upgrade_knjrbfw_checker.rb +41 -0
  183. data/lib/knj/sms.rb +54 -0
  184. data/lib/knj/sshrobot/sshrobot.rb +93 -0
  185. data/lib/knj/strings.rb +65 -0
  186. data/lib/knj/sysuser.rb +27 -0
  187. data/lib/knj/tests/compiler/compiler_test.rb +13 -0
  188. data/lib/knj/tests/compiler/compiler_test_file.rb +62 -0
  189. data/lib/knj/tests/test_degulesider.rb +11 -0
  190. data/lib/knj/tests/test_mount.rb +30 -0
  191. data/lib/knj/tests/test_retry.rb +30 -0
  192. data/lib/knj/thread.rb +32 -0
  193. data/lib/knj/thread2.rb +47 -0
  194. data/lib/knj/threadhandler.rb +130 -0
  195. data/lib/knj/threadpool.rb +177 -0
  196. data/lib/knj/translations.rb +139 -0
  197. data/lib/knj/unix_proc.rb +82 -0
  198. data/lib/knj/web.rb +932 -0
  199. data/lib/knj/webscripts/image.rhtml +82 -0
  200. data/lib/knj/win.rb +4 -0
  201. data/lib/knj/win_registry.rb +60 -0
  202. data/lib/knj/win_tightvnc.rb +127 -0
  203. data/lib/knj/x11vnc.rb +48 -0
  204. data/lib/knj/youtube.rb +38 -0
  205. data/lib/knjrbfw.rb +4 -0
  206. data/spec/knjrbfw_spec.rb +269 -0
  207. data/spec/spec_helper.rb +12 -0
  208. metadata +336 -0
@@ -0,0 +1,731 @@
1
+ class Knj::Objects
2
+ attr_reader :args, :events
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
+ @objects = {}
11
+ @objects_mutex = Mutex.new
12
+
13
+ @events = Knj::Event_handler.new
14
+ @events.add_event(
15
+ :name => :no_html,
16
+ :connections_max => 1
17
+ )
18
+
19
+ raise "No DB given." if !@args[:db]
20
+ raise "No class path given." if !@args[:class_path] and (@args[:require] or !@args.has_key?(:require))
21
+ end
22
+
23
+ #Returns a cloned version of the @objects variable. Cloned because iteration on it may crash some of the other methods in Ruby 1.9+
24
+ def objects
25
+ objs_cloned = {}
26
+
27
+ @objects_mutex.synchronize do
28
+ @objects.each do |classn, newhash|
29
+ objs_cloned[classn] = newhash.clone
30
+ end
31
+ end
32
+
33
+ return objs_cloned
34
+ end
35
+
36
+ def db
37
+ return @args[:db]
38
+ end
39
+
40
+ def count_objects
41
+ count = 0
42
+ @objects_mutex.synchronize do
43
+ @objects.each do |key, value|
44
+ value.each do |id, object|
45
+ count += 1
46
+ end
47
+ end
48
+ end
49
+
50
+ return count
51
+ end
52
+
53
+ def connect(args, &block)
54
+ raise "No object given." if !args["object"]
55
+ raise "No signals given." if !args.has_key?("signal") and !args.has_key?("signals")
56
+ args["block"] = block if block_given?
57
+ @callbacks[args["object"]] = {} if !@callbacks[args["object"]]
58
+ conn_id = @callbacks[args["object"]].length.to_s
59
+ @callbacks[args["object"]][conn_id] = args
60
+ end
61
+
62
+ def call(args, &block)
63
+ classstr = args["object"].class.to_s
64
+
65
+ if @callbacks[classstr]
66
+ @callbacks[classstr].clone.each do |callback_key, callback|
67
+ docall = false
68
+
69
+ if callback.has_key?("signal") and args.has_key?("signal") and callback["signal"] == args["signal"]
70
+ docall = true
71
+ elsif callback["signals"] and args["signal"] and callback["signals"].index(args["signal"]) != nil
72
+ docall = true
73
+ end
74
+
75
+ next if !docall
76
+
77
+ if callback["block"]
78
+ callargs = []
79
+ arity = callback["block"].arity
80
+ if arity <= 0
81
+ #do nothing
82
+ elsif arity == 1
83
+ callargs << args["object"]
84
+ else
85
+ raise "Unknown number of arguments: #{arity}"
86
+ end
87
+
88
+ callback["block"].call(*callargs)
89
+ elsif callback["callback"]
90
+ Knj::Php.call_user_func(callback["callback"], args)
91
+ else
92
+ raise "No valid callback given."
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ def requireclass(classname)
99
+ return nil if !@args[:require] and @args.has_key?(:require)
100
+ classname = classname.to_s
101
+
102
+ if !Knj::Php.class_exists(classname)
103
+ filename = @args[:class_path] + "/#{@args[:class_pre]}#{classname.downcase}.rb"
104
+ filename_req = @args[:class_path] + "/#{@args[:class_pre]}#{classname.downcase}"
105
+ raise "Class file could not be found: #{filename}." if !File.exists?(filename)
106
+ require filename_req
107
+ end
108
+ end
109
+
110
+ def get(classname, data)
111
+ classname = classname.to_sym
112
+
113
+ if data.is_a?(Hash) and data[@args[:col_id].to_sym]
114
+ id = data[@args[:col_id].to_sym].to_i
115
+ elsif data.is_a?(Hash) and data[@args[:col_id].to_s]
116
+ id = data[@args[:col_id].to_s].to_i
117
+ elsif data.is_a?(Integer) or data.is_a?(String) or data.is_a?(Fixnum)
118
+ id = data.to_i
119
+ elsif
120
+ raise Knj::Errors::InvalidData, "Unknown data: '#{data.class.to_s}'."
121
+ end
122
+
123
+ return @objects[classname][id] if @objects.has_key?(classname) and @objects[classname].has_key?(id)
124
+
125
+ retobj = nil
126
+ @objects_mutex.synchronize do
127
+ if !@objects.has_key?(classname)
128
+ self.requireclass(classname)
129
+ @objects[classname] = {}
130
+ end
131
+
132
+ if @args[:datarow]
133
+ @objects[classname][id] = @args[:module].const_get(classname).new(Knj::Hash_methods.new(
134
+ :ob => self,
135
+ :data => data
136
+ ))
137
+ else
138
+ args = [data]
139
+ args = args | @args[:extra_args] if @args[:extra_args]
140
+ @objects[classname][id] = @args[:module].const_get(classname).new(*args)
141
+ end
142
+
143
+ return @objects[classname][id]
144
+ end
145
+
146
+ raise "Something went wrong."
147
+ end
148
+
149
+ def get_by(classname, args = {})
150
+ classname = classname.to_sym
151
+ self.requireclass(classname)
152
+ classob = @args[:module].const_get(classname)
153
+
154
+ raise "list-function has not been implemented for #{classname}" if !classob.respond_to?("list")
155
+
156
+ args[:limit_from] = 0
157
+ args[:limit_to] = 1
158
+
159
+ self.list(classname, args) do |obj|
160
+ return obj
161
+ end
162
+
163
+ return false
164
+ end
165
+
166
+ def get_try(obj, col_name, obj_name = nil)
167
+ if !obj_name
168
+ if match = col_name.to_s.match(/^(.+)_id$/)
169
+ obj_name = Knj::Php.ucwords(match[1]).to_sym
170
+ else
171
+ raise "Could not figure out objectname for: #{col_name}."
172
+ end
173
+ end
174
+
175
+ id_data = obj[col_name].to_i
176
+ return false if !id_data
177
+
178
+ begin
179
+ return self.get(obj_name, id_data)
180
+ rescue Knj::Errors::NotFound
181
+ return false
182
+ end
183
+ end
184
+
185
+ def list(classname, args = {}, &block)
186
+ classname = classname.to_sym
187
+ self.requireclass(classname)
188
+ classob = @args[:module].const_get(classname)
189
+
190
+ raise "list-function has not been implemented for #{classname}" if !classob.respond_to?("list")
191
+
192
+ if @args[:datarow]
193
+ ret = classob.list(Knj::Hash_methods.new(:args => args, :ob => self, :db => @args[:db]))
194
+ else
195
+ realargs = [args]
196
+ realargs = realargs | @args[:extra_args] if @args[:extra_args]
197
+ ret = classob.list(*realargs)
198
+ end
199
+
200
+ if block_given?
201
+ ret.each do |obj|
202
+ yield(obj)
203
+ end
204
+ else
205
+ return ret
206
+ end
207
+ end
208
+
209
+ def list_opts(classname, args = {})
210
+ Knj::ArrayExt.hash_sym(args)
211
+ classname = classname.to_sym
212
+
213
+ if args[:list_args]
214
+ obs = self.list(classname, args[:list_args])
215
+ else
216
+ obs = self.list(classname)
217
+ end
218
+
219
+ html = ""
220
+
221
+ if args[:addnew] or args[:add]
222
+ html += "<option"
223
+ html += " selected=\"selected\"" if !args[:selected]
224
+ html += " value=\"\">#{_("Add new")}</option>"
225
+ end
226
+
227
+ obs.each do |object|
228
+ html += "<option value=\"#{object.id.html}\""
229
+
230
+ selected = false
231
+ if args[:selected].is_a?(Array) and args[:selected].index(object) != nil
232
+ selected = true
233
+ elsif args[:selected] and args[:selected].respond_to?("is_knj?") and args[:selected].id.to_s == object.id.to_s
234
+ selected = true
235
+ end
236
+
237
+ html += " selected=\"selected\"" if selected
238
+
239
+ obj_methods = object.class.instance_methods(false)
240
+
241
+ begin
242
+ if obj_methods.index("name") != nil or obj_methods.index(:name) != nil
243
+ objhtml = object.name.html
244
+ elsif obj_methods.index("title") != nil or obj_methods.index(:title) != nil
245
+ objhtml = object.title.html
246
+ elsif object.respond_to?(:data)
247
+ obj_data = object.data
248
+
249
+ if obj_data.has_key?(:name)
250
+ objhtml = obj_data[:name]
251
+ elsif obj_data.has_key?(:title)
252
+ objhtml = obj_data[:title]
253
+ end
254
+ else
255
+ objhtml = ""
256
+ end
257
+
258
+ raise "Could not figure out which name-method to call?" if !objhtml
259
+ html += ">#{objhtml}</option>"
260
+ rescue Exception => e
261
+ html += ">[#{object.class.name}: #{e.message}]</option>"
262
+ end
263
+ end
264
+
265
+ return html
266
+ end
267
+
268
+ def list_optshash(classname, args = {})
269
+ Knj::ArrayExt.hash_sym(args)
270
+ classname = classname.to_sym
271
+
272
+ if args[:list_args]
273
+ obs = self.list(classname, args[:list_args])
274
+ else
275
+ obs = self.list(classname)
276
+ end
277
+
278
+ if Knj::Php.class_exists("Dictionary")
279
+ list = Dictionary.new
280
+ else
281
+ list = Hash.new
282
+ end
283
+
284
+ if args[:addnew] or args[:add]
285
+ list["0"] = _("Add new")
286
+ elsif args[:choose]
287
+ list["0"] = _("Choose") + ":"
288
+ elsif args[:all]
289
+ list["0"] = _("All")
290
+ elsif args[:none]
291
+ list["0"] = _("None")
292
+ end
293
+
294
+ obs.each do |object|
295
+ list[object.id] = object.title
296
+ end
297
+
298
+ return list
299
+ end
300
+
301
+ # Returns a list of a specific object by running specific SQL against the database.
302
+ def list_bysql(classname, sql)
303
+ classname = classname.to_sym
304
+
305
+ ret = [] if !block_given?
306
+ @args[:db].q(sql) do |d_obs|
307
+ if block_given?
308
+ yield(self.get(classname, d_obs))
309
+ else
310
+ ret << self.get(classname, d_obs)
311
+ end
312
+ end
313
+
314
+ return ret if !block_given?
315
+ end
316
+
317
+ # Add a new object to the database and to the cache.
318
+ def add(classname, data = {})
319
+ classname = classname.to_sym
320
+ self.requireclass(classname)
321
+
322
+ args = [data]
323
+ args = args | @args[:extra_args] if @args[:extra_args]
324
+
325
+ if @args[:datarow]
326
+ classobj = @args[:module].const_get(classname)
327
+ if classobj.respond_to?(:add)
328
+ classobj.add(Knj::Hash_methods.new(
329
+ :ob => self,
330
+ :db => self.db,
331
+ :data => data
332
+ ))
333
+ end
334
+
335
+ required_data = classobj.required_data
336
+ required_data.each do |req_data|
337
+ if !data.has_key?(req_data[:col])
338
+ raise "No '#{req_data[:class]}' given by the data '#{req_data[:col]}'."
339
+ end
340
+
341
+ begin
342
+ obj = self.get(req_data[:class], data[req_data[:col]])
343
+ rescue Knj::Errors::NotFound
344
+ raise "The '#{req_data[:class]}' by ID '#{data[req_data[:col]]}' could not be found with the data '#{req_data[:col]}'."
345
+ end
346
+ end
347
+
348
+ ins_id = @args[:db].insert(classname, data, {:return_id => true})
349
+ retob = self.get(classname, ins_id)
350
+ else
351
+ retob = @args[:module].const_get(classname).add(*args)
352
+ end
353
+
354
+ self.call("object" => retob, "signal" => "add")
355
+ if retob.respond_to?(:add_after)
356
+ retob.send(:add_after, {})
357
+ end
358
+
359
+ return retob
360
+ end
361
+
362
+ def adds(classname, datas)
363
+ if !@args[:datarow]
364
+ datas.each do |data|
365
+ @args[:module].const_get(classname).add(*args)
366
+ self.call("object" => retob, "signal" => "add")
367
+ end
368
+ else
369
+ if @args[:module].const_get(classname).respond_to?(:add)
370
+ datas.each do |data|
371
+ @args[:module].const_get(classname).add(Knj::Hash_methods.new(
372
+ :ob => self,
373
+ :db => self.db,
374
+ :data => data
375
+ ))
376
+ end
377
+ end
378
+
379
+ db.insert_multi(classname, datas)
380
+ end
381
+ end
382
+
383
+ def static(class_name, method_name, *args)
384
+ raise "Only available with datarow enabled." if !@args[:datarow]
385
+ class_name = class_name.to_sym
386
+ method_name = method_name.to_sym
387
+
388
+ self.requireclass(class_name)
389
+ class_obj = @args[:module].const_get(class_name)
390
+ raise "The class '#{class_obj.name}' has no such method: '#{method_name}'." if !class_obj.respond_to?(method_name)
391
+ method_obj = class_obj.method(method_name)
392
+
393
+ pass_args = []
394
+ pass_args << Knj::Hash_methods.new(
395
+ :ob => self,
396
+ :db => self.db
397
+ )
398
+
399
+ args.each do |arg|
400
+ pass_args << arg
401
+ end
402
+
403
+ method_obj.call(*pass_args)
404
+ end
405
+
406
+ # Unset object. Do this if you are sure, that there are no more references left. This will be done automatically when deleting it.
407
+ def unset(object)
408
+ if object.is_a?(Array)
409
+ object.each do |obj|
410
+ unset(obj)
411
+ end
412
+ return nil
413
+ end
414
+
415
+ classname = object.class.name
416
+
417
+ if @args[:module]
418
+ classname = classname.gsub(@args[:module].name + "::", "")
419
+ end
420
+
421
+ classname = classname.to_sym
422
+
423
+ #if !@objects.has_key?(classname)
424
+ #raise "Could not find object class in cache: #{classname}."
425
+ #elsif !@objects[classname].has_key?(object.id.to_i)
426
+ #errstr = ""
427
+ #errstr += "Could not unset object from cache.\n"
428
+ #errstr += "Class: #{object.class.name}.\n"
429
+ #errstr += "ID: #{object.id}.\n"
430
+ #errstr += "Could not find object ID in cache."
431
+ #raise errstr
432
+ #else
433
+ @objects_mutex.synchronize do
434
+ @objects[classname].delete(object.id.to_i)
435
+ end
436
+ #end
437
+ end
438
+
439
+ def unset_class(classname)
440
+ if classname.is_a?(Array)
441
+ classname.each do |classn|
442
+ self.unset_class(classn)
443
+ end
444
+
445
+ return false
446
+ end
447
+
448
+ classname = classname.to_sym
449
+
450
+ return false if !@objects.has_key?(classname)
451
+ @objects_mutex.synchronize do
452
+ @objects[classname] = {}
453
+ end
454
+ end
455
+
456
+ # Delete an object. Both from the database and from the cache.
457
+ def delete(object)
458
+ self.call("object" => object, "signal" => "delete_before")
459
+ self.unset(object)
460
+ obj_id = object.id
461
+ object.delete if object.respond_to?(:delete)
462
+
463
+ if @args[:datarow]
464
+ object.class.depending_data.each do |dep_data|
465
+ objs = self.list(dep_data[:classname], {dep_data[:colname].to_s => object.id, "limit" => 1})
466
+ if !objs.empty?
467
+ raise "Cannot delete <#{object.class.name}:#{object.id}> because <#{objs[0].class.name}:#{objs[0].id}> depends on it."
468
+ end
469
+ end
470
+
471
+ @args[:db].delete(object.table, {:id => obj_id})
472
+ end
473
+
474
+ self.call("object" => object, "signal" => "delete")
475
+ object.destroy
476
+ end
477
+
478
+ def deletes(objs)
479
+ if !@args[:datarow]
480
+ objs.each do |obj|
481
+ self.delete(obj)
482
+ end
483
+ else
484
+ arr_ids = []
485
+ ids = []
486
+ objs.each do |obj|
487
+ ids << obj.id
488
+ if ids.length >= 1000
489
+ arr_ids << ids
490
+ ids = []
491
+ end
492
+
493
+ obj.delete if obj.respond_to?(:delete)
494
+ end
495
+
496
+ arr_ids << ids if ids.length > 0
497
+ arr_ids.each do |ids|
498
+ @args[:db].delete(objs[0].table, {:id => ids})
499
+ end
500
+ end
501
+ end
502
+
503
+ # 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.
504
+ def clean(classn)
505
+ if classn.is_a?(Array)
506
+ classn.each do |realclassn|
507
+ self.clean(realclassn)
508
+ end
509
+ else
510
+ return false if !@objects.has_key?(classn)
511
+ @objects_mutex.synchronize do
512
+ @objects[classn] = {}
513
+ GC.start
514
+ end
515
+ end
516
+ end
517
+
518
+ def clean_all
519
+ classnames = []
520
+ @objects_mutex.synchronize do
521
+ @objects.each do |classn, hash_list|
522
+ classnames << classn
523
+ end
524
+
525
+ classnames.each do |classn|
526
+ @objects[classn] = {}
527
+ end
528
+ end
529
+
530
+ GC.start
531
+ end
532
+
533
+ def clean_recover
534
+ @objects_mutex.synchronize do
535
+ @objects.each do |classn, hash_list|
536
+ classobj = Kernel.const_get(classn)
537
+ ObjectSpace.each_object(classobj) do |obj|
538
+ @objects[classn][obj.id] = obj
539
+ end
540
+ end
541
+ end
542
+ end
543
+
544
+ def sqlhelper(list_args, args)
545
+ if args[:db]
546
+ db = args[:db]
547
+ else
548
+ db = @args[:db]
549
+ end
550
+
551
+ if args[:table]
552
+ table = "`#{db.esc_table(args[:table])}`."
553
+ else
554
+ table = ""
555
+ end
556
+
557
+ sql_where = ""
558
+ sql_order = ""
559
+ sql_limit = ""
560
+
561
+ limit_from = nil
562
+ limit_to = nil
563
+
564
+ cols_str_has = args.has_key?(:cols_str)
565
+ cols_num_has = args.has_key?(:cols_num)
566
+ cols_date_has = args.has_key?(:cols_date)
567
+ cols_dbrows_has = args.has_key?(:cols_dbrows)
568
+ cols_bools_has = args.has_key?(:cols_bools)
569
+
570
+ if list_args.has_key?("orderby")
571
+ orders = []
572
+ orderstr = list_args["orderby"]
573
+
574
+ if list_args["orderby"].is_a?(String)
575
+ found = false
576
+ found = true if !found and cols_str_has and args[:cols_str].index(orderstr) != nil
577
+ found = true if !found and cols_date_has and args[:cols_date].index(orderstr) != nil
578
+ found = true if !found and cols_num_has and args[:cols_num].index(orderstr) != nil
579
+
580
+ if found
581
+ sql_order += " ORDER BY "
582
+ ordermode = " ASC"
583
+ if list_args.has_key?("ordermode")
584
+ if list_args["ordermode"] == "desc"
585
+ ordermode = " DESC"
586
+ elsif list_args["ordermode"] == "asc"
587
+ ordermode = " ASC"
588
+ raise "Unknown ordermode: #{list_args["ordermode"]}"
589
+ end
590
+
591
+ list_args.delete("ordermode")
592
+ end
593
+
594
+ sql_order += "#{table}`#{db.esc_col(list_args["orderby"])}`#{ordermode}"
595
+ list_args.delete("orderby")
596
+ end
597
+ elsif list_args["orderby"].is_a?(Array)
598
+ sql_order += " ORDER BY "
599
+
600
+ list_args["orderby"].each do |val|
601
+ if val.is_a?(Array)
602
+ orderstr = val[0]
603
+
604
+ if val[1] == "asc"
605
+ ordermode = " ASC"
606
+ elsif val[1] == "desc"
607
+ ordermode = "DESC"
608
+ end
609
+ elsif val.is_a?(String)
610
+ orderstr = val
611
+ ordermode = " ASC"
612
+ else
613
+ raise "Unknown object: #{val.class.name}"
614
+ end
615
+
616
+ found = false
617
+ found = true if !found and cols_str_has and args[:cols_str].index(orderstr) != nil
618
+ found = true if !found and cols_date_has and args[:cols_date].index(orderstr) != nil
619
+ found = true if !found and cols_num_has and args[:cols_num].index(orderstr) != nil
620
+ found = true if !found and cols_bools_has and args[:cols_bools].index(orderstr) != nil
621
+
622
+ raise "Column not found for ordering: #{orderstr}." if !found
623
+ orders << "#{table}`#{db.esc_col(orderstr)}`#{ordermode}"
624
+ end
625
+
626
+ sql_order += orders.join(", ")
627
+ list_args.delete("orderby")
628
+ else
629
+ raise "Unknown orderby object: #{list_args["orderby"].class.name}."
630
+ end
631
+ end
632
+
633
+ list_args.each do |key, val|
634
+ found = false
635
+
636
+ 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)
637
+ if val.is_a?(Array)
638
+ escape_sql = Knj::ArrayExt.join(
639
+ :arr => val,
640
+ :callback => proc{|value|
641
+ db.escape(value)
642
+ },
643
+ :sep => ",",
644
+ :surr => "'")
645
+ sql_where += " AND #{table}`#{db.esc_col(key)}` IN (#{escape_sql})"
646
+ else
647
+ sql_where += " AND #{table}`#{db.esc_col(key)}` = '#{db.esc(val)}'"
648
+ end
649
+
650
+ found = true
651
+ elsif cols_bools_has and args[:cols_bools].index(key) != nil
652
+ 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"))
653
+ realval = "1"
654
+ 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"))
655
+ realval = "0"
656
+ else
657
+ raise "Could not make real value out of class: #{val.class.name} => #{val}."
658
+ end
659
+
660
+ sql_where += " AND #{table}`#{db.esc_col(key)}` = '#{db.esc(realval)}'"
661
+ found = true
662
+ elsif key.to_s == "limit_from"
663
+ limit_from = val.to_i
664
+ found = true
665
+ elsif key.to_s == "limit_to"
666
+ limit_to = val.to_i
667
+ found = true
668
+ elsif key.to_s == "limit"
669
+ limit_from = 0
670
+ limit_to = val.to_i
671
+ found = true
672
+ elsif cols_dbrows_has and args[:cols_dbrows].index(key.to_s + "_id") != nil
673
+ sql_where += " AND #{table}`#{db.esc_col(key.to_s + "_id")}` = '#{db.esc(val.id)}'"
674
+ found = true
675
+ elsif cols_str_has and match = key.match(/^([A-z_\d]+)_(search|has)$/) and args[:cols_str].index(match[1]) != nil
676
+ if match[2] == "search"
677
+ Knj::Strings.searchstring(val).each do |str|
678
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` LIKE '%#{db.esc(str)}%'"
679
+ end
680
+ elsif match[2] == "has"
681
+ if val
682
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` != ''"
683
+ else
684
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` = ''"
685
+ end
686
+ end
687
+
688
+ found = true
689
+ 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))
690
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` != '#{db.esc(val)}'"
691
+ found = true
692
+ elsif cols_date_has and match = key.match(/^(.+)_(day|month|from|to)$/) and args[:cols_date].index(match[1]) != nil
693
+ if match[2] == "day"
694
+ sql_where += " AND DATE_FORMAT(#{table}`#{db.esc_col(match[1])}`, '%d %m %Y') = DATE_FORMAT('#{db.esc(val.dbstr)}', '%d %m %Y')"
695
+ elsif match[2] == "month"
696
+ sql_where += " AND DATE_FORMAT(#{table}`#{db.esc_col(match[1])}`, '%m %Y') = DATE_FORMAT('#{db.esc(val.dbstr)}', '%m %Y')"
697
+ elsif match[2] == "from"
698
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` >= '#{db.esc(val.dbstr)}'"
699
+ elsif match[2] == "to"
700
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` <= '#{db.esc(val.dbstr)}'"
701
+ else
702
+ raise "Unknown date-key: #{match[2]}."
703
+ end
704
+
705
+ found = true
706
+ elsif cols_num_has and match = key.match(/^(.+)_(from|to)$/) and args[:cols_num].index(match[1]) != nil
707
+ if match[2] == "from"
708
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` <= '#{db.esc(val)}'"
709
+ elsif match[2] == "to"
710
+ sql_where += " AND #{table}`#{db.esc_col(match[1])}` >= '#{db.esc(val)}'"
711
+ else
712
+ raise "Unknown method of treating cols-num-argument: #{match[2]}."
713
+ end
714
+
715
+ found = true
716
+ end
717
+
718
+ list_args.delete(key) if found
719
+ end
720
+
721
+ if limit_from and limit_to
722
+ sql_limit = " LIMIT #{limit_from}, #{limit_to}"
723
+ end
724
+
725
+ return {
726
+ :sql_where => sql_where,
727
+ :sql_limit => sql_limit,
728
+ :sql_order => sql_order
729
+ }
730
+ end
731
+ end