13561: Old collection version's modified_at reflects version's create time.
[arvados.git] / services / api / app / models / arvados_model.rb
index b9edeae06ecf93f0a1b6014eef0772224deed1a1..4ba4ac77105db67b2037199a792ab3f79f635295 100644 (file)
@@ -537,12 +537,12 @@ class ArvadosModel < ActiveRecord::Base
 
   def update_modified_by_fields
     current_time = db_current_time
-    self.created_at = created_at_was || current_time
+    self.created_at ||= created_at_was || current_time
     self.updated_at = current_time
     self.owner_uuid ||= current_default_owner if self.respond_to? :owner_uuid=
-    self.modified_at = current_time
     if !anonymous_updater
       self.modified_by_user_uuid = current_user ? current_user.uuid : nil
+      self.modified_at = current_time
     end
     self.modified_by_client_uuid = current_api_client ? current_api_client.uuid : nil
     true
@@ -596,16 +596,24 @@ class ArvadosModel < ActiveRecord::Base
     end
   end
 
-  def self.where_serialized(colname, value)
+  def self.where_serialized(colname, value, md5: false)
+    colsql = colname.to_s
+    if md5
+      colsql = "md5(#{colsql})"
+    end
     if value.empty?
       # rails4 stores as null, rails3 stored as serialized [] or {}
-      sql = "#{colname.to_s} is null or #{colname.to_s} IN (?)"
+      sql = "#{colsql} is null or #{colsql} IN (?)"
       sorted = value
     else
-      sql = "#{colname.to_s} IN (?)"
+      sql = "#{colsql} IN (?)"
       sorted = deep_sort_hash(value)
     end
-    where(sql, [sorted.to_yaml, SafeJSON.dump(sorted)])
+    params = [sorted.to_yaml, SafeJSON.dump(sorted)]
+    if md5
+      params = params.map { |x| Digest::MD5.hexdigest(x) }
+    end
+    where(sql, params)
   end
 
   Serializer = {
@@ -763,36 +771,51 @@ class ArvadosModel < ActiveRecord::Base
     end
   end
 
+  def is_audit_logging_enabled?
+    return !(Rails.configuration.max_audit_log_age.to_i == 0 &&
+             Rails.configuration.max_audit_log_delete_batch.to_i > 0)
+  end
+
   def log_start_state
-    @old_attributes = Marshal.load(Marshal.dump(attributes))
-    @old_logged_attributes = Marshal.load(Marshal.dump(logged_attributes))
+    if is_audit_logging_enabled?
+      @old_attributes = Marshal.load(Marshal.dump(attributes))
+      @old_logged_attributes = Marshal.load(Marshal.dump(logged_attributes))
+    end
   end
 
   def log_change(event_type)
-    log = Log.new(event_type: event_type).fill_object(self)
-    yield log
-    log.save!
-    log_start_state
+    if is_audit_logging_enabled?
+      log = Log.new(event_type: event_type).fill_object(self)
+      yield log
+      log.save!
+      log_start_state
+    end
   end
 
   def log_create
-    log_change('create') do |log|
-      log.fill_properties('old', nil, nil)
-      log.update_to self
+    if is_audit_logging_enabled?
+      log_change('create') do |log|
+        log.fill_properties('old', nil, nil)
+        log.update_to self
+      end
     end
   end
 
   def log_update
-    log_change('update') do |log|
-      log.fill_properties('old', etag(@old_attributes), @old_logged_attributes)
-      log.update_to self
+    if is_audit_logging_enabled?
+      log_change('update') do |log|
+        log.fill_properties('old', etag(@old_attributes), @old_logged_attributes)
+        log.update_to self
+      end
     end
   end
 
   def log_destroy
-    log_change('delete') do |log|
-      log.fill_properties('old', etag(@old_attributes), @old_logged_attributes)
-      log.update_to nil
+    if is_audit_logging_enabled?
+      log_change('delete') do |log|
+        log.fill_properties('old', etag(@old_attributes), @old_logged_attributes)
+        log.update_to nil
+      end
     end
   end
 end