From 77bd719aedd53e98d72ea00a656773fe7e0a4e48 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Mon, 5 Sep 2016 18:25:39 +0200 Subject: [PATCH] SONAR-7676 support for new PROPERTIES columns in Ruby --- .../java/org/sonar/server/ui/JRubyFacade.java | 20 +++++- .../app/controllers/account_controller.rb | 4 +- .../controllers/api/properties_controller.rb | 2 +- .../api/user_properties_controller.rb | 5 +- .../webapp/WEB-INF/app/models/property.rb | 62 +++++++++++-------- .../main/webapp/WEB-INF/app/models/user.rb | 10 +-- 6 files changed, 61 insertions(+), 42 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 105d05c116a..5b4dd2021bb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -48,6 +48,8 @@ import org.sonar.core.timemachine.Periods; import org.sonar.db.Database; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.property.PropertiesDao; +import org.sonar.db.property.PropertyDto; import org.sonar.db.version.DatabaseMigration; import org.sonar.db.version.DatabaseVersion; import org.sonar.process.ProcessProperties; @@ -189,8 +191,22 @@ public final class JRubyFacade { return getContainer().getComponentsByType(Footer.class); } - public void setGlobalProperty(String key, @Nullable String value) { - get(PersistentSettings.class).saveProperty(key, value); + public void saveProperty(String key, @Nullable Long componentId, @Nullable Long userId, @Nullable String value) { + if (componentId == null && userId == null) { + get(PersistentSettings.class).saveProperty(key, value); + } else { + DbClient dbClient = get(DbClient.class); + PropertiesDao propertiesDao = dbClient.propertiesDao(); + + try (DbSession dbSession = dbClient.openSession(false)) { + if (value == null) { + propertiesDao.delete(dbSession, new PropertyDto().setKey(key).setResourceId(componentId).setUserId(userId)); + } else { + propertiesDao.saveProperty(dbSession, new PropertyDto().setKey(key).setResourceId(componentId).setUserId(userId).setValue(value)); + } + dbSession.commit(); + } + } } public Settings getSettings() { diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/account_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/account_controller.rb index af804e260e2..d3bb3d70cad 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/account_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/account_controller.rb @@ -45,7 +45,7 @@ class AccountController < ApplicationController # Global notifs global_notifs = params[:global_notifs] Property.delete_all(['prop_key like ? AND user_id = ? AND resource_id IS NULL', 'notification.%', current_user.id]) - global_notifs.each_key { |key| current_user.add_property(:prop_key => 'notification.' + key, :text_value => 'true') } if global_notifs + global_notifs.each_key { |key| Api::Utils.java_facade.saveProperty('notification.' + key, nil, current_user.id, 'true') } if global_notifs # Per project notifs project_notifs = params[:project_notifs] @@ -54,7 +54,7 @@ class AccountController < ApplicationController project_notifs.each do |r_id, per_project_notif| per_project_notif.each do |dispatch, channels| channels.each do |channel, value| - current_user.add_property(:prop_key => 'notification.' + dispatch + '.' + channel, :text_value => 'true', :resource_id => r_id) + Api::Utils.java_facade.saveProperty('notification.' + dispatch + '.' + channel, r_id, current_user.id, 'true') end end end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/properties_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/properties_controller.rb index 0c69c45098a..1be65ebedba 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/properties_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/properties_controller.rb @@ -135,7 +135,7 @@ class Api::PropertiesController < Api::ApiController not_found('resource not found') end end - Property.clear(key, resource_id_or_key) + Api::Utils.java_facade.saveProperty(key, resource_id_or_key, nil, nil) render_success('property deleted') end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/user_properties_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/user_properties_controller.rb index d25c2d23010..5a909f8310a 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/user_properties_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/user_properties_controller.rb @@ -65,8 +65,7 @@ class Api::UserPropertiesController < Api::ApiController value = params[:value] if key begin - Property.clear(key, nil, current_user.id) - property=Property.create(:prop_key => key, :text_value => value, :user_id => current_user.id) + property=Property.set(key, value, nil, current_user.id) respond_to do |format| format.json { render :json => jsonp(properties_to_json([property])) } format.xml { render :xml => properties_to_xml([property]) } @@ -88,7 +87,7 @@ class Api::UserPropertiesController < Api::ApiController def destroy begin if params[:id] - Property.clear(params[:id], nil, current_user.id) + Api::Utils.java_facade.saveProperty(params[:id], nil, current_user.id, nil) end render_success("Property deleted") rescue Exception => e diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/models/property.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/models/property.rb index a66e0e452d5..225896f3129 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/models/property.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/models/property.rb @@ -23,7 +23,8 @@ class Property < ActiveRecord::Base named_scope :with_keys, lambda { |values| {:conditions => ['prop_key in (?)', values]} } named_scope :with_key, lambda { |value| {:conditions => {:prop_key, value}} } named_scope :with_key_prefix, lambda { |value| {:conditions => ['prop_key like ?', value + '%']} } - named_scope :with_value, lambda { |value| {:conditions => ['text_value like ?', value]} } + named_scope :with_text_value, lambda { |value| {:conditions => ['text_value = ?', value]} } + named_scope :with_clob_value, lambda { |value| {:conditions => ['clob_value like ?', value]} } named_scope :with_resource, lambda { |value| {:conditions => {:resource_id => value}} } named_scope :with_user, lambda { |value| {:conditions => {:user_id => value}} } named_scope :with_resources, :conditions => 'resource_id is not null' @@ -36,7 +37,13 @@ class Property < ActiveRecord::Base end def value - text_value + if is_empty? + '' + elsif text_value.nil? + clob_value + else + text_value + end end def self.hash(resource_id=nil, user_id=nil) @@ -48,8 +55,7 @@ class Property < ActiveRecord::Base def self.clear(key, resource_id=nil, user_id=nil) prop = by_key(key, resource_id, user_id) if prop - all(key, resource_id, user_id).delete_all - setGlobalProperty(key, nil, resource_id, user_id) + Api::Utils.java_facade.saveProperty(key, resource_id, user_id, nil) end prop end @@ -57,7 +63,11 @@ class Property < ActiveRecord::Base def self.clear_for_resources(key, value=nil) scope = Property.with_resources().with_key(key) if value - scope = scope.with_value(value) + if value.length > 4000 + scope = scope.with_clob_value(value) + else + scope = scope.with_text_value(value) + end end scope.delete_all end @@ -78,7 +88,7 @@ class Property < ActiveRecord::Base property = by_key(key, resource_id, user_id) return default_value unless property - property.text_value || default_value + property.value || default_value end def self.values(key, resource_id=nil, user_id=nil) @@ -93,33 +103,35 @@ class Property < ActiveRecord::Base value = Property.new({:prop_key => key}).multi_values? ? array_value_to_string(value) : value.first end - text_value = value.to_s if defined? value - text_value = nil if text_value.blank? + raw_value = value.to_s if defined? value + raw_value = nil if raw_value.blank? # Load Java property definition property_def = field_property_def(key) || property_def(key) - if text_value.blank? - return Property.clear(key, resource_id) + prop = by_key(key, resource_id, user_id) + if !prop + prop = Property.new(:prop_key => key, :resource_id => resource_id, :user_id => user_id) end - prop = by_key(key, resource_id, user_id) - if prop && prop.text_value == text_value + if prop.value == raw_value return prop end - if !prop - prop = Property.new(:prop_key => key, :resource_id => resource_id, :user_id => user_id) - # Do not update password that wasn't updated - elsif property_def.type().to_s == PropertyType::TYPE_PASSWORD && text_value == EXISTING_PASSWORD - text_value = prop.text_value + # Do not update password that wasn't updated + if property_def.type().to_s == PropertyType::TYPE_PASSWORD && raw_value == EXISTING_PASSWORD + raw_value = prop.value end - prop.text_value = text_value - if prop.save - setGlobalProperty(key, text_value, resource_id, user_id) - end + # create/update property in DB + Api::Utils.java_facade.saveProperty(key, resource_id, user_id, raw_value) + # update returned property + if raw_value.nil? + prop.text_value='' + else + prop.text_value=raw_value + end prop end @@ -170,10 +182,6 @@ class Property < ActiveRecord::Base array.map { |v| v.gsub(',', '%2C') }.join(',') end - def self.setGlobalProperty(key, value, resource_id, user_id) - Api::Utils.java_facade.setGlobalProperty(key, value) unless (resource_id || user_id) - end - private def self.all(key, resource_id=nil, user_id=nil) @@ -191,14 +199,14 @@ class Property < ActiveRecord::Base def validate_property if java_definition - validation_result = java_definition.validate(text_value) + validation_result = java_definition.validate(value) errors.add_to_base(validation_result.errorKey) unless validation_result.isValid() end end def validate_field if java_field_definition - validation_result = java_field_definition.validate(text_value) + validation_result = java_field_definition.validate(value) errors.add_to_base(validation_result.errorKey) unless validation_result.isValid() end end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/models/user.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/models/user.rb index 73c89188be8..34f10ac5b18 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/models/user.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/models/user.rb @@ -161,8 +161,7 @@ class User < ActiveRecord::Base def add_favourite(resource_key) favourite=Project.by_key(resource_key) if favourite - delete_favourite(favourite.id) - properties().create(:prop_key => FAVOURITE_PROPERTY_KEY, :user_id => id, :resource_id => favourite.id) + Api::Utils.java_facade.saveProperty(FAVOURITE_PROPERTY_KEY, favourite.id, id, '') end favourite end @@ -174,11 +173,8 @@ class User < ActiveRecord::Base rid = resource.id if resource end if rid - props=properties().select { |p| p.key==FAVOURITE_PROPERTY_KEY && p.resource_id==rid } - if props.size>0 - properties().delete(props) - return true - end + Api::Utils.java_facade.saveProperty(FAVOURITE_PROPERTY_KEY, rid, id, nil) + true end false end -- 2.39.5