spiderfw 0.6.20 → 0.6.21

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 (63) hide show
  1. data/CHANGELOG +13 -0
  2. data/README.rdoc +8 -2
  3. data/Rakefile +49 -24
  4. data/VERSION +1 -1
  5. data/apps/app_server/controllers/app_server_controller.rb +3 -2
  6. data/apps/app_server/lib/git_app.rb +11 -2
  7. data/apps/config_editor/_init.rb +2 -1
  8. data/apps/config_editor/controllers/config_editor_controller.rb +7 -1
  9. data/apps/drb_server/script/start_server.rb +1 -1
  10. data/apps/servant/bin/spider-servant.rb +1 -1
  11. data/blueprints/home/{spider.gemfile → Gemfile} +18 -3
  12. data/blueprints/install/config.ru +1 -1
  13. data/lib/spiderfw/app.rb +7 -0
  14. data/lib/spiderfw/cmd/cmd.rb +1 -1
  15. data/lib/spiderfw/cmd/commands/app.rb +6 -2
  16. data/lib/spiderfw/cmd/commands/cert.rb +1 -0
  17. data/lib/spiderfw/cmd/commands/console.rb +1 -1
  18. data/lib/spiderfw/cmd/commands/content.rb +2 -2
  19. data/lib/spiderfw/cmd/commands/create.rb +1 -1
  20. data/lib/spiderfw/cmd/commands/model.rb +2 -2
  21. data/lib/spiderfw/cmd/commands/setup.rb +1 -1
  22. data/lib/spiderfw/cmd/commands/test.rb +1 -1
  23. data/lib/spiderfw/config/options/spider.rb +2 -1
  24. data/lib/spiderfw/controller/controller.rb +15 -4
  25. data/lib/spiderfw/controller/mixins/visual.rb +2 -0
  26. data/lib/spiderfw/http/adapters/cgi.rb +3 -3
  27. data/lib/spiderfw/http/adapters/mongrel.rb +2 -2
  28. data/lib/spiderfw/http/adapters/rack.rb +2 -2
  29. data/lib/spiderfw/http/adapters/webrick.rb +2 -2
  30. data/lib/spiderfw/http/server.rb +26 -11
  31. data/lib/spiderfw/i18n/cldr.rb +8 -6
  32. data/lib/spiderfw/i18n/javascript_parser.rb +1 -0
  33. data/lib/spiderfw/init.rb +2 -0
  34. data/lib/spiderfw/model/base_model.rb +13 -3
  35. data/lib/spiderfw/model/condition.rb +4 -0
  36. data/lib/spiderfw/model/mappers/db_mapper.rb +9 -8
  37. data/lib/spiderfw/model/mappers/mapper.rb +18 -10
  38. data/lib/spiderfw/model/migrations/drop_table.rb +20 -0
  39. data/lib/spiderfw/model/migrations/replace.rb +18 -13
  40. data/lib/spiderfw/model/migrations.rb +5 -0
  41. data/lib/spiderfw/model/mixins/tree.rb +1 -1
  42. data/lib/spiderfw/model/model.rb +3 -0
  43. data/lib/spiderfw/model/storage/db/adapters/oracle.rb +1 -1
  44. data/lib/spiderfw/model/storage/db/adapters/sqlite.rb +1 -1
  45. data/lib/spiderfw/model/storage/db/connectors/jdbc_oracle.rb +1 -1
  46. data/lib/spiderfw/model/storage/db/connectors/oci8.rb +1 -1
  47. data/lib/spiderfw/model/storage/db/db_schema.rb +4 -1
  48. data/lib/spiderfw/model/storage/db/dialects/no_total_rows.rb +1 -1
  49. data/lib/spiderfw/setup/app_manager.rb +11 -3
  50. data/lib/spiderfw/setup/app_server_client.rb +13 -7
  51. data/lib/spiderfw/setup/setup_task.rb +43 -0
  52. data/lib/spiderfw/setup/spider_setup_wizard.rb +1 -1
  53. data/lib/spiderfw/spider.rb +16 -3
  54. data/lib/spiderfw/templates/blocks/html.rb +2 -0
  55. data/lib/spiderfw/templates/layout.rb +10 -5
  56. data/lib/spiderfw/templates/resources/less.rb +11 -8
  57. data/lib/spiderfw/templates/template_blocks.rb +1 -1
  58. data/lib/spiderfw/test/capybara.rb +2 -1
  59. data/lib/spiderfw/test.rb +2 -1
  60. data/lib/spiderfw.rb +1 -4
  61. data/spider.gemspec +5 -2
  62. metadata +47 -18
  63. data/blueprints/home/Gemfile.disabled +0 -3
