handle invalid token more gracefully
[arvados.git] / app / models / orvos_base.rb
1 class OrvosBase < ActiveRecord::Base
2   self.abstract_class = true
3
4   def self.columns
5     return @columns unless @columns.nil?
6     @columns = []
7     return @columns if $orvos_api_client.orvos_schema[self.to_s.to_sym].nil?
8     $orvos_api_client.orvos_schema[self.to_s.to_sym].each do |coldef|
9       k = coldef[:name].to_sym
10       if coldef[:type] == coldef[:type].downcase
11         @columns << column(k, coldef[:type].to_sym)
12       else
13         @columns << column(k, :text)
14         serialize k, coldef[:type].constantize
15       end
16       attr_accessible k
17     end
18     attr_reader :etag
19     attr_reader :kind
20     @columns
21   end
22   def self.column(name, sql_type = nil, default = nil, null = true)
23     ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
24   end
25   def self.find(uuid)
26     new($orvos_api_client.api(self, '/' + uuid))
27   end
28   def self.where(*args)
29     OrvosResourceList.new(self).where(*args)
30   end
31   def self.eager(*args)
32     OrvosResourceList.new(self).eager(*args)
33   end
34   def self.all(*args)
35     OrvosResourceList.new(self).all(*args)
36   end
37   def save
38     obdata = {}
39     self.class.columns.each do |col|
40       obdata[col.name.to_sym] = self.send(col.name.to_sym)
41     end
42     obdata.delete :id
43     obdata.delete :uuid
44     postdata = { self.class.to_s.underscore => obdata }
45     if etag
46       postdata['_method'] = 'PUT'
47       resp = $orvos_api_client.api(self.class, '/' + uuid, postdata)
48     else
49       resp = $orvos_api_client.api(self.class, '', postdata)
50     end
51     return false if !resp[:etag] || !resp[:uuid]
52     @etag = resp[:etag]
53     @kind = resp[:kind]
54     self.uuid ||= resp[:uuid]
55     self
56   end
57   def save!
58     self.save or raise Exception.new("Save failed")
59   end
60   def initialize(h={})
61     @etag = h.delete :etag
62     @kind = h.delete :kind
63     super
64   end
65   def metadata(*args)
66     o = {}
67     o.merge!(args.pop) if args[-1].is_a? Hash
68     o[:metadata_class] ||= args.shift
69     o[:name] ||= args.shift
70     o[:head_kind] ||= args.shift
71     o[:tail_kind] = self.kind
72     o[:tail] = self.uuid
73     if all_metadata
74       return all_metadata.select do |m|
75         ok = true
76         o.each do |k,v|
77           if !v.nil?
78             test_v = m.send(k)
79             if (v.respond_to?(:uuid) ? v.uuid : v.to_s) != (test_v.respond_to?(:uuid) ? test_v.uuid : test_v.to_s)
80               ok = false
81             end
82           end
83         end
84         ok
85       end
86     end
87     @metadata = $orvos_api_client.api Metadatum, '', { _method: 'GET', where: o, eager: true }
88     @metadata = $orvos_api_client.unpack_api_response(@metadata)
89   end
90   def all_metadata
91     return @all_metadata if @all_metadata
92     res = $orvos_api_client.api Metadatum, '', {
93       _method: 'GET',
94       where: {
95         tail_kind: self.kind,
96         tail: self.uuid
97       },
98       eager: true
99     }
100     @all_metadata = $orvos_api_client.unpack_api_response(res)
101   end
102   def reload
103     raise "No such object" if !uuid
104     $orvos_api_client.api(self, '/' + uuid).each do |k,v|
105       self.instance_variable_set('@' + k.to_s, v)
106     end
107     @all_metadata = nil
108   end
109   def dup
110     super.forget_uuid!
111   end
112
113   protected
114
115   def forget_uuid!
116     self.uuid = nil
117     @etag = nil
118     self
119   end
120 end