Merge pull request #811 from umbraco/temp-U4-4652

Temp u4 4652
This commit is contained in:
Shannon Deminick
2015-10-14 12:09:52 +02:00
25 changed files with 352 additions and 48 deletions
@@ -158,6 +158,11 @@ namespace Umbraco.Core
/// </summary>
public const string IntegerAlias = "Umbraco.Integer";
/// <summary>
/// Alias for the Decimal datatype.
/// </summary>
public const string DecimalAlias = "Umbraco.Decimal";
/// <summary>
/// Alias for the listview datatype.
/// </summary>
+1
View File
@@ -431,6 +431,7 @@ namespace Umbraco.Core
new Lazy<Type>(() => typeof (DelimitedManifestValueValidator)),
new Lazy<Type>(() => typeof (EmailValidator)),
new Lazy<Type>(() => typeof (IntegerValidator)),
new Lazy<Type>(() => typeof (DecimalValidator)),
});
//by default we'll use the db server registrar unless the developer has the legacy
@@ -21,6 +21,8 @@ namespace Umbraco.Core.Models
[EnumMember]
Integer,
[EnumMember]
Date
Date,
[EnumMember]
Decimal
}
}
+3
View File
@@ -402,6 +402,9 @@ namespace Umbraco.Core.Models
if (DataTypeDatabaseType == DataTypeDatabaseType.Integer && type == typeof(int))
return true;
if (DataTypeDatabaseType == DataTypeDatabaseType.Decimal && type == typeof(decimal))
return true;
if (DataTypeDatabaseType == DataTypeDatabaseType.Date && type == typeof(DateTime))
return true;
@@ -33,6 +33,10 @@ namespace Umbraco.Core.Models.Rdbms
[NullSetting(NullSetting = NullSettings.Null)]
public int? Integer { get; set; }
[Column("dataDecimal")]
[NullSetting(NullSetting = NullSettings.Null)]
public decimal? Decimal { get; set; }
[Column("dataDate")]
[NullSetting(NullSetting = NullSettings.Null)]
public DateTime? Date { get; set; }
@@ -55,22 +59,27 @@ namespace Umbraco.Core.Models.Rdbms
{
get
{
if(Integer.HasValue)
if (Integer.HasValue)
{
return Integer.Value;
}
if (Decimal.HasValue)
{
return Decimal.Value;
}
if(Date.HasValue)
if (Date.HasValue)
{
return Date.Value;
}
if(string.IsNullOrEmpty(VarChar) == false)
if (string.IsNullOrEmpty(VarChar) == false)
{
return VarChar;
}
if(string.IsNullOrEmpty(Text) == false)
if (string.IsNullOrEmpty(Text) == false)
{
return Text;
}
@@ -63,7 +63,9 @@ namespace Umbraco.Core.Persistence.Factories
//Check if property has an Id and set it, so that it can be updated if it already exists
if (property.HasIdentity)
{
dto.Id = property.Id;
}
if (property.DataTypeDatabaseType == DataTypeDatabaseType.Integer)
{
@@ -82,11 +84,21 @@ namespace Umbraco.Core.Persistence.Factories
}
}
}
else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Decimal && property.Value != null)
{
decimal val;
if (decimal.TryParse(property.Value.ToString(), out val))
{
dto.Decimal = val;
}
}
else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Date && property.Value != null && string.IsNullOrWhiteSpace(property.Value.ToString()) == false)
{
DateTime date;
if(DateTime.TryParse(property.Value.ToString(), out date))
if (DateTime.TryParse(property.Value.ToString(), out date))
{
dto.Date = date;
}
}
else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Ntext && property.Value != null)
{
@@ -0,0 +1,29 @@
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero
{
[Migration("7.4.0", 1, GlobalSettings.UmbracoMigrationName)]
public class AddDataDecimalColumn : MigrationBase
{
public AddDataDecimalColumn(ISqlSyntaxProvider sqlSyntax, ILogger logger)
: base(sqlSyntax, logger)
{
}
public override void Up()
{
//Don't exeucte if the column is already there
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
if (columns.Any(x => x.TableName.InvariantEquals("cmsPropertyData") && x.ColumnName.InvariantEquals("dataDecimal")) == false)
Create.Column("dataDecimal").OnTable("cmsPropertyData").AsDecimal().Nullable();
}
public override void Down()
{
}
}
}
@@ -10,6 +10,19 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public abstract class MicrosoftSqlSyntaxProviderBase<TSyntax> : SqlSyntaxProviderBase<TSyntax>
where TSyntax : ISqlSyntaxProvider
{
protected MicrosoftSqlSyntaxProviderBase()
{
AutoIncrementDefinition = "IDENTITY(1,1)";
GuidColumnDefinition = "UniqueIdentifier";
RealColumnDefinition = "FLOAT";
BoolColumnDefinition = "BIT";
DecimalColumnDefinition = "DECIMAL(38,6)";
TimeColumnDefinition = "TIME"; //SQLSERVER 2008+
BlobColumnDefinition = "VARBINARY(MAX)";
InitColumnTypeMap();
}
public override string RenameTable { get { return "sp_rename '{0}', '{1}'"; } }
public override string AddColumn { get { return "ALTER TABLE {0} ADD {1}"; } }
@@ -18,10 +18,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public MySqlSyntaxProvider(ILogger logger)
{
_logger = logger;
DefaultStringLength = 255;
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
AutoIncrementDefinition = "AUTO_INCREMENT";
IntColumnDefinition = "int(11)";
BoolColumnDefinition = "tinyint(1)";
@@ -29,9 +26,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
TimeColumnDefinition = "time";
DecimalColumnDefinition = "decimal(38,6)";
GuidColumnDefinition = "char(36)";
InitColumnTypeMap();
DefaultValueFormat = "DEFAULT {0}";
}
@@ -15,19 +15,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
{
public SqlCeSyntaxProvider()
{
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
AutoIncrementDefinition = "IDENTITY(1,1)";
StringColumnDefinition = "NVARCHAR(255)";
GuidColumnDefinition = "UniqueIdentifier";
RealColumnDefinition = "FLOAT";
BoolColumnDefinition = "BIT";
DecimalColumnDefinition = "DECIMAL(38,6)";
TimeColumnDefinition = "TIME"; //SQLSERVER 2008+
BlobColumnDefinition = "VARBINARY(MAX)";
InitColumnTypeMap();
}
public override bool SupportsClustered()
@@ -13,19 +13,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
{
public SqlServerSyntaxProvider()
{
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
AutoIncrementDefinition = "IDENTITY(1,1)";
StringColumnDefinition = "VARCHAR(8000)";
GuidColumnDefinition = "UniqueIdentifier";
RealColumnDefinition = "FLOAT";
BoolColumnDefinition = "BIT";
DecimalColumnDefinition = "DECIMAL(38,6)";
TimeColumnDefinition = "TIME"; //SQLSERVER 2008+
BlobColumnDefinition = "VARBINARY(MAX)";
InitColumnTypeMap();
}
/// <summary>
@@ -32,6 +32,13 @@ namespace Umbraco.Core.Persistence.SqlSyntax
FormatPrimaryKey,
FormatIdentity
};
//defaults for all providers
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
DecimalColumnDefinition = string.Format(DecimalColumnDefinitionFormat, DefaultDecimalPrecision, DefaultDecimalScale);
InitColumnTypeMap();
}
public string GetWildcardPlaceholder()
@@ -41,9 +48,12 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public string StringLengthNonUnicodeColumnDefinitionFormat = "VARCHAR({0})";
public string StringLengthUnicodeColumnDefinitionFormat = "NVARCHAR({0})";
public string DecimalColumnDefinitionFormat = "DECIMAL({0},{1})";
public string DefaultValueFormat = "DEFAULT ({0})";
public int DefaultStringLength = 255;
public int DefaultDecimalPrecision = 20;
public int DefaultDecimalScale = 9;
//Set by Constructor
public string StringColumnDefinition;
@@ -55,7 +65,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public string GuidColumnDefinition = "GUID";
public string BoolColumnDefinition = "BOOL";
public string RealColumnDefinition = "DOUBLE";
public string DecimalColumnDefinition = "DECIMAL";
public string DecimalColumnDefinition;
public string BlobColumnDefinition = "BLOB";
public string DateTimeColumnDefinition = "DATETIME";
public string TimeColumnDefinition = "DATETIME";
@@ -431,6 +441,13 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return string.Format(StringLengthColumnDefinitionFormat, valueOrDefault);
}
if (type == typeof(decimal))
{
var precision = column.Size != default(int) ? column.Size : DefaultDecimalPrecision;
var scale = column.Precision != default(int) ? column.Precision : DefaultDecimalScale;
return string.Format(DecimalColumnDefinitionFormat, precision, scale);
}
string definition = DbTypeMap.ColumnTypeMap.First(x => x.Key == type).Value;
string dbTypeDefinition = column.Size != default(int)
? string.Format("{0}({1})", definition, column.Size)
@@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Umbraco.Core.Models;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// A validator that validates that the value is a valid decimal
/// </summary>
[ValueValidator("Decimal")]
internal sealed class DecimalValidator : ManifestValueValidator, IPropertyValidator
{
public override IEnumerable<ValidationResult> Validate(object value, string config, PreValueCollection preValues, PropertyEditor editor)
{
if (value != null && value.ToString() != string.Empty)
{
var result = value.TryConvertTo<decimal>();
if (result.Success == false)
{
yield return new ValidationResult("The value " + value + " is not a valid decimal", new[] { "value" });
}
}
}
public IEnumerable<ValidationResult> Validate(object value, PreValueCollection preValues, PropertyEditor editor)
{
return Validate(value, "", preValues, editor);
}
}
}
@@ -133,6 +133,8 @@ namespace Umbraco.Core.PropertyEditors
case "INT":
case "INTEGER":
return DataTypeDatabaseType.Integer;
case "DECIMAL":
return DataTypeDatabaseType.Decimal;
case "STRING":
return DataTypeDatabaseType.Nvarchar;
case "TEXT":
@@ -202,6 +204,11 @@ namespace Umbraco.Core.PropertyEditors
? Attempt<object>.Succeed((int)(long)result.Result)
: result;
case DataTypeDatabaseType.Decimal:
//ensure these are nullable so we can return a null if required
valueType = typeof(decimal?);
break;
case DataTypeDatabaseType.Date:
//ensure these are nullable so we can return a null if required
valueType = typeof(DateTime?);
@@ -283,6 +290,7 @@ namespace Umbraco.Core.PropertyEditors
}
return property.Value.ToString();
case DataTypeDatabaseType.Integer:
case DataTypeDatabaseType.Decimal:
//we can just ToString() any of these types
return property.Value.ToString();
case DataTypeDatabaseType.Date:
@@ -325,6 +333,7 @@ namespace Umbraco.Core.PropertyEditors
{
case DataTypeDatabaseType.Date:
case DataTypeDatabaseType.Integer:
case DataTypeDatabaseType.Decimal:
return new XText(ConvertDbToString(property, propertyType, dataTypeService));
case DataTypeDatabaseType.Nvarchar:
case DataTypeDatabaseType.Ntext:
@@ -354,6 +363,7 @@ namespace Umbraco.Core.PropertyEditors
property.Value.ToXmlString<string>();
return property.Value.ToXmlString<string>();
case DataTypeDatabaseType.Integer:
case DataTypeDatabaseType.Decimal:
return property.Value.ToXmlString(property.Value.GetType());
case DataTypeDatabaseType.Date:
//treat dates differently, output the format as xml format
@@ -0,0 +1,31 @@
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[PropertyValueType(typeof(decimal))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DecimalValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
return Constants.PropertyEditors.DecimalAlias.Equals(propertyType.PropertyEditorAlias);
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null) return 0M;
// in XML a decimal is a string
var sourceString = source as string;
if (sourceString != null)
{
decimal d;
return (decimal.TryParse(sourceString, out d)) ? d : 0M;
}
// in the database an a decimal is an a decimal
// default value is zero
return (source is decimal) ? source : 0M;
}
}
}
+3
View File
@@ -405,6 +405,7 @@
<Compile Include="Persistence\Mappers\AccessMapper.cs" />
<Compile Include="Persistence\Mappers\DomainMapper.cs" />
<Compile Include="Persistence\Mappers\MigrationEntryMapper.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFourZero\AddDataDecimalColumn.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\AddExternalLoginsTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\AddForeignKeysForLanguageAndDictionaryTables.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\AddServerRegistrationColumnsAndLock.cs" />
@@ -456,7 +457,9 @@
<Compile Include="Persistence\Repositories\RepositoryCacheOptions.cs" />
<Compile Include="Persistence\Repositories\TaskRepository.cs" />
<Compile Include="Persistence\Repositories\TaskTypeRepository.cs" />
<Compile Include="PropertyEditors\DecimalValidator.cs" />
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DecimalValueConverter.cs" />
<Compile Include="Publishing\UnPublishedStatusType.cs" />
<Compile Include="Publishing\UnPublishStatus.cs" />
<Compile Include="Security\BackOfficeClaimsIdentityFactory.cs" />
@@ -5,12 +5,29 @@ using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Strings;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.PropertyEditors
{
[TestFixture]
public class PropertyEditorValueEditorTests
{
[SetUp]
public virtual void TestSetup()
{
ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper(SettingsForTests.GetDefault()));
Resolution.Freeze();
}
[TearDown]
public virtual void TestTearDown()
{
ResolverCollection.ResetAll();
Resolution.Reset();
}
[TestCase("{prop1: 'val1', prop2: 'val2'}", true)]
[TestCase("{1,2,3,4}", false)]
[TestCase("[1,2,3,4]", true)]
@@ -46,6 +63,47 @@ namespace Umbraco.Tests.PropertyEditors
Assert.AreEqual(expected, result.Result);
}
// The following decimal tests have not been added as [TestCase]s
// as the decimal type cannot be used as an attribute parameter
[Test]
public void Value_Editor_Can_Convert_To_Decimal_Clr_Type()
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
};
var result = valueEditor.TryConvertValueToCrlType("12.34");
Assert.IsTrue(result.Success);
Assert.AreEqual(12.34M, result.Result);
}
[Test]
public void Value_Editor_Can_Convert_To_Decimal_Clr_Type_With_Other_Separator()
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
};
var result = valueEditor.TryConvertValueToCrlType("12,34");
Assert.IsTrue(result.Success);
Assert.AreEqual(12.34M, result.Result);
}
[Test]
public void Value_Editor_Can_Convert_To_Decimal_Clr_Type_With_Empty_String()
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
};
var result = valueEditor.TryConvertValueToCrlType(string.Empty);
Assert.IsTrue(result.Success);
Assert.IsNull(result.Result);
}
[Test]
public void Value_Editor_Can_Convert_To_Date_Clr_Type()
{
@@ -78,6 +136,35 @@ namespace Umbraco.Tests.PropertyEditors
Assert.AreEqual(expected, result);
}
[Test]
public void Value_Editor_Can_Serialize_Decimal_Value()
{
var value = 12.34M;
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
};
var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Decimal), value);
var result = valueEditor.ConvertDbToEditor(prop, prop.PropertyType, new Mock<IDataTypeService>().Object);
Assert.AreEqual("12.34", result);
}
[Test]
public void Value_Editor_Can_Serialize_Decimal_Value_With_Empty_String()
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
};
var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Decimal), string.Empty);
var result = valueEditor.ConvertDbToEditor(prop, prop.PropertyType, new Mock<IDataTypeService>().Object);
Assert.AreEqual(string.Empty, result);
}
[Test]
public void Value_Editor_Can_Serialize_Date_Value()
{
@@ -40,7 +40,7 @@ function valRegex() {
var patternValidator = function (viewValue) {
//NOTE: we don't validate on empty values, use required validator for that
if (!viewValue || regex.test(viewValue)) {
if (!viewValue || regex.test(viewValue.toString())) {
// it is valid
ctrl.$setValidity('valRegex', true);
//assign a message to the validator
@@ -0,0 +1,11 @@
<div>
<input name="decimalField" class="umb-editor umb-number"
type="number"
ng-model="model.value"
val-server="value"
fix-number />
<span class="help-inline" val-msg-for="decimalField" val-toggle-msg="number">Not a number</span>
<span class="help-inline" val-msg-for="decimalField" val-toggle-msg="valServer">{{propertyForm.requiredField.errorMsg}}</span>
</div>
@@ -3,7 +3,7 @@
type="number"
ng-model="model.value"
val-server="value"
fix-number />
fix-number />
<span class="help-inline" val-msg-for="numberField" val-toggle-msg="number">Not a number</span>
<span class="help-inline" val-msg-for="numberField" val-toggle-msg="valServer">{{propertyForm.requiredField.errorMsg}}</span>
@@ -0,0 +1,11 @@
<div class="umb-editor">
<input name="decimalField"
type="number"
class="umb-editor umb-number"
ng-model="model.value"
val-server="value"
fix-number min="{{model.config.min}}" max="{{model.config.max}}" step="{{model.config.step}}" />
<span class="help-inline" val-msg-for="decimalField" val-toggle-msg="number">Not a number</span>
<span class="help-inline" val-msg-for="decimalField" val-toggle-msg="valServer">{{propertyForm.requiredField.errorMsg}}</span>
</div>
@@ -1,10 +1,11 @@
<div class="umb-editor">
<input name="integerField" type="number" class="umb-editor umb-number "
ng-model="model.value"
val-server="value"
fix-number min="{{model.config.min}}" max="{{model.config.max}}" step="{{model.config.step}}" />
<input name="integerField"
type="number"
class="umb-editor umb-number "
ng-model="model.value"
val-server="value"
fix-number min="{{model.config.min}}" max="{{model.config.max}}" step="{{model.config.step}}" />
<span class="help-inline" val-msg-for="integerField" val-toggle-msg="number">Not a number</span>
<span class="help-inline" val-msg-for="integerField" val-toggle-msg="valServer">{{propertyForm.requiredField.errorMsg}}</span>
</div>
@@ -0,0 +1,57 @@
using Umbraco.Core;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[PropertyEditor(Constants.PropertyEditors.DecimalAlias, "Decimal", "decimal", "decimal", IsParameterEditor = true)]
public class DecimalPropertyEditor : PropertyEditor
{
/// <summary>
/// Overridden to ensure that the value is validated
/// </summary>
/// <returns></returns>
protected override PropertyValueEditor CreateValueEditor()
{
var editor = base.CreateValueEditor();
editor.Validators.Add(new DecimalValidator());
return editor;
}
protected override PreValueEditor CreatePreValueEditor()
{
return new DecimalPreValueEditor();
}
/// <summary>
/// A custom pre-value editor class to deal with the legacy way that the pre-value data is stored.
/// </summary>
internal class DecimalPreValueEditor : PreValueEditor
{
public DecimalPreValueEditor()
{
//create the fields
Fields.Add(new PreValueField(new DecimalValidator())
{
Description = "Enter the minimum amount of number to be entered",
Key = "min",
View = "decimal",
Name = "Minimum"
});
Fields.Add(new PreValueField(new DecimalValidator())
{
Description = "Enter the intervals amount between each step of number to be entered",
Key = "step",
View = "decimal",
Name = "Step Size"
});
Fields.Add(new PreValueField(new DecimalValidator())
{
Description = "Enter the maximum amount of number to be entered",
Key = "max",
View = "decimal",
Name = "Maximum"
});
}
}
}
}
@@ -3,7 +3,7 @@ using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[PropertyEditor(Constants.PropertyEditors.IntegerAlias, "Numeric", "integer", IsParameterEditor = true)]
[PropertyEditor(Constants.PropertyEditors.IntegerAlias, "Numeric", "integer", IsParameterEditor = true, ValueType = "integer")]
public class IntegerPropertyEditor : PropertyEditor
{
/// <summary>
+1
View File
@@ -307,6 +307,7 @@
<Compile Include="Models\ContentEditing\SimpleNotificationModel.cs" />
<Compile Include="Models\PublishedContentWithKeyBase.cs" />
<Compile Include="PropertyEditors\DatePreValueEditor.cs" />
<Compile Include="PropertyEditors\DecimalPropertyEditor.cs" />
<Compile Include="RequestLifespanMessagesFactory.cs" />
<Compile Include="Scheduling\LatchedBackgroundTaskBase.cs" />
<Compile Include="Security\Identity\ExternalSignInAutoLinkOptions.cs" />