Skip to content

Commit 52ea237

Browse files
committed
Support Database Default values specified using a custom attribute #85
#85
1 parent 83d9802 commit 52ea237

File tree

9 files changed

+94
-1
lines changed

9 files changed

+94
-1
lines changed

SQLite.CodeFirst.Console/Entity/Person.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.ComponentModel.DataAnnotations;
1+
using System;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.ComponentModel.DataAnnotations.Schema;
24

35
namespace SQLite.CodeFirst.Console.Entity
46
{
@@ -18,5 +20,9 @@ public abstract class Person : IEntity
1820

1921
[Required]
2022
public string City { get; set; }
23+
24+
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
25+
[SqlDefaultValue(DefaultValue = "DATETIME('now')")]
26+
public DateTime CreatedUtc { get; set; }
2127
}
2228
}

SQLite.CodeFirst.Console/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ private static void DisplaySeededData(DbContext context)
131131
System.Console.WriteLine("\t\t LastName: {0}", player.LastName);
132132
System.Console.WriteLine("\t\t Street: {0}", player.Street);
133133
System.Console.WriteLine("\t\t City: {0}", player.City);
134+
System.Console.WriteLine("\t\t Created: {0}", player.CreatedUtc);
134135
System.Console.WriteLine();
135136
}
136137
}

SQLite.CodeFirst.Test/SQLite.CodeFirst.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
<Compile Include="UnitTests\Statement\ColumnConstraint\ColumnConstraintCollectionTest.cs" />
9999
<Compile Include="UnitTests\Statement\ColumnConstraint\NotNullConstraintTest.cs" />
100100
<Compile Include="UnitTests\Statement\ColumnConstraint\CollateConstraintTest.cs" />
101+
<Compile Include="UnitTests\Statement\ColumnConstraint\DefaultValueConstraintTest.cs" />
101102
<Compile Include="UnitTests\Statement\ColumnConstraint\UniqueConstraintTest.cs" />
102103
<Compile Include="UnitTests\Statement\ColumnStatementCollectionTest.cs" />
103104
<Compile Include="UnitTests\Statement\PrimaryKeyStatementTest.cs" />
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using SQLite.CodeFirst.Statement.ColumnConstraint;
3+
4+
namespace SQLite.CodeFirst.Test.UnitTests.Statement.ColumnConstraint
5+
{
6+
[TestClass]
7+
public class DefaultValueConstraintTest
8+
{
9+
[TestMethod]
10+
public void CreateStatement_StatementIsCorrect_IntDefault()
11+
{
12+
var defaultValueConstraint = new DefaultValueConstraint();
13+
defaultValueConstraint.DefaultValue = "0";
14+
string output = defaultValueConstraint.CreateStatement();
15+
Assert.AreEqual(output, "DEFAULT 0");
16+
}
17+
18+
[TestMethod]
19+
public void CreateStatement_StatementIsCorrect_StringDefault()
20+
{
21+
var defaultValueConstraint = new DefaultValueConstraint();
22+
defaultValueConstraint.DefaultValue = @"'Something'";
23+
string output = defaultValueConstraint.CreateStatement();
24+
Assert.AreEqual(output, "DEFAULT 'Something'");
25+
}
26+
27+
[TestMethod]
28+
public void CreateStatement_StatementIsCorrect_ExpressionDefault()
29+
{
30+
var defaultValueConstraint = new DefaultValueConstraint();
31+
defaultValueConstraint.DefaultValue = @"(datetime('now'))";
32+
string output = defaultValueConstraint.CreateStatement();
33+
Assert.AreEqual(output, "DEFAULT (datetime('now'))");
34+
}
35+
}
36+
}

SQLite.CodeFirst/Internal/Builder/ColumnStatementCollectionBuilder.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ private IEnumerable<ColumnStatement> CreateColumnStatements()
4141
AddUniqueConstraintIfNecessary(property, columnStatement);
4242
AddCollationConstraintIfNecessary(property, columnStatement);
4343
AddPrimaryKeyConstraintAndAdjustTypeIfNecessary(property, columnStatement);
44+
AddDefaultValueConstraintIfNecessary(property, columnStatement);
4445

