Skip to content

Commit

Permalink
Merge branch 'release/1.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Cédric L. Charlier committed Apr 21, 2016
2 parents 1253bf8 + 4131062 commit 0e9b7c3
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 16 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,6 @@ _Pvt_Extensions

# FAKE - F# Make
.fake/

# Mergefiles
*.orig
81 changes: 79 additions & 2 deletions ERMine.Core.UnitTesting/Parsing/AttributeParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ public void Attributes_NullSpaceMultiValued_UniqueAttribute()
}

[TestMethod]
public void Attributes_Derivated_UniqueAttribute()
public void Attributes_Derived_UniqueAttribute()
{
var input = "Age int%\r\n";
var attributes = AttributeParser.Attributes.Parse(input);
Expand All @@ -287,7 +287,7 @@ public void Attributes_Derivated_UniqueAttribute()
}

[TestMethod]
public void Attributes_DerivatedSpace_UniqueAttribute()
public void Attributes_DerivedSpace_UniqueAttribute()
{
var input = "Age int %\r\n";
var attributes = AttributeParser.Attributes.Parse(input);
Expand All @@ -299,7 +299,84 @@ public void Attributes_DerivatedSpace_UniqueAttribute()
Assert.IsFalse(attribute.IsNullable);
Assert.IsFalse(attribute.IsMultiValued);
Assert.IsTrue(attribute.IsDerived);
Assert.IsFalse(attribute.IsImmutable);
}

[TestMethod]
public void Attributes_Immutable_UniqueAttribute()
{
var input = "Age int^\r\n";
var attributes = AttributeParser.Attributes.Parse(input);
Assert.AreEqual(attributes.Count(), 1);

var attribute = attributes.ElementAt(0);
Assert.AreEqual("Age", attribute.Label);
Assert.AreEqual("int", attribute.DataType);
Assert.IsFalse(attribute.IsNullable);
Assert.IsFalse(attribute.IsMultiValued);
Assert.IsFalse(attribute.IsDerived);
Assert.IsTrue(attribute.IsImmutable);
}

[TestMethod]
public void Attributes_ImmutablSpace_UniqueAttribute()
{
var input = "Age int ^\r\n";
var attributes = AttributeParser.Attributes.Parse(input);
Assert.AreEqual(attributes.Count(), 1);

var attribute = attributes.ElementAt(0);
Assert.AreEqual("Age", attribute.Label);
Assert.AreEqual("int", attribute.DataType);
Assert.IsFalse(attribute.IsNullable);
Assert.IsFalse(attribute.IsMultiValued);
Assert.IsFalse(attribute.IsDerived);
Assert.IsTrue(attribute.IsImmutable);
}

[TestMethod]
public void Attributes_FormulaDerived_UniqueAttribute()
{
var input = "fullName varchar(50){% firstName + ' ' + lastName %}\r\n";
var attributes = AttributeParser.Attributes.Parse(input);
Assert.AreEqual(attributes.Count(), 1);

var attribute = attributes.ElementAt(0);
Assert.AreEqual("fullName", attribute.Label);
Assert.IsFalse(attribute.IsNullable);
Assert.IsFalse(attribute.IsMultiValued);
Assert.IsTrue(attribute.IsDerived);
Assert.AreEqual("firstName + ' ' + lastName", attribute.DerivedFormula);
}

[TestMethod]
public void Attributes_FormulaDerivedSpace_UniqueAttribute()
{
var input = "fullName varchar(50) {% firstName + ' ' + lastName %}\r\n";
var attributes = AttributeParser.Attributes.Parse(input);
Assert.AreEqual(attributes.Count(), 1);

var attribute = attributes.ElementAt(0);
Assert.AreEqual("fullName", attribute.Label);
Assert.IsFalse(attribute.IsNullable);
Assert.IsFalse(attribute.IsMultiValued);
Assert.IsTrue(attribute.IsDerived);
Assert.AreEqual("firstName + ' ' + lastName", attribute.DerivedFormula);
}