@@ -43,7 +43,12 @@ module Spider; module HTTP
43
43
 
44
44
  start = lambda{
45
45
  $SPIDER_WEB_SERVER = true
46
- require 'spiderfw'
46
+ begin
47
+ require 'spiderfw/init'
48
+ rescue Exception => exc
49
+ Spider.logger.error(exc)
50
+ return
51
+ end
47
52
  require 'spiderfw/controller/http_controller'
48
53
 
49
54
  port ||= Spider.conf.get('webserver.port')
@@ -54,11 +59,15 @@ module Spider; module HTTP
54
59
  server = Spider::HTTP.const_get(servers[server_name]).new
55
60
  ssl_server = nil
56
61
  Spider.startup
57
- if Spider.conf.get('devel.trace.extended')
58
- require 'ruby-debug'
59
- require 'spiderfw/utils/monkey/debugger'
60
- Debugger.start
61
- Debugger.post_mortem
62
+ begin
63
+ if Spider.conf.get('devel.trace.extended')
64
+ require 'ruby-debug'
65
+ require 'spiderfw/utils/monkey/debugger'
66
+ Debugger.start
67
+ Debugger.post_mortem
68
+ end
69
+ rescue Exception => exc
70
+ Spider.logger.warn "Unable to start debugger"
62
71
  end
63
72
 
64
73
  thread = Thread.new do
@@ -79,7 +88,7 @@ module Spider; module HTTP
79
88
  end
80
89
  end
81
90
  do_shutdown = lambda{
82
- Debugger.post_mortem = false
91
+ Debugger.post_mortem = false if defined?(Debugger)
83
92
  # debugger
84
93
  server.shutdown
85
94
  ssl_server.shutdown if ssl_server
@@ -95,7 +104,7 @@ module Spider; module HTTP
95
104
  ssl_thread.join if ssl_thread
96
105
  }
97
106
  if options[:daemonize]
98
- require 'spiderfw'
107
+ require 'spiderfw/init'
99
108
  require 'spiderfw/utils/fork'
100
109
  pid_file = File.join(Spider.paths[:var], 'run/server.pid')
101
110
  process_name = (options[:daemonize] == true) ? 'spider-server' : options[:daemonize]
@@ -117,9 +126,11 @@ module Spider; module HTTP
117
126
  if Spider.conf.get('webserver.respawn_on_change')
118
127
  Spider.start_loggers
119
128
  begin
120
- begin
129
+ gemfile = File.join(Spider.paths[:root], 'Gemfile')
130
+ gemfile_lock = File.join(Spider.paths[:root], 'Gemfile.lock')
131
+ if File.file?(gemfile) && File.file?(gemfile_lock)
132
+ require 'bundler'
121
133
  Bundler.require :default, Spider.runmode.to_sym
122
- rescue
123
134
  end
124
135
  spawner = Spawner.new({'spawn' => start})
125
136
  spawner.run('spawn')
@@ -132,7 +143,11 @@ module Spider; module HTTP
132
143
  unless spawner_started
133
144
  Spider.main_process_startup
134
145
  Spider.startup
135
- start.call
146
+ begin
147
+ start.call
148
+ rescue Exception => exc
149
+ Spider.logger.error(exc)
150
+ end
136
151
  end
137
152
  end
138
153
  end
@@ -40,8 +40,8 @@ module Spider; module I18n
40
40
  # FIXME: handle more efficiently
41
41
  d = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
42
42
  obj_d = d[object.wday]
43
- days = @cldr.calendar.days[options[:calendar].to_sym]
44
- months = @cldr.calendar.months[options[:calendar].to_sym]
43
+ days = @cldr.calendar.days[options[:calendar].to_sym][:format] || @cldr.calendar.days[options[:calendar].to_sym]
44
+ months = @cldr.calendar.months[options[:calendar].to_sym][:format] || @cldr.calendar.months[options[:calendar].to_sym]
45
45
  replacements = [
46
46
  [/y{1,4}/, '%Y'], # year don't use two digits year, they cause confusion [/y{1,2}/, '%y']
47
47
  [/M{5}/, months[:narrow][object.month.to_s]], [/M{4}/, months[:wide][object.month.to_s]], #month
@@ -115,9 +115,9 @@ module Spider; module I18n
115
115
  end
116
116
  end
117
117
 
118
- def day_names(format = :wide, calendar = self.default_calendar)
118
+ def day_names(format = :wide, context = :stand_alone, calendar = self.default_calendar)
119
119
  begin
120
- days = @cldr.calendar.days[calendar][format]
120
+ days = @cldr.calendar.days[calendar][format] || @cldr.calendar.days[calendar][context][format]
121
121
  return [days['sun'], days['mon'], days['tue'], days['wed'], days['thu'], days['fri'], days['sat']]
122
122
  rescue NoMethodError
123
123
  raise ArgumentError, "Calendar #{calendar} not found" unless @cldr.days[calendar]
@@ -126,10 +126,12 @@ module Spider; module I18n
126
126
 
127
127
  end
128
128
 
129
- def month_names(format = :wide, calendar = self.default_calendar)
129
+ def month_names(format = :wide, context = :stand_alone, calendar = self.default_calendar)
130
130
  months = []
131
131
  begin
132
- @cldr.calendar.months[calendar][format].each do |k, v|
132
+ # CLDR 1 doesn't have context, CLDR 2 does
133
+ months = @cldr.calendar.months[calendar][format] || @cldr.calendar.months[calendar][context][format]
134
+ months.each do |k, v|
133
135
  months[k.to_i] = v
134
136
  end
135
137
  rescue NoMethodError
@@ -1,5 +1,6 @@
1
1
  require 'gettext/tools'
2
2
  require 'spiderfw/templates/blocks/text'
3
+ require 'json'
3
4
 
4
5
  module Spider; module I18n
5
6
 
@@ -0,0 +1,2 @@
1
+ require 'spiderfw/spider'
2
+ Spider.init
@@ -957,6 +957,11 @@ module Spider; module Model
957
957
  def self.elements
958
958
  @elements
959
959
  end
960
+
961
+ # An array of non-integrated elements
962
+ def self.own_elements
963
+ elements_array.reject{ |el| el.integrated? }
964
+ end
960
965
 
961
966
  # An array of the model's Elements.
962
967
  def self.elements_array
@@ -1251,8 +1256,8 @@ module Spider; module Model
1251
1256
  self.load(values) || self.create(values)
1252
1257
  end
1253
1258
 
1254
- def self.get(values)
1255
- return self.new(values) unless Spider::Model.identity_mapper
1259
+ def self.get(values, static=false)
1260
+ return static ? self.static(values) : self.new(values) unless Spider::Model.identity_mapper
1256
1261
  values = [values] unless values.is_a?(Hash) || values.is_a?(Array)
1257
1262
  if values.is_a?(Array)
1258
1263
  vals = {}
@@ -1262,11 +1267,16 @@ module Spider; module Model
1262
1267
  values = vals
1263
1268
  end
1264
1269
  curr = Spider::Model.identity_mapper.get(self, values)
1270
+ curr.autoload = false if static
1265
1271
  return curr if curr
1266
- obj = self.new(values)
1272
+ obj = static ? self.static(values) : self.new(values)
1267
1273
  Spider::Model.identity_mapper.put(obj)
1268
1274
  obj
1269
1275
  end
1276
+
1277
+ def self.get_static(values)
1278
+ self.get(values, true)
1279
+ end
1270
1280
 
1271
1281
  def set_values(values)
1272
1282
  if (values.is_a? Hash)
@@ -144,6 +144,10 @@ module Spider; module Model
144
144
  sub.all_each_with_comparison{ |k, v, c| yield k, v, c }
145
145
  end
146
146
  end
147
+
148
+ def primary_keys_only?(model)
149
+ self.select{ |key, value| !model.elements[key] || !model.elements[key].primary_key? }.empty?
150
+ end
147
151
 
148
152
  # Returns the result of merging the condition with another one (does not modify the original condition).
149
153
  def +(condition)
@@ -595,8 +595,7 @@ module Spider; module Model; module Mappers
595
595
  el_join_info[jk[k.to_s.length+1..-1]] = jv
596
596
  end
597
597
  end
598
- if (v && model.mapper.have_references?(element.name) && v.select{ |key, value|
599
- !element.model.elements[key] || !element.model.elements[key].primary_key? }.empty?)
598
+ if v && model.mapper.have_references?(element.name) && v.primary_keys_only?(element.model)
600
599
  # 1/n <-> 1 with only primary keys
601
600
  element_cond = {:conj => 'AND', :values => [], :is_having => is_having}
602
601
  v.each_with_comparison do |el_k, el_v, el_comp|
@@ -781,20 +780,23 @@ module Spider; module Model; module Mappers
781
780
  joins = []
782
781
  el = nil
783
782
  # Spider::Logger.debug("GETTING DEEP JOIN TO #{dotted_element} (#{@model})")
783
+ cnt = 0
784
784
  parts.each do |part|
785
+ cnt += 1
785
786
  el = current_model.elements[part]
786
787
  raise "Can't find element #{part} in model #{current_model}" unless el
787
- if (el.integrated?)
788
+ next if have_references?(el) && cnt == parts.length
789
+ if el.integrated?
788
790
  joins << current_model.mapper.get_join(el.integrated_from)
789
791
  current_model = el.integrated_from.type
790
792
  el = current_model.elements[el.integrated_from_element]
791
793
  end
792
- if (el.model? && can_join?(el))
794
+ if el.model? && can_join?(el)
793
795
  joins << current_model.mapper.get_join(el)
794
796
  current_model = el.model
795
797
  end
796
798
  end
797
- while (el.integrated?)
799
+ while el.integrated? && !have_references?(el)
798
800
  joins << current_model.mapper.get_join(el.integrated_from)
799
801
  # joins << current_model.integrated_from.mapper.get_join(el.integrated_from_element)
800
802
  current_model = el.integrated_from.type
@@ -845,9 +847,8 @@ module Spider; module Model; module Mappers
845
847
  fields << [field, direction]
846
848
  else
847
849
  el_joins, el_model, el = get_deep_join(order_element)
848
- if (el.model?)
849
- # FIXME: integrated elements
850
- if el.model.storage != storage
850
+ if el.model?
851
+ if el_model.mapper.have_references?(el) || el.model.storage != storage
851
852
  el.model.primary_keys.each do |pk|
852
853
  fields << [el_model.mapper.schema.foreign_key_field(el.name, pk.name), direction]
853
854
  end
@@ -20,7 +20,6 @@ module Spider; module Model
20
20
  def initialize(model, storage)
21
21
  @model = model
22
22
  @storage = storage
23
- @raw_data = {}
24
23
  @options = {}
25
24
  @no_map_elements = {}
26
25
  @sequences = []
@@ -416,7 +415,10 @@ module Spider; module Model
416
415
 
417
416
  # Deletes an object, or objects according to a condition.
418
417
  # Will not delete with null condition (i.e. all objects) unless force is true
419
- def delete(obj_or_condition, force=false)
418
+ # Options can be:
419
+ # :keep_single_reverse: don't delete associations that have a single reverse.
420
+ # Useful when an object will be re-inserted with the same keys.
421
+ def delete(obj_or_condition, force=false, options={})
420
422
 
421
423
  def prepare_delete_condition(obj)
422
424
  condition = Condition.and
@@ -459,6 +461,7 @@ module Spider; module Model
459
461
  end
460
462
  vals << obj_vals
461
463
  assocs.each do |el|
464
+ next if el.has_single_reverse? && options[:keep_single_reverse]
462
465
  delete_element_associations(curr_obj, el)
463
466
  end
464
467
  end
@@ -580,7 +583,6 @@ module Spider; module Model
580
583
  @model.primary_keys.each{ |key| query.request[key] = true}
581
584
  expand_request(query.request, set) unless options[:no_expand_request] || !query.request.expandable?
582
585
  query = prepare_query(query, query_set)
583
- query.request.total_rows = true unless query.request.total_rows == false
584
586
  result = fetch(query)
585
587
  if !result || result.empty?
586
588
  set.each_current do |obj|
@@ -600,7 +602,6 @@ module Spider; module Model
600
602
  next unless obj
601
603
  merged_obj = merge_object(set, obj, query.request)
602
604
  merged[merged_obj.object_id] = true
603
- @raw_data[obj.object_id] = row
604
605
  end
605
606
  query.request.keys.each do |k, v|
606
607
  set.element_loaded(k) if have_references?(k)
@@ -932,8 +933,7 @@ module Spider; module Model
932
933
  next if k.is_a?(Spider::QueryFuncs::Function)
933
934
  next unless element = model.elements[k]
934
935
  changed_v = false
935
- if element.type < Spider::DataType && !v.is_a?(element.type)
936
- condition.delete(k)
936
+ if element.type < Spider::DataType && !v.is_a?(element.type) && element.type.force_wrap?
937
937
  begin
938
938
  v = element.type.from_value(v)
939
939
  changed_v = true
@@ -944,8 +944,10 @@ module Spider; module Model
944
944
  v = DateTime.parse(v)
945
945
  changed_v = true
946
946
  elsif element.model? && v.is_a?(Spider::Model::Condition)
947
- v = element.mapper.preprocess_condition(v)
948
- changed_v = true
947
+ unless v.primary_keys_only?(element.model)
948
+ v = element.mapper.preprocess_condition(v)
949
+ changed_v = true
950
+ end
949
951
  end
950
952
  if element.integrated?
951
953
  condition.delete(k)
@@ -953,15 +955,21 @@ module Spider; module Model
953
955
  integrated_from_element = element.integrated_from_element
954
956
  sub = condition.get_deep_obj
955
957
  sub.set(integrated_from_element, c, v)
956
- condition[integrated_from.name] = integrated_from.model.mapper.preprocess_condition(sub)
958
+ unless sub.primary_keys_only?(integrated_from.model)
959
+ sub = integrated_from.model.mapper.preprocess_condition(sub)
960
+ end
961
+ condition[integrated_from.name] = sub
957
962
  elsif element.junction? && !v.is_a?(BaseModel) && !v.is_a?(Hash) && !v.nil? # conditions on junction id don't make sense
958
963
  condition.delete(k)
959
- condition.set("#{k}.#{element.attributes[:junction_their_element]}", c, v)
964
+ sub = condition.get_deep_obj
965
+ sub.set(element.attributes[:junction_their_element], c, v)
966
+ condition[k] = element.model.mapper.preprocess_condition(sub)
960
967
  elsif changed_v
961
968
  condition.delete(k)
962
969
  condition.set(k, c, v)
963
970
  end
964
971
  end
972
+ condition
965
973
  end
966
974
 
967
975
  basic_preprocess(condition)
@@ -0,0 +1,20 @@
1
+ module Spider; module Migrations
2
+
3
+ class DropTable < IrreversibleMigration
4
+
5
+ def initialize(model, options={})
6
+ @model = model
7
+ @options = options
8
+ end
9
+
10
+ def run
11
+ table = @options[:table_name]
12
+ if !table
13
+ table = @model.mapper.schema.table.name
14
+ end
15
+ @model.mapper.storage.drop_table(table)
16
+ end
17
+
18
+ end
19
+
20
+ end; end
@@ -3,28 +3,33 @@ module Spider; module Migrations
3
3
  class Replace < Migration
4
4
 
5
5
  def initialize(model, element, values)
6
- @model = model
6
+ @models = model
7
+ @models = [@models] unless @models.is_a?(Enumerable)
7
8
  @element = element
8
9
  @values = values
9
10
  end
10
11
 
11
12
  def run
12
- field = @model.mapper.schema.field(@model.get_element(@element).name)
13
- table = @model.mapper.schema.table
14
- raise "Table #{table} does not have a field #{field}" unless field
15
- @values.each do |from, to|
16
- save = {
17
- :table => table,
18
- :values => {field => to},
19
- :condition => {:values => [[field, '=', from]]}
20
- }
21
- sql, bind_vars = @model.storage.sql_update(save)
22
- return @model.storage.execute(sql, *bind_vars)
13
+ @models.each do |model|
14
+ field = model.mapper.schema.field(model.get_element(@element).name)
15
+ table = model.mapper.schema.table
16
+ raise "Table #{table} does not have a field #{field}" unless field
17
+ @values.each do |from, to|
18
+ save = {
19
+ :table => table,
20
+ :values => {field => to},
21
+ :condition => {:values => [[field, '=', from]]}
22
+ }
23
+ sql, bind_vars = model.storage.sql_update(save)
24
+ model.storage.execute(sql, *bind_vars)
25
+ end
23
26
  end
24
27
  end
25
28
 
26
29
  def undo
27
- Replace.new(@model, @element, @values.invert).run
30
+ @models.each do |model|
31
+ Replace.new(model, @element, @values.invert).run
32
+ end
28
33
  end
29
34
 
30
35
  end
@@ -2,6 +2,7 @@ require 'spiderfw/model/migrations/migration'
2
2
  require 'spiderfw/model/migrations/irreversible_migration'
3
3
  require 'spiderfw/model/migrations/replace'
4
4
  require 'spiderfw/model/migrations/drop_element'
5
+ require 'spiderfw/model/migrations/drop_table'
5
6
 
6
7
  module Spider
7
8
 
@@ -14,6 +15,10 @@ module Spider
14
15
  def self.drop_element!(model, element, options={})
15
16
  Spider::Migrations::DropElement.new(model, element, options={})
16
17
  end
18
+
19
+ def self.drop_table!(model, options={})
20
+ Spider::Migrations::DropTable.new(model, element, options={})
21
+ end
17
22
 
18
23
 
19
24
  end
@@ -165,7 +165,7 @@ module Spider; module Model
165
165
  cnt += 1
166
166
  break if sub == self
167
167
  end
168
- cnt = nil if cnt = 0
168
+ cnt = nil if cnt == 0
169
169
  cnt
170
170
  end
171
171
 
@@ -230,6 +230,7 @@ module Spider
230
230
  end
231
231
  # Ruby 1.9: steps are not needed with ordered hashes
232
232
  data = [data] unless data.is_a?(Array)
233
+ loaded = []
233
234
  data.each do |step|
234
235
  step.each do |mod_name, mod_data|
235
236
  mod = const_get_full(mod_name)
@@ -248,9 +249,11 @@ module Spider
248
249
  end
249
250
  obj = mod.new(h)
250
251
  obj.insert
252
+ loaded << obj
251
253
  end
252
254
  end
253
255
  end
256
+ loaded
254
257
  end
255
258
 
256
259
  # Generic Model error.
@@ -67,7 +67,7 @@ module Spider; module Model; module Storage; module Db
67
67
  return nil unless curr[:last_executed]
68
68
  q = curr[:last_query].clone
69
69
  unless (q[:offset] || q[:limit])
70
- return curr[:last_result] ? curr[:last_result].length : nil
70
+ return curr[:last_result_length] ? curr[:last_result_length] : nil
71
71
  end
72
72
  q.delete(:offset); q.delete(:limit)
73
73
  q[:query_type] = :count
@@ -121,7 +121,7 @@ module Spider; module Model; module Storage; module Db
121
121
  return nil unless curr[:last_query]
122
122
  q = curr[:last_query]
123
123
  unless (q[:offset] || q[:limit])
124
- return curr[:last_result] ? curr[:last_result].length : nil
124
+ return curr[:last_result_length] ? curr[:last_result_length] : nil
125
125
  end
126
126
  q[:offset] = q[:limit] = nil
127
127
  q[:keys] = ["COUNT(*) AS N"]
@@ -257,8 +257,8 @@ module Spider; module Model; module Storage; module Db; module Connectors
257
257
  end
258
258
  if (res)
259
259
  unless block_given?
260
+ curr[:last_result_length] = result.length
260
261
  result.extend(StorageResult)
261
- curr[:last_result] = result
262
262
  return result
263
263
  end
264
264
  else
@@ -125,8 +125,8 @@ module Spider; module Model; module Storage; module Db; module Connectors
125
125
  end
126
126
  if (have_result)
127
127
  unless block_given?
128
+ curr[:last_result_length] = result.length
128
129
  result.extend(StorageResult)
129
- curr[:last_result] = result
130
130
  return result
131
131
  end
132
132
  else
@@ -267,7 +267,10 @@ module Spider; module Model; module Storage; module Db
267
267
  attr_reader :expression
268
268
 
269
269
  def initialize(table, name, type, attributes={})
270
- super
270
+ @table = table
271
+ @name = name.to_s
272
+ @type = type
273
+ @attributes = attributes
271
274
  @expression = attributes[:expression]
272
275
  end
273
276
 
@@ -6,7 +6,7 @@ module Spider; module Model; module Storage; module Db; module Dialects
6
6
  return nil unless @last_executed
7
7
  q = @last_query.clone
8
8
  unless (q[:offset] || q[:limit])
9
- return @last_result ? @last_result.length : nil
9
+ return @last_result_length ? @last_result_length : nil
10
10
  end
11
11
  q.delete(:offset); q.delete(:limit); q[:order]= []
12
12
  q[:query_type] = :count
@@ -4,6 +4,10 @@ require 'fileutils'
4
4
  module Spider
5
5
 
6
6
  class AppManager
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ end
7
11
 
8
12
  def self.installed?(app)
9
13
  require 'spiderfw/home'
@@ -269,7 +273,8 @@ module Spider
269
273
  require 'rubygems/package'
270
274
  client = AppServerClient.new(spec.app_server)
271
275
  print _("Fetching %s from server... ") % spec.app_id
272
- tmp_path = client.fetch_app(spec.app_id)
276
+ options[:branch] ||= 'master'
277
+ tmp_path = client.fetch_app(spec.app_id, options[:branch])
273
278
  Spider.output _("Fetched.")
274
279
  dest = File.join(@home_path, "apps/#{spec.app_id}")
275
280
  FileUtils.mkdir_p(dest)
@@ -307,8 +312,9 @@ module Spider
307
312
  app_path = File.join(@home_path, "apps", spec.id)
308
313
  app_repo = Git.open(app_path)
309
314
  Spider.output _("Updating %s from %s") % [spec.app_id, spec.git_repo]
315
+ options[:branch] ||= 'master'
310
316
  Dir.chdir(app_path) do
311
- app_repo.branch('master').checkout
317
+ app_repo.branch(options[:branch]).checkout
312
318
  end
313
319
  response = err = nil
314
320
  Dir.chdir(app_path) do
@@ -321,7 +327,7 @@ module Spider
321
327
  end
322
328
  Dir.chdir(app_path) do
323
329
  app_repo.reset('HEAD', :hard => true)
324
- app_repo.branch('master').checkout
330
+ app_repo.branch(options[:branch]).checkout
325
331
  end
326
332
 
327
333
  home_repo.add("apps/#{spec.id}")
@@ -401,11 +407,13 @@ module Spider
401
407
  end
402
408
  end
403
409
  done_tasks = []
410
+
404
411
 
405
412
  tasks.each do |task|
406
413
  Spider.output _("Running setup task #{path+'/'+task}...")
407
414
  t = Spider::SetupTask.load("#{path}/#{task}")
408
415
  t.app = app
416
+ raise "Can't run interactive task" if t.interactive? && !@options[:interactive]
409
417
  begin
410
418
  done_tasks << t
411
419
  t.do_sync
@@ -12,8 +12,8 @@ module Spider
12
12
  @url = url
13
13
  end
14
14
 
15
- def specs
16
- load_specs unless @specs
15
+ def specs(branch=nil)
16
+ load_specs(branch) unless @specs
17
17
  @specs
18
18
  end
19
19
 
@@ -34,29 +34,35 @@ module Spider
34
34
  end
35
35
 
36
36
  def load_specs
37
- result = http_get(@url+'/list.json')
37
+ url = @url+'/list.json'
38
+ result = http_get(url)
38
39
  list = JSON.parse(result)
39
40
  @specs = list.map{ |app| Spider::App::AppSpec.parse_hash(app) }
40
41
  end
41
42
 
42
43
  def get_specs(app_ids)
43
44
  app_ids = [app_ids] unless app_ids.is_a?(Array)
44
- result = http_get(@url+"/list/#{app_ids.join('+')}.json")
45
+ url = @url+"/list/#{app_ids.join('+')}.json"
46
+ result = http_get(url)
45
47
  JSON.parse(result).map{ |app| Spider::App::AppSpec.parse_hash(app) }
46
48
  end
47
49
 
48
50
  def get_deps(app_ids, options={})
49
51
  app_ids = [app_ids] unless app_ids.is_a?(Array)
50
52
  url = "#{@url}/deps/#{app_ids.join('+')}.json"
51
- url += "?no_optional=true" if options[:no_optional]
53
+ params = []
54
+ params << 'no_optional=true' if options[:no_optional]
55
+ url += '?'+params.join('&') unless params.empty?
52
56
  result = http_get(url)
53
57
  JSON.parse(result).map{ |app| Spider::App::AppSpec.parse_hash(app) }
54
58
  end
55
59
 
56
- def fetch_app(app_id)
60
+ def fetch_app(app_id, branch=nil)
57
61
  tmp = Tempfile.new("spider-app-archive")
58
62
  tmp.binmode
59
- res = http_get(@url+"/pack/#{app_id}")
63
+ url = @url+"/pack/#{app_id}"
64
+ url += "?branch=#{branch}" if branch
65
+ res = http_get(url)
60
66
  tmp << res
61
67
  tmp.flush
62
68
  tmp.path