4546
yield return columnStatement;
4647
}
@@ -90,6 +91,15 @@ private static void AddUniqueConstraintIfNecessary(EdmProperty property, ColumnS
9091
}
9192
}
9293

94+
private static void AddDefaultValueConstraintIfNecessary(EdmProperty property, ColumnStatement columnStatement)
95+
{
96+
var value = property.GetCustomAnnotation<SqlDefaultValueAttribute>();
97+
if (value != null)
98+
{
99+
columnStatement.ColumnConstraints.Add(new DefaultValueConstraint { DefaultValue = value.DefaultValue });
100+
}
101+
}
102+
93103
private void AddPrimaryKeyConstraintAndAdjustTypeIfNecessary(EdmProperty property, ColumnStatement columnStatement)
94104
{
95105
// Only handle a single primary key this way.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Text;
2+
3+
namespace SQLite.CodeFirst.Statement.ColumnConstraint
4+
{
5+
internal class DefaultValueConstraint : IColumnConstraint
6+
{
7+
private const string Template = "DEFAULT ({defaultValue})";
8+
9+
public string DefaultValue { get; set; }
10+
11+
public string CreateStatement()
12+
{
13+
var sb = new StringBuilder(Template);
14+
15+
sb.Replace("{defaultValue}", DefaultValue);
16+
17+
return sb.ToString().Trim();
18+
}
19+
}
20+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
3+
namespace SQLite.CodeFirst
4+
{
5+
/// <summary>
6+
/// Decorate an column with this attribute to create a "DEFAULT {defaultvalue}".
7+
/// <remarks>
8+
/// https://www.sqlite.org/lang_createtable.html [05.10.2017]
9+
/// </remarks>
10+
/// </summary>
11+
[AttributeUsage(AttributeTargets.Property)]
12+
public sealed class SqlDefaultValueAttribute : Attribute
13+
{
14+
public string DefaultValue { get; set; }
15+
}
16+
}

SQLite.CodeFirst/Public/DbInitializers/SqliteInitializerBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ protected SqliteInitializerBase(DbModelBuilder modelBuilder)
4343
modelBuilder.RegisterAttributeAsColumnAnnotation<UniqueAttribute>();
4444
modelBuilder.RegisterAttributeAsColumnAnnotation<CollateAttribute>();
4545
modelBuilder.RegisterAttributeAsColumnAnnotation<AutoincrementAttribute>();
46+
modelBuilder.RegisterAttributeAsColumnAnnotation<SqlDefaultValueAttribute>();
4647

4748
// By default there is a 'ForeignKeyIndexConvention' but it can be removed.
4849
// And there is no "Contains" and no way to enumerate the ConventionsCollection.

SQLite.CodeFirst/SQLite.CodeFirst.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,15 @@
8888
<Link>Properties\AssemblySharedInfo.cs</Link>
8989
</Compile>
9090
<Compile Include="Internal\Builder\NameCreators\NameCreator.cs" />
91+
<Compile Include="Internal\Statement\ColumnConstraint\DefaultValueConstraint.cs" />
9192
<Compile Include="Internal\Utility\InMemoryAwareFile.cs" />
9293
<Compile Include="Internal\Extensions\ListExtensions.cs" />
9394
<Compile Include="Internal\Statement\ColumnConstraint\PrimaryKeyConstraint.cs" />
9495
<Compile Include="Public\Attributes\AutoincrementAttribute.cs" />
9596
<Compile Include="Public\Attributes\CollateAttribute.cs" />
9697
<Compile Include="Public\Attributes\CollationFunction.cs" />
9798
<Compile Include="Public\Attributes\OnConflictAction.cs" />
99+
<Compile Include="Public\Attributes\SqlDefaultValueAttribute.cs" />
98100
<Compile Include="Public\Attributes\UniqueAttribute.cs" />
99101
<Compile Include="Public\Entities\IHistory.cs" />
100102
<Compile Include="Internal\Builder\NameCreators\IndexNameCreator.cs" />

0 commit comments

Comments
 (0)