[TestMethod]
public void Attributes_FormulaDerivedUnspecified_UniqueAttribute()
{
var input = "fullName varchar(50) %\r\n";
var attributes = AttributeParser.Attributes.Parse(input);
Assert.AreEqual(attributes.Count(), 1);

var attribute = attributes.ElementAt(0);
Assert.AreEqual("fullName", attribute.Label);
Assert.IsTrue(attribute.IsDerived);
Assert.AreEqual(string.Empty, attribute.DerivedFormula);
}


}
}
1 change: 1 addition & 0 deletions ERMine.Core/ERMine.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<Compile Include="Modeling\Key.cs" />
<Compile Include="Modeling\PartialKey.cs" />
<Compile Include="Modeling\Repository\ModelRepository.cs" />
<Compile Include="Parsing\Formula.cs" />
<Compile Include="Parsing\ModelParser.cs" />
<Compile Include="Parsing\Parser.cs" />
<Compile Include="Parsing\RelationshipTernaryParser.cs" />
Expand Down
2 changes: 2 additions & 0 deletions ERMine.Core/Modeling/Attribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class Attribute
public string Label { get; set; }
public string DataType { get; set; }
public bool IsNullable { get; set; }
public bool IsImmutable { get; set; }
public KeyType Key { get; set; }
public bool IsPartOfPrimaryKey
{
Expand All @@ -24,5 +25,6 @@ public bool IsPartOfPartialKey
}
public bool IsMultiValued { get; set; }
public bool IsDerived { get; set; }
public string DerivedFormula { get; set; }
}
}
12 changes: 8 additions & 4 deletions ERMine.Core/Parsing/AttributeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ from keyType in Keyword.IsPartOfKey.Optional()
from label in Grammar.Textual
from dataType in DataType.Optional()
from isNullable in Keyword.IsNullable.Optional()
from isImmutable in Keyword.IsImmutable.Optional()
from isMultiValued in Keyword.IsMultiValued.Optional()
from isDerivated in Keyword.IsDerived.Optional()
from isDerived in Keyword.IsDerived.Optional()
from formulaDerived in Formula.Derived.Optional()
select new Attribute() { Label = label
, DataType=dataType.GetOrDefault()
, IsNullable=isNullable.IsDefined
, DataType = dataType.GetOrDefault()
, IsNullable = isNullable.IsDefined
, Key = keyType.IsDefined ? keyType.Get() : KeyType.None
, IsImmutable = isImmutable.IsDefined
, IsMultiValued = isMultiValued.IsDefined
, IsDerived = isDerivated.IsDefined
, IsDerived = isDerived.IsDefined || formulaDerived.IsDefined
, DerivedFormula = formulaDerived.GetOrElse(string.Empty).Trim()
}
);

Expand Down
15 changes: 15 additions & 0 deletions ERMine.Core/Parsing/Formula.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using ERMine.Core.Modeling;
using Sprache;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ERMine.Core.Parsing
{
class Formula
{
public static readonly Parser<string> Derived = Parse.CharExcept("{%}").AtLeastOnce().Text().Contained(Parse.String("{%"), Parse.String("%}")).Token();
}
}
1 change: 1 addition & 0 deletions ERMine.Core/Parsing/Keyword.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ class Keyword
public static readonly Parser<string> IsNullable = Parse.String("?").Text().Or(Parse.String("?").Text().Token().Or(Parse.String("NULL").Text().Token()));
public static readonly Parser<string> IsMultiValued = Parse.String("#").Text().Or(Parse.String("#").Text().Token().Or(Parse.String("MV").Text()));
public static readonly Parser<string> IsDerived = Parse.String("%").Text().Or(Parse.String("%").Text().Token().Or(Parse.String("CALC").Text()));
public static readonly Parser<string> IsImmutable = Parse.String("^").Text().Or(Parse.String("^").Text().Token().Or(Parse.String("IMMUTABLE").Text()));
}
}
25 changes: 15 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,31 @@ The name of an entity must be written between brackets:

## Attributes

Atrributes must follow the name of the entity
Attributes must follow the name of the entity

[[ * | PK ] | [ ~ | PPK ]] *attribute_name* [ *sql-type* ] [ ? | NULL ] [ # ] [ % ]
[[ * | PK ] | [ ~ | PPK ]] *attribute_name* [ *sql-type* ] [ ? | NULL ] [^] [ # ] [ % ] [{% *derivated_formula* %}]

**Expl:**

* ``` firstName ```
* ``` firstName varchar(50) ```
* ``` email varchar(50)? ```
* ``` * customerNr char(10)```
* ``` address varchar(250) # ```
* ``` fullName % ```
* ``` firstName ``` attribute *firstName* exists
* ``` firstName varchar(50) ``` attribute *firstName* is a *varchar(50)*
* ``` email varchar(50)? ``` attribute *email* is a *varchar(50)* and is nullable
* ``` * customerNr char(10)``` attribute *customerNr* is a *char(10)* and is part of the primary key
* ``` lastName varchar(50)^ ``` attribute *lastName* is a *varchar(50)* and is immutable
* ``` address varchar(250) # ``` attribute *address* is a *varchar(250)* and must support multiple values
* ``` fullName varchar(250) {% firstName + ' ' + lastName %} ``` attribute *fullName* is derivated and the formula is *firstName + ' ' + lastName*

### Before the name of the attribute
Primary key is noted with a star (*). An alternative notation is "PK".
Partial keys are noted with a tilt (~). An alternative notation is "PPK".
### After the name of the attribute
The sql-type of the attribute must follow the name of the attribute.
Nullable attributes must postfix the sql-type with an interrogation point (?). An alternative notation is "NULL".
Multivalued attributes are noted with a cardinal (#).
Derivated attributes are noted with a percentage (%).
Immutable attributes must postfix the sql-type with a circumflex accent (^). An alternative is the notation "IMMUTABLE"
Multivalued attributes are noted with a cardinal (#). An alternative is the notation "MV"
Derivated attributes are noted with a percentage (%). An alternative is the notation "CALC"
Formula for implementation of derivated attribyes must be specified between the curly braces and percentages symbols ({% ... %})


# Relationships

Expand All @@ -64,3 +68,4 @@ Ternary relationships are noted differently

* ``` [Customer] +-owns-1 [Account] ```
* ``` [City] 1-located-* [Country] ```

0 comments on commit 0e9b7c3

Please sign in to comment.