summaryrefslogtreecommitdiff
path: root/slips/src/app/Marina/DataAccess
diff options
context:
space:
mode:
authormokhan <mokhan@da190166-9cfc-4ee1-ae03-434a172be219>2009-02-21 21:44:27 +0000
committermokhan <mokhan@da190166-9cfc-4ee1-ae03-434a172be219>2009-02-21 21:44:27 +0000
commit1dfdccb8118aeaa3cd844ac8de2a672c93312166 (patch)
tree4b19e7f816ab1019f180a46b68572af4b66fe4bc /slips/src/app/Marina/DataAccess
parent42d66bcab8262c7b8b2452615df535e694a3ec1c (diff)
git-svn-id: http://svn.xp-dev.com/svn/mokhan-sait@2 da190166-9cfc-4ee1-ae03-434a172be219
Diffstat (limited to 'slips/src/app/Marina/DataAccess')
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/DatabaseDelete.cs31
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/DatabaseInsert.cs50
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/DatabaseSelect.cs101
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/DatabaseUpdate.cs52
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/IDeleteQueryBuilder.cs3
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/IInsertQueryBuilder.cs5
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/IJoin.cs6
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/IQuery.cs7
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/IQueryBuilder.cs9
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/ISelectQueryBuilder.cs11
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/IUpdateQueryBuilder.cs5
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/Query.cs22
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/SqlQuery.cs18
-rw-r--r--slips/src/app/Marina/DataAccess/Builders/WhereClause.cs27
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/BoatDataMapper.cs74
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/CustomerDataMapper.cs82
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/DockDataMapper.cs54
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/IBoatDataMapper.cs12
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/ICustomerDataMapper.cs11
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/IDataMapper.cs5
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/IDockDataMapper.cs6
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/ILeaseDataMapper.cs14
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/IRegistrationDataMapper.cs11
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/ISlipDataMapper.cs9
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/LeaseDataMapper.cs87
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/RegistrationDataMapper.cs88
-rw-r--r--slips/src/app/Marina/DataAccess/DataMappers/SlipDataMapper.cs97
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseColumn.cs23
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseCommand.cs23
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseCommandParameter.cs19
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseConfiguration.cs22
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseConnection.cs38
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseConnectionFactory.cs7
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseGateway.cs60
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseProviderFactory.cs10
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseRow.cs24
-rw-r--r--slips/src/app/Marina/DataAccess/DatabaseTransaction.cs19
-rw-r--r--slips/src/app/Marina/DataAccess/Exceptions/ObjectAlreadyAddedToIdentityMapException.cs9
-rw-r--r--slips/src/app/Marina/DataAccess/IDatabaseCommand.cs9
-rw-r--r--slips/src/app/Marina/DataAccess/IDatabaseConfiguration.cs7
-rw-r--r--slips/src/app/Marina/DataAccess/IDatabaseConnection.cs10
-rw-r--r--slips/src/app/Marina/DataAccess/IDatabaseConnectionFactory.cs5
-rw-r--r--slips/src/app/Marina/DataAccess/IDatabaseGateway.cs19
-rw-r--r--slips/src/app/Marina/DataAccess/IDatabaseProviderFactory.cs7
-rw-r--r--slips/src/app/Marina/DataAccess/IDatabaseRow.cs5
-rw-r--r--slips/src/app/Marina/DataAccess/IDatabaseTransaction.cs7
-rw-r--r--slips/src/app/Marina/DataAccess/IIdentityMap.cs9
-rw-r--r--slips/src/app/Marina/DataAccess/IdentityMap.cs42
-rw-r--r--slips/src/app/Marina/DataAccess/Repositories/CustomerRepository.cs51
-rw-r--r--slips/src/app/Marina/DataAccess/Repositories/DockRepository.cs20
-rw-r--r--slips/src/app/Marina/DataAccess/Repositories/SlipsRepository.cs58
-rw-r--r--slips/src/app/Marina/DataAccess/Schemas/AuthorizationTable.cs9
-rw-r--r--slips/src/app/Marina/DataAccess/Schemas/BoatTable.cs11
-rw-r--r--slips/src/app/Marina/DataAccess/Schemas/CustomerTable.cs10
-rw-r--r--slips/src/app/Marina/DataAccess/Schemas/DockTable.cs10
-rw-r--r--slips/src/app/Marina/DataAccess/Schemas/LeaseTable.cs11
-rw-r--r--slips/src/app/Marina/DataAccess/Schemas/LeaseType.cs8
-rw-r--r--slips/src/app/Marina/DataAccess/Schemas/LocationTable.cs7
-rw-r--r--slips/src/app/Marina/DataAccess/Schemas/SlipTable.cs9
59 files changed, 1475 insertions, 0 deletions
diff --git a/slips/src/app/Marina/DataAccess/Builders/DatabaseDelete.cs b/slips/src/app/Marina/DataAccess/Builders/DatabaseDelete.cs
new file mode 100644
index 0000000..801aba0
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/DatabaseDelete.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+
+namespace Marina.DataAccess.Builders {
+ public static class DatabaseDelete {
+ public static IQuery Where< T >( DatabaseColumn column, T equalsValue ) {
+ return new DeleteQueryBuilder< T >( column, equalsValue ).Build( );
+ }
+
+ private class DeleteQueryBuilder< T > : IDeleteQueryBuilder {
+ public DeleteQueryBuilder( DatabaseColumn column, T value ) {
+ _column = column;
+ _value = value;
+ }
+
+ public override string ToString() {
+ return string.Format( "DELETE FROM [{0}] WHERE [{0}].[{1}] = @{1};", _column.TableName, _column.ColumnName );
+ }
+
+ public IEnumerable< DatabaseCommandParameter > Parameters() {
+ yield return new DatabaseCommandParameter( _column.ColumnName, _value );
+ }
+
+ public IQuery Build() {
+ return new Query( this );
+ }
+
+ private readonly DatabaseColumn _column;
+ private readonly T _value;
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/DatabaseInsert.cs b/slips/src/app/Marina/DataAccess/Builders/DatabaseInsert.cs
new file mode 100644
index 0000000..57c0c1d
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/DatabaseInsert.cs
@@ -0,0 +1,50 @@
+using System.Collections.Generic;
+using System.Text;
+
+namespace Marina.DataAccess.Builders {
+ public static class DatabaseInsert {
+ public static IInsertQueryBuilder Into( string tableName ) {
+ return new InsertQueryBuilder( tableName );
+ }
+
+ private class InsertQueryBuilder : IInsertQueryBuilder {
+ public InsertQueryBuilder( string tableName ) {
+ _tableName = tableName;
+ _parameters = new List< DatabaseCommandParameter >( );
+ }
+
+ public IEnumerable< DatabaseCommandParameter > Parameters() {
+ return _parameters;
+ }
+
+ public IQuery Build() {
+ return new Query( this );
+ }
+
+ public IInsertQueryBuilder AddValue< T >( DatabaseColumn column, T value ) {
+ _parameters.Add( new DatabaseCommandParameter( column.ColumnName, value ) );
+ return this;
+ }
+
+ public override string ToString() {
+ StringBuilder builder = new StringBuilder( );
+ builder.AppendFormat( "INSERT INTO {0} ({1}) VALUES ({2});SELECT @@IDENTITY;", _tableName,
+ GetParameterNames( string.Empty ),
+ GetParameterNames( "@" ) );
+ return builder.ToString( );
+ }
+
+ private string GetParameterNames( string prefix ) {
+ StringBuilder builder = new StringBuilder( );
+ foreach ( DatabaseCommandParameter parameter in _parameters ) {
+ builder.AppendFormat( "{0}{1},", prefix, parameter.ColumnName );
+ }
+ builder.Remove( builder.Length - 1, 1 );
+ return builder.ToString( );
+ }
+
+ private readonly string _tableName;
+ private readonly IList< DatabaseCommandParameter > _parameters;
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/DatabaseSelect.cs b/slips/src/app/Marina/DataAccess/Builders/DatabaseSelect.cs
new file mode 100644
index 0000000..6e61fff
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/DatabaseSelect.cs
@@ -0,0 +1,101 @@
+using System.Collections.Generic;
+using System.Text;
+
+namespace Marina.DataAccess.Builders {
+ public static class DatabaseSelect {
+ public static ISelectQueryBuilder From( string tableName ) {
+ return new SelectQueryBuilder( tableName );
+ }
+
+ private class SelectQueryBuilder : ISelectQueryBuilder {
+ public SelectQueryBuilder( string tableName ) {
+ _tableName = string.Format( "[{0}]", tableName );
+ _innerJoins = new List< InnerJoin >( );
+ _selectColumns = new List< DatabaseColumn >( );
+ }
+
+ public ISelectQueryBuilder AddColumn( DatabaseColumn column ) {
+ _selectColumns.Add( column );
+ return this;
+ }
+
+ public ISelectQueryBuilder InnerJoinOn( DatabaseColumn leftColumn, DatabaseColumn rightColumn ) {
+ _innerJoins.Add( new InnerJoin( leftColumn, rightColumn ) );
+ return this;
+ }
+
+ public ISelectQueryBuilder Where( DatabaseColumn column, string value ) {
+ _whereClause = new WhereClause( column, value );
+ return this;
+ }
+
+ public ISelectQueryBuilder Where< T >( DatabaseColumn column, T value ) {
+ return Where( column, value.ToString( ) );
+ }
+
+ public override string ToString() {
+ return
+ string.Format( "SELECT {0} FROM {1} {2} {3};", GetColumnNames( ), _tableName, GetInnerJoins( ), _whereClause );
+ }
+
+ public IEnumerable< DatabaseCommandParameter > Parameters() {
+ foreach ( DatabaseColumn databaseColumn in _selectColumns ) {
+ yield return new DatabaseCommandParameter( databaseColumn.ColumnName, string.Empty );
+ }
+ }
+
+ public IQuery Build() {
+ return new Query( this );
+ }
+
+ private string GetInnerJoins() {
+ StringBuilder builder = new StringBuilder( );
+ foreach ( InnerJoin innerJoin in _innerJoins ) {
+ builder.Append( innerJoin.ToString( ) );
+ }
+ return builder.ToString( );
+ }
+
+ private string GetColumnNames() {
+ StringBuilder builder = new StringBuilder( );
+ foreach ( DatabaseColumn selectColumn in _selectColumns ) {
+ builder.AppendFormat( "{0},", selectColumn );
+ }
+ builder.Remove( builder.Length - 1, 1 );
+ return builder.ToString( );
+ }
+
+ private readonly string _tableName;
+ private readonly IList< DatabaseColumn > _selectColumns;
+ private readonly IList< InnerJoin > _innerJoins;
+ private WhereClause _whereClause;
+
+ private class InnerJoin : IJoin {
+ public InnerJoin( DatabaseColumn leftColumn, DatabaseColumn rightColumn ) {
+ _leftColumn = leftColumn;
+ _rightColumn = rightColumn;
+ }
+
+ public DatabaseColumn Left() {
+ return _leftColumn;
+ }
+
+ public DatabaseColumn Right() {
+ return _rightColumn;
+ }
+
+ public override string ToString() {
+ return
+ string.Format( "INNER JOIN [{0}] ON [{0}].[{1}] = [{2}].[{3}]",
+ _leftColumn.TableName,
+ _leftColumn.ColumnName,
+ _rightColumn.TableName,
+ _rightColumn.ColumnName );
+ }
+
+ private readonly DatabaseColumn _leftColumn;
+ private readonly DatabaseColumn _rightColumn;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/DatabaseUpdate.cs b/slips/src/app/Marina/DataAccess/Builders/DatabaseUpdate.cs
new file mode 100644
index 0000000..8b90edc
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/DatabaseUpdate.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Text;
+
+namespace Marina.DataAccess.Builders {
+ public static class DatabaseUpdate {
+ public static IUpdateQueryBuilder Where< T >( DatabaseColumn whereColumn, T whereValue ) {
+ return new UpdateQueryBuilder( whereColumn, whereValue.ToString( ) );
+ }
+
+ private class UpdateQueryBuilder : IUpdateQueryBuilder {
+ public UpdateQueryBuilder( DatabaseColumn whereColumn, string whereValue )
+ : this( new List< DatabaseCommandParameter >( ), new WhereClause( whereColumn, whereValue ) ) {}
+
+ public UpdateQueryBuilder( IList< DatabaseCommandParameter > parameters, WhereClause where ) {
+ _parameters = parameters;
+ _where = where;
+ }
+
+ public IEnumerable< DatabaseCommandParameter > Parameters() {
+ return _parameters;
+ }
+
+ public IQuery Build() {
+ return new Query( this );
+ }
+
+ public IUpdateQueryBuilder Add( DatabaseColumn column, string value ) {
+ _parameters.Add( new DatabaseCommandParameter( column.ColumnName, value ) );
+ return this;
+ }
+
+ public override string ToString() {
+ StringBuilder builder = new StringBuilder( );
+ builder.AppendFormat( "UPDATE [{0}] SET {1};", _where.Column( ).TableName, GetParameterNames( ) );
+ return builder.ToString( );
+ }
+
+ private string GetParameterNames() {
+ StringBuilder builder = new StringBuilder( );
+ foreach ( DatabaseCommandParameter parameter in _parameters ) {
+ builder.AppendFormat( "[{0}].[{1}] = @{1},", _where.Column( ).TableName, parameter.ColumnName );
+ }
+ builder.Remove( builder.Length - 1, 1 );
+ builder.Append( _where );
+ return builder.ToString( );
+ }
+
+ private readonly IList< DatabaseCommandParameter > _parameters;
+ private readonly WhereClause _where;
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/IDeleteQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/IDeleteQueryBuilder.cs
new file mode 100644
index 0000000..2b7290a
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/IDeleteQueryBuilder.cs
@@ -0,0 +1,3 @@
+namespace Marina.DataAccess.Builders {
+ public interface IDeleteQueryBuilder : IQueryBuilder {}
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/IInsertQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/IInsertQueryBuilder.cs
new file mode 100644
index 0000000..946c914
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/IInsertQueryBuilder.cs
@@ -0,0 +1,5 @@
+namespace Marina.DataAccess.Builders {
+ public interface IInsertQueryBuilder : IQueryBuilder {
+ IInsertQueryBuilder AddValue< T >( DatabaseColumn column, T value );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/IJoin.cs b/slips/src/app/Marina/DataAccess/Builders/IJoin.cs
new file mode 100644
index 0000000..c4ae46f
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/IJoin.cs
@@ -0,0 +1,6 @@
+namespace Marina.DataAccess.Builders {
+ internal interface IJoin {
+ DatabaseColumn Left();
+ DatabaseColumn Right();
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/IQuery.cs b/slips/src/app/Marina/DataAccess/Builders/IQuery.cs
new file mode 100644
index 0000000..a45527f
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/IQuery.cs
@@ -0,0 +1,7 @@
+using System.Data;
+
+namespace Marina.DataAccess.Builders {
+ public interface IQuery {
+ void Prepare( IDbCommand command );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/IQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/IQueryBuilder.cs
new file mode 100644
index 0000000..175c2d5
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/IQueryBuilder.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace Marina.DataAccess.Builders {
+ public interface IQueryBuilder {
+ IEnumerable< DatabaseCommandParameter > Parameters();
+
+ IQuery Build();
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/ISelectQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/ISelectQueryBuilder.cs
new file mode 100644
index 0000000..058a7a1
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/ISelectQueryBuilder.cs
@@ -0,0 +1,11 @@
+namespace Marina.DataAccess.Builders {
+ public interface ISelectQueryBuilder : IQueryBuilder {
+ ISelectQueryBuilder AddColumn( DatabaseColumn column );
+
+ ISelectQueryBuilder InnerJoinOn( DatabaseColumn leftColumn, DatabaseColumn rightColumn );
+
+ ISelectQueryBuilder Where( DatabaseColumn column, string value );
+
+ ISelectQueryBuilder Where< T >( DatabaseColumn column, T value );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/IUpdateQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/IUpdateQueryBuilder.cs
new file mode 100644
index 0000000..c599243
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/IUpdateQueryBuilder.cs
@@ -0,0 +1,5 @@
+namespace Marina.DataAccess.Builders {
+ public interface IUpdateQueryBuilder : IQueryBuilder {
+ IUpdateQueryBuilder Add( DatabaseColumn column, string value );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/Query.cs b/slips/src/app/Marina/DataAccess/Builders/Query.cs
new file mode 100644
index 0000000..0b95bf1
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/Query.cs
@@ -0,0 +1,22 @@
+using System.Data;
+
+namespace Marina.DataAccess.Builders {
+ public class Query : IQuery {
+ public Query( IQueryBuilder builder ) {
+ _builder = builder;
+ }
+
+ public void Prepare( IDbCommand command ) {
+ command.CommandText = _builder.ToString( );
+ command.CommandType = CommandType.Text;
+ foreach ( DatabaseCommandParameter parameter in _builder.Parameters( ) ) {
+ IDataParameter commandParameter = command.CreateParameter( );
+ commandParameter.ParameterName = "@" + parameter.ColumnName;
+ commandParameter.Value = parameter.Value;
+ command.Parameters.Add( commandParameter );
+ }
+ }
+
+ private readonly IQueryBuilder _builder;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/SqlQuery.cs b/slips/src/app/Marina/DataAccess/Builders/SqlQuery.cs
new file mode 100644
index 0000000..c6b2b47
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/SqlQuery.cs
@@ -0,0 +1,18 @@
+using System.Data;
+
+namespace Marina.DataAccess.Builders {
+ public class SqlQuery : IQuery {
+ public SqlQuery( string sqlQuery ) {
+ _sqlQuery = sqlQuery;
+ }
+
+ public void Prepare( IDbCommand command ) {
+ if ( command != null ) {
+ command.CommandText = _sqlQuery;
+ command.CommandType = CommandType.Text;
+ }
+ }
+
+ private readonly string _sqlQuery;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Builders/WhereClause.cs b/slips/src/app/Marina/DataAccess/Builders/WhereClause.cs
new file mode 100644
index 0000000..5768fde
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Builders/WhereClause.cs
@@ -0,0 +1,27 @@
+namespace Marina.DataAccess.Builders {
+ public class WhereClause {
+ public WhereClause( DatabaseColumn column, string value ) {
+ _column = column;
+ _value = value;
+ }
+
+ public DatabaseColumn Column() {
+ return _column;
+ }
+
+ public string Value() {
+ return _value;
+ }
+
+ public string ToSql() {
+ return ToString( );
+ }
+
+ public override string ToString() {
+ return string.Format( " WHERE [{0}].[{1}] = {2};", _column.TableName, _column.ColumnName, _value );
+ }
+
+ private readonly DatabaseColumn _column;
+ private readonly string _value;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/BoatDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/BoatDataMapper.cs
new file mode 100644
index 0000000..fbd33cd
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/BoatDataMapper.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using Marina.DataAccess.Builders;
+using Marina.DataAccess.Schemas;
+using Marina.Domain;
+using Marina.Domain.Interfaces;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.DataMappers {
+ public class BoatDataMapper : IBoatDataMapper {
+ public BoatDataMapper() : this( Resolve.DependencyFor< IDatabaseGateway >( ) ) {}
+
+ public BoatDataMapper( IDatabaseGateway gateway ) {
+ _gateway = gateway;
+ }
+
+ public IEnumerable< IBoat > AllBoatsFor( long customerId ) {
+ return Map.From( _gateway.FindAllRowsMatching( Queries.SelectBoatsFor( customerId ) ) );
+ }
+
+ public void Insert( IEnumerable< IBoat > boats, long forCustomerId ) {
+ _gateway.Execute( Queries.InsertQueriesFor( boats, forCustomerId ) );
+ }
+
+ public void Update( IEnumerable< IBoat > boats, long forCustomerId ) {
+ using ( IDatabaseTransaction transaction = new DatabaseTransaction( ) ) {
+ _gateway.Execute( DatabaseDelete.Where( BoatTable.CustomerID, forCustomerId ) );
+ Insert( boats, forCustomerId );
+ transaction.Commit( );
+ }
+ }
+
+ private readonly IDatabaseGateway _gateway;
+
+ private class Queries {
+ public static IQuery SelectBoatsFor( long customerId ) {
+ return DatabaseSelect.From( BoatTable.TableName )
+ .AddColumn( BoatTable.Length )
+ .AddColumn( BoatTable.Manufacturer )
+ .AddColumn( BoatTable.ModelYear )
+ .AddColumn( BoatTable.RegistrationNumber )
+ .AddColumn( BoatTable.BoatID )
+ .Where( BoatTable.CustomerID, customerId.ToString( ) ).Build( );
+ }
+
+ public static IEnumerable< IQuery > InsertQueriesFor( IEnumerable< IBoat > boats, long customerId ) {
+ foreach ( IBoat boat in boats ) {
+ yield return DatabaseInsert.Into( BoatTable.TableName )
+ .AddValue( BoatTable.CustomerID, customerId )
+ .AddValue( BoatTable.Length, boat.LengthInFeet( ) )
+ .AddValue( BoatTable.Manufacturer, boat.Manufacturer( ) )
+ .AddValue( BoatTable.ModelYear, boat.YearOfModel( ).Year )
+ .AddValue( BoatTable.RegistrationNumber, boat.RegistrationNumber( ) ).Build( );
+ }
+ }
+ }
+
+ private class Map {
+ public static IEnumerable< IBoat > From( IEnumerable< IDatabaseRow > rows ) {
+ foreach ( IDatabaseRow dataRow in rows ) {
+ yield return new Boat(
+ dataRow.From< long >( BoatTable.BoatID ),
+ dataRow.From< string >( BoatTable.RegistrationNumber ),
+ dataRow.From< string >( BoatTable.Manufacturer ),
+ dataRow.From< int >( BoatTable.ModelYear ) != 0
+ ? new DateTime( dataRow.From< int >( BoatTable.ModelYear ), 1, 01 )
+ : DateTime.MinValue,
+ dataRow.From< long >( BoatTable.Length )
+ );
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/CustomerDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/CustomerDataMapper.cs
new file mode 100644
index 0000000..cdc56be
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/CustomerDataMapper.cs
@@ -0,0 +1,82 @@
+using Marina.DataAccess.Builders;
+using Marina.DataAccess.Schemas;
+using Marina.Domain;
+using Marina.Domain.Interfaces;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.DataMappers {
+ public class CustomerDataMapper : ICustomerDataMapper {
+ public CustomerDataMapper() : this
+ (
+ Resolve.DependencyFor< IDatabaseGateway >( ),
+ Resolve.DependencyFor< IBoatDataMapper >( ),
+ Resolve.DependencyFor< ILeaseDataMapper >( ),
+ Resolve.DependencyFor< IRegistrationDataMapper >( )
+ ) {}
+
+ public CustomerDataMapper( IDatabaseGateway gateway, IBoatDataMapper boatMapper, ILeaseDataMapper leaseMapper,
+ IRegistrationDataMapper registrationMapper ) {
+ _gateway = gateway;
+ _boatMapper = boatMapper;
+ _leaseMapper = leaseMapper;
+ _registrationMapper = registrationMapper;
+ }
+
+ public ICustomer FindBy( long customerId ) {
+ if ( customerId > 0 ) {
+ return new Customer( customerId,
+ _boatMapper.AllBoatsFor( customerId ),
+ _leaseMapper.AllLeasesFor( customerId ),
+ _registrationMapper.For( customerId ) );
+ }
+ return null;
+ }
+
+ public ICustomer FindBy( string username ) {
+ IDatabaseRow row = _gateway.LoadRowUsing( Queries.SelectCustomerBy( username ) );
+ return FindBy( row.From< long >( AuthorizationTable.CustomerID ) );
+ }
+
+ public void Insert( ICustomer customer ) {
+ using ( IDatabaseTransaction workUnit = new DatabaseTransaction( ) ) {
+ customer.ChangeIdTo( _gateway.ExecuteScalar( Queries.Insert( ) ) );
+ _registrationMapper.Insert( customer.Registration( ), customer.ID( ) );
+ _boatMapper.Insert( customer.RegisteredBoats( ), customer.ID( ) );
+ _leaseMapper.Insert( customer.Leases( ), customer.ID( ) );
+ workUnit.Commit( );
+ }
+ }
+
+ public void Update( ICustomer customer ) {
+ using ( IDatabaseTransaction workUnit = new DatabaseTransaction( ) ) {
+ _registrationMapper.Update( customer.Registration( ), customer.ID( ) );
+ _boatMapper.Update( customer.RegisteredBoats( ), customer.ID( ) );
+ _leaseMapper.Update( customer.Leases( ), customer.ID( ) );
+ workUnit.Commit( );
+ }
+ }
+
+ private readonly IDatabaseGateway _gateway;
+ private readonly IBoatDataMapper _boatMapper;
+ private readonly ILeaseDataMapper _leaseMapper;
+ private readonly IRegistrationDataMapper _registrationMapper;
+
+ private static class Queries {
+ public static IQuery Insert() {
+ return DatabaseInsert.Into( CustomerTable.TableName )
+ .AddValue( CustomerTable.FirstName, string.Empty )
+ .AddValue( CustomerTable.LastName, string.Empty )
+ .AddValue( CustomerTable.Phone, string.Empty )
+ .AddValue( CustomerTable.City, string.Empty ).Build( );
+ }
+
+ public static IQuery SelectCustomerBy( string username ) {
+ return DatabaseSelect.From( AuthorizationTable.TableName )
+ .AddColumn( AuthorizationTable.CustomerID )
+ .AddColumn( AuthorizationTable.UserName )
+ .Where( AuthorizationTable.UserName, "'" + username + "'" )
+ .Build( );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/DockDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/DockDataMapper.cs
new file mode 100644
index 0000000..bf2ae13
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/DockDataMapper.cs
@@ -0,0 +1,54 @@
+using Marina.DataAccess.Builders;
+using Marina.DataAccess.Schemas;
+using Marina.Domain;
+using Marina.Domain.Interfaces;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.DataMappers {
+ public class DockDataMapper : IDockDataMapper {
+ public DockDataMapper() : this( Resolve.DependencyFor< IDatabaseGateway >( ) ) {}
+
+ public DockDataMapper( IDatabaseGateway gateway ) {
+ _gateway = gateway;
+ }
+
+ public IDock FindBy( long dockId ) {
+ return Map.From( _gateway.LoadRowUsing( Queries.SelectDockBy( dockId ) ) );
+ }
+
+ private readonly IDatabaseGateway _gateway;
+
+ private static class Queries {
+ public static IQuery SelectDockBy( long dockId ) {
+ return DatabaseSelect
+ .From( DockTable.TableName )
+ .AddColumn( DockTable.DockID )
+ .AddColumn( DockTable.DockName )
+ .AddColumn( DockTable.LocationId )
+ .AddColumn( DockTable.WaterService )
+ .AddColumn( DockTable.ElectricalService )
+ .AddColumn( LocationTable.Name )
+ .InnerJoinOn( LocationTable.ID, DockTable.LocationId )
+ .Where( DockTable.DockID, dockId ).Build( );
+ }
+ }
+
+ private class Map {
+ public static IDock From( IDatabaseRow row ) {
+ return new Dock(
+ row.From< long >( DockTable.DockID ),
+ row.From< string >( DockTable.DockName ),
+ new Location( row.From< string >( LocationTable.Name ) ),
+ GetEnabledUtilities( row )
+ );
+ }
+
+ private static IUtility GetEnabledUtilities( IDatabaseRow row ) {
+ return Utilities.For(
+ row.From< bool >( DockTable.WaterService ) ? Utilities.Water : null,
+ row.From< bool >( DockTable.ElectricalService ) ? Utilities.Electrical : null
+ );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/IBoatDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/IBoatDataMapper.cs
new file mode 100644
index 0000000..bcdb7d1
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/IBoatDataMapper.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using Marina.Domain.Interfaces;
+
+namespace Marina.DataAccess.DataMappers {
+ public interface IBoatDataMapper {
+ IEnumerable< IBoat > AllBoatsFor( long customerId );
+
+ void Insert( IEnumerable< IBoat > boats, long forCustomerId );
+
+ void Update( IEnumerable< IBoat > boats, long forCustomerId );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/ICustomerDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/ICustomerDataMapper.cs
new file mode 100644
index 0000000..fc757e7
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/ICustomerDataMapper.cs
@@ -0,0 +1,11 @@
+using Marina.Domain.Interfaces;
+
+namespace Marina.DataAccess.DataMappers {
+ public interface ICustomerDataMapper : IDataMapper< ICustomer > {
+ void Insert( ICustomer customer );
+
+ void Update( ICustomer customer );
+
+ ICustomer FindBy( string username );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/IDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/IDataMapper.cs
new file mode 100644
index 0000000..249eeb7
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/IDataMapper.cs
@@ -0,0 +1,5 @@
+namespace Marina.DataAccess.DataMappers {
+ public interface IDataMapper< T > {
+ T FindBy( long id );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/IDockDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/IDockDataMapper.cs
new file mode 100644
index 0000000..5140eb1
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/IDockDataMapper.cs
@@ -0,0 +1,6 @@
+using Marina.DataAccess.DataMappers;
+using Marina.Domain.Interfaces;
+
+namespace Marina.DataAccess.DataMappers {
+ public interface IDockDataMapper : IDataMapper< IDock > {}
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/ILeaseDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/ILeaseDataMapper.cs
new file mode 100644
index 0000000..c7134d7
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/ILeaseDataMapper.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using Marina.Domain.Interfaces;
+
+namespace Marina.DataAccess.DataMappers {
+ public interface ILeaseDataMapper {
+ IEnumerable< ISlipLease > AllLeasesFor( long customerId );
+
+ void Insert( IEnumerable< ISlipLease > leases, long forCustomerId );
+
+ void Update( IEnumerable< ISlipLease > leases, long forCustomerId );
+
+ bool IsLeased( long slipId );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/IRegistrationDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/IRegistrationDataMapper.cs
new file mode 100644
index 0000000..a9f01dc
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/IRegistrationDataMapper.cs
@@ -0,0 +1,11 @@
+using Marina.Domain.Interfaces;
+
+namespace Marina.DataAccess.DataMappers {
+ public interface IRegistrationDataMapper {
+ IRegistration For( long customerId );
+
+ void Insert( IRegistration registration, long forCustomerId );
+
+ void Update( IRegistration registration, long forCustomerId );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/ISlipDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/ISlipDataMapper.cs
new file mode 100644
index 0000000..99ff069
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/ISlipDataMapper.cs
@@ -0,0 +1,9 @@
+using Marina.DataAccess.DataMappers;
+using Marina.Domain.Interfaces;
+using Marina.Infrastructure;
+
+namespace Marina.DataAccess.DataMappers {
+ public interface ISlipDataMapper : IDataMapper< ISlip > {
+ IRichEnumerable< ISlip > AllSlips();
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/LeaseDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/LeaseDataMapper.cs
new file mode 100644
index 0000000..8214b05
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/LeaseDataMapper.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using Marina.DataAccess.Builders;
+using Marina.DataAccess.Schemas;
+using Marina.Domain;
+using Marina.Domain.Interfaces;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.DataMappers {
+ public class LeaseDataMapper : ILeaseDataMapper {
+ public LeaseDataMapper()
+ : this( Resolve.DependencyFor< IDatabaseGateway >( ), Resolve.DependencyFor< ISlipDataMapper >( ) ) {}
+
+ public LeaseDataMapper( IDatabaseGateway gateway, ISlipDataMapper slipMapper ) {
+ _gateway = gateway;
+ _slipMapper = slipMapper;
+ }
+
+ public IEnumerable< ISlipLease > AllLeasesFor( long customerId ) {
+ foreach ( IDatabaseRow row in _gateway.FindAllRowsMatching( Queries.SelectLeasesFor( customerId ) ) ) {
+ yield return
+ new SlipLease(
+ _slipMapper.FindBy( row.From< long >( LeaseTable.SlipID ) ),
+ LeaseDurations.FindFor( row.From< DateTime >( LeaseTable.StartDate ), row.From< DateTime >( LeaseTable.EndDate ) ),
+ row.From< DateTime >( LeaseTable.StartDate ),
+ row.From< DateTime >( LeaseTable.EndDate )
+ );
+ }
+ }
+
+ public void Insert( IEnumerable< ISlipLease > leases, long forCustomerId ) {
+ using ( IDatabaseTransaction transaction = new DatabaseTransaction( ) ) {
+ IList< IQuery > queries = new List< IQuery >( );
+ foreach ( ISlipLease lease in leases ) {
+ queries.Add(
+ DatabaseInsert.Into( LeaseTable.TableName )
+ .AddValue( LeaseTable.StartDate, lease.StartDate( ) )
+ .AddValue( LeaseTable.EndDate, lease.ExpiryDate( ) )
+ .AddValue( LeaseTable.SlipID, lease.Slip( ).ID( ) )
+ .AddValue( LeaseTable.CustomerID, forCustomerId )
+ .AddValue( LeaseTable.LeaseTypeID, lease.Duration( ).ID( ) ).Build( )
+ );
+ }
+ _gateway.Execute( queries );
+ transaction.Commit( );
+ }
+ }
+
+ public void Update( IEnumerable< ISlipLease > leases, long forCustomerId ) {
+ using ( IDatabaseTransaction transaction = new DatabaseTransaction( ) ) {
+ _gateway.Execute( DatabaseDelete.Where( LeaseTable.CustomerID, forCustomerId ) );
+ Insert( leases, forCustomerId );
+ transaction.Commit( );
+ }
+ }
+
+ public bool IsLeased( long slipId ) {
+ IQuery query =
+ DatabaseSelect.From( LeaseTable.TableName ).AddColumn( LeaseTable.SlipID ).Where( LeaseTable.SlipID, slipId ).Build( );
+
+ return !_gateway.LoadRowUsing( query ).Equals( DatabaseRow.Blank );
+ }
+
+ private readonly IDatabaseGateway _gateway;
+ private readonly ISlipDataMapper _slipMapper;
+
+ private static class Queries {
+ public static IQuery SelectLeasesFor( long customerId ) {
+ return DatabaseSelect
+ .From( LeaseTable.TableName )
+ .AddColumn( LeaseTable.EndDate )
+ .AddColumn( LeaseTable.ID )
+ .AddColumn( LeaseTable.LeaseTypeID )
+ .AddColumn( LeaseTable.SlipID )
+ .AddColumn( LeaseTable.StartDate )
+ .Where( LeaseTable.CustomerID, customerId ).Build( );
+ }
+
+ public static IQuery SelectLeaseFor( long slipId ) {
+ return DatabaseSelect.From( LeaseTable.TableName )
+ .AddColumn( LeaseTable.StartDate )
+ .AddColumn( LeaseTable.EndDate )
+ .Where( LeaseTable.SlipID, slipId ).Build( );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/RegistrationDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/RegistrationDataMapper.cs
new file mode 100644
index 0000000..5c2cd41
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/RegistrationDataMapper.cs
@@ -0,0 +1,88 @@
+using Marina.DataAccess.Builders;
+using Marina.DataAccess.Schemas;
+using Marina.Domain;
+using Marina.Domain.Interfaces;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.DataMappers {
+ public class RegistrationDataMapper : IRegistrationDataMapper {
+ public RegistrationDataMapper() : this( Resolve.DependencyFor< IDatabaseGateway >( ) ) {}
+
+ public RegistrationDataMapper( IDatabaseGateway gateway ) {
+ _gateway = gateway;
+ }
+
+ public IRegistration For( long customerId ) {
+ return Mappers.From( _gateway.LoadRowUsing( Queries.SelectRegistrationFor( customerId ) ) );
+ }
+
+ public void Insert( IRegistration registration, long forCustomerId ) {
+ using ( IDatabaseTransaction unitOfWork = new DatabaseTransaction( ) ) {
+ _gateway.Execute( Queries.Insert( registration, forCustomerId ),
+ Queries.UpdateCustomer( registration, forCustomerId ) );
+ unitOfWork.Commit( );
+ }
+ }
+
+ public void Update( IRegistration registration, long forCustomerId ) {
+ using ( IDatabaseTransaction unitOfWork = new DatabaseTransaction( ) ) {
+ _gateway.Execute( Queries.UpdateCustomer( registration, forCustomerId ),
+ Queries.UpdateAuthorization( registration, forCustomerId ) );
+ unitOfWork.Commit( );
+ }
+ }
+
+ private readonly IDatabaseGateway _gateway;
+
+ private class Queries {
+ public static IQuery SelectRegistrationFor( long customerId ) {
+ return DatabaseSelect.From( CustomerTable.TableName )
+ .AddColumn( CustomerTable.FirstName )
+ .AddColumn( CustomerTable.LastName )
+ .AddColumn( CustomerTable.Phone )
+ .AddColumn( CustomerTable.City )
+ .AddColumn( AuthorizationTable.UserName )
+ .AddColumn( AuthorizationTable.Password )
+ .InnerJoinOn( AuthorizationTable.CustomerID, CustomerTable.CustomerID )
+ .Where( CustomerTable.CustomerID, customerId.ToString( ) ).Build( );
+ }
+
+ public static IQuery Insert( IRegistration registration, long forCustomerId ) {
+ return DatabaseInsert.Into( AuthorizationTable.TableName )
+ .AddValue( AuthorizationTable.CustomerID, forCustomerId.ToString( ) )
+ .AddValue( AuthorizationTable.UserName, registration.Username( ) )
+ .AddValue( AuthorizationTable.Password, registration.Password( ) )
+ .Build( );
+ }
+
+ public static IQuery UpdateCustomer( IRegistration registration, long forCustomerId ) {
+ return DatabaseUpdate.Where( CustomerTable.CustomerID, forCustomerId )
+ .Add( CustomerTable.FirstName, registration.FirstName( ) )
+ .Add( CustomerTable.LastName, registration.LastName( ) )
+ .Add( CustomerTable.Phone, registration.PhoneNumber( ) )
+ .Add( CustomerTable.City, registration.City( ) )
+ .Build( );
+ }
+
+ public static IQuery UpdateAuthorization( IRegistration registration, long forCustomerId ) {
+ return DatabaseUpdate.Where( AuthorizationTable.CustomerID, forCustomerId )
+ .Add( AuthorizationTable.UserName, registration.Username( ) )
+ .Add( AuthorizationTable.Password, registration.Password( ) )
+ .Build( );
+ }
+ }
+
+ private class Mappers {
+ public static IRegistration From( IDatabaseRow row ) {
+ return new CustomerRegistration(
+ row.From< string >( AuthorizationTable.UserName ),
+ row.From< string >( AuthorizationTable.Password ),
+ row.From< string >( CustomerTable.FirstName ),
+ row.From< string >( CustomerTable.LastName ),
+ row.From< string >( CustomerTable.Phone ),
+ row.From< string >( CustomerTable.City )
+ );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DataMappers/SlipDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/SlipDataMapper.cs
new file mode 100644
index 0000000..67f7d69
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DataMappers/SlipDataMapper.cs
@@ -0,0 +1,97 @@
+using System.Collections.Generic;
+using Marina.DataAccess.Builders;
+using Marina.DataAccess.Schemas;
+using Marina.Domain;
+using Marina.Domain.Interfaces;
+using Marina.Infrastructure;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.DataMappers {
+ public class SlipDataMapper : ISlipDataMapper {
+ public SlipDataMapper( IDatabaseGateway gateway ) {
+ _gateway = gateway;
+ }
+
+ public ISlip FindBy( long slipId ) {
+ return Map.From( _gateway.LoadRowUsing( Queries.SelectSlipBy( slipId ) ) );
+ }
+
+ public IRichEnumerable< ISlip > AllSlips() {
+ return new RichEnumerable< ISlip >( FetchAllSlips( ) );
+ }
+
+ private IEnumerable< ISlip > FetchAllSlips() {
+ return Map.From( _gateway.FindAllRowsMatching( Queries.SelectAllSlips( ) ) );
+ }
+
+ private readonly IDatabaseGateway _gateway;
+
+ private static class Queries {
+ public static IQuery SelectAllSlips() {
+ return SelectAllColumns( ).Build( );
+ }
+
+ public static IQuery SelectSlipBy( long slipId ) {
+ return SelectAllColumns( ).Where( SlipTable.ID, slipId ).Build( );
+ }
+
+ private static ISelectQueryBuilder SelectAllColumns() {
+ return DatabaseSelect
+ .From( SlipTable.TableName )
+ .AddColumn( SlipTable.ID )
+ .AddColumn( SlipTable.Width )
+ .AddColumn( SlipTable.Length )
+ .AddColumn( SlipTable.DockID )
+ .AddColumn( DockTable.DockName )
+ .AddColumn( DockTable.WaterService )
+ .AddColumn( DockTable.ElectricalService )
+ .AddColumn( LocationTable.Name )
+ .InnerJoinOn( DockTable.DockID, SlipTable.DockID )
+ .InnerJoinOn( LocationTable.ID, DockTable.LocationId );
+ }
+ }
+
+ private static class Map {
+ public static IEnumerable< ISlip > From( IEnumerable< IDatabaseRow > rows ) {
+ return new EnumerableMapper< IDatabaseRow, ISlip >( new DatabaseRowToSlipMapper( ) ).MapFrom( rows );
+ }
+
+ public static ISlip From( IDatabaseRow row ) {
+ return new DatabaseRowToSlipMapper( ).MapFrom( row );
+ }
+
+ private class DatabaseRowToSlipMapper : IMapper< IDatabaseRow, ISlip > {
+ public DatabaseRowToSlipMapper()
+ : this( Resolve.DependencyFor< ILeaseDataMapper >( ) ) {}
+
+ public DatabaseRowToSlipMapper( ILeaseDataMapper leaseDataMapper ) {
+ this.leaseDataMapper = leaseDataMapper;
+ }
+
+ public ISlip MapFrom( IDatabaseRow row ) {
+ return new Slip(
+ row.From< long >( SlipTable.ID ),
+ CreateDockFrom( row ),
+ row.From< int >( SlipTable.Width ),
+ row.From< int >( SlipTable.Length ),
+ leaseDataMapper.IsLeased( row.From< long >( SlipTable.ID ) )
+ );
+ }
+
+ private static Dock CreateDockFrom( IDatabaseRow row ) {
+ return new Dock(
+ row.From< long >( DockTable.DockID ),
+ row.From< string >( DockTable.DockName ),
+ new Location( row.From< string >( LocationTable.Name ) ),
+ Utilities.For(
+ row.From< bool >( DockTable.WaterService ) ? Utilities.Water : null,
+ row.From< bool >( DockTable.ElectricalService ) ? Utilities.Electrical : null
+ )
+ );
+ }
+
+ private readonly ILeaseDataMapper leaseDataMapper;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseColumn.cs b/slips/src/app/Marina/DataAccess/DatabaseColumn.cs
new file mode 100644
index 0000000..cc79200
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseColumn.cs
@@ -0,0 +1,23 @@
+namespace Marina.DataAccess {
+ public class DatabaseColumn {
+ internal DatabaseColumn( string tableName, string columnName ) {
+ _tableName = tableName;
+ _columnName = columnName;
+ }
+
+ public string TableName {
+ get { return _tableName; }
+ }
+
+ public string ColumnName {
+ get { return _columnName; }
+ }
+
+ public override string ToString() {
+ return string.Format( "[{0}].[{1}]", _tableName, _columnName );
+ }
+
+ private readonly string _tableName;
+ private readonly string _columnName;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseCommand.cs b/slips/src/app/Marina/DataAccess/DatabaseCommand.cs
new file mode 100644
index 0000000..f394ec0
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseCommand.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Data;
+
+namespace Marina.DataAccess {
+ public class DatabaseCommand : IDatabaseCommand {
+ public DatabaseCommand( IDbCommand command ) {
+ _command = command;
+ }
+
+ public DataTable ExecuteQuery() {
+ DataTable table = new DataTable( );
+ table.Load( _command.ExecuteReader( ) );
+ return table;
+ }
+
+ public long ExecuteScalarQuery() {
+ object scalar = _command.ExecuteScalar( );
+ return DBNull.Value != scalar ? Convert.ToInt32( scalar ) : -1;
+ }
+
+ private readonly IDbCommand _command;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseCommandParameter.cs b/slips/src/app/Marina/DataAccess/DatabaseCommandParameter.cs
new file mode 100644
index 0000000..84a0675
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseCommandParameter.cs
@@ -0,0 +1,19 @@
+namespace Marina.DataAccess {
+ public class DatabaseCommandParameter {
+ public DatabaseCommandParameter( string columnName, object value ) {
+ _columnName = columnName;
+ _value = value;
+ }
+
+ public string ColumnName {
+ get { return _columnName; }
+ }
+
+ public object Value {
+ get { return _value; }
+ }
+
+ private readonly string _columnName;
+ private readonly object _value;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseConfiguration.cs b/slips/src/app/Marina/DataAccess/DatabaseConfiguration.cs
new file mode 100644
index 0000000..f70a437
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseConfiguration.cs
@@ -0,0 +1,22 @@
+using System.Configuration;
+
+namespace Marina.DataAccess {
+ public class DatabaseConfiguration : IDatabaseConfiguration {
+ private readonly ConnectionStringSettings _connectionSettings;
+
+ public DatabaseConfiguration()
+ : this( ConfigurationManager.ConnectionStrings[ ConfigurationManager.AppSettings[ "ActiveConnection" ] ] ) {}
+
+ public DatabaseConfiguration( ConnectionStringSettings connectionSettings ) {
+ _connectionSettings = connectionSettings;
+ }
+
+ public string ConnectionString() {
+ return _connectionSettings.ConnectionString;
+ }
+
+ public string ProviderName() {
+ return _connectionSettings.ProviderName;
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseConnection.cs b/slips/src/app/Marina/DataAccess/DatabaseConnection.cs
new file mode 100644
index 0000000..b08399f
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseConnection.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Data;
+using Marina.DataAccess.Builders;
+
+namespace Marina.DataAccess {
+ public class DatabaseConnection : IDatabaseConnection {
+ private readonly IDbConnection _connection;
+
+ public DatabaseConnection() : this( new DatabaseConfiguration( ), new DatabaseProviderFactory( ) ) {}
+
+ public DatabaseConnection( IDatabaseConfiguration configuration, IDatabaseProviderFactory providerFactory ) {
+ _connection = providerFactory.CreateConnectionFor( configuration.ProviderName( ) );
+ _connection.ConnectionString = configuration.ConnectionString( );
+ _connection.Open( );
+ }
+
+ public IDatabaseCommand CreateCommandFor( string sqlQuery ) {
+ return CreateCommandFor( new SqlQuery( sqlQuery ) );
+ }
+
+ public IDatabaseCommand CreateCommandFor( IQuery query ) {
+ IDbCommand command = _connection.CreateCommand( );
+ query.Prepare( command );
+ return new DatabaseCommand( command );
+ }
+
+ public void Dispose() {
+ Dispose( true );
+ GC.SuppressFinalize( this );
+ }
+
+ protected virtual void Dispose( bool disposing ) {
+ if ( disposing ) {
+ _connection.Close( );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseConnectionFactory.cs b/slips/src/app/Marina/DataAccess/DatabaseConnectionFactory.cs
new file mode 100644
index 0000000..2747148
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseConnectionFactory.cs
@@ -0,0 +1,7 @@
+namespace Marina.DataAccess {
+ public class DatabaseConnectionFactory : IDatabaseConnectionFactory {
+ public IDatabaseConnection Create() {
+ return new DatabaseConnection( );
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseGateway.cs b/slips/src/app/Marina/DataAccess/DatabaseGateway.cs
new file mode 100644
index 0000000..92892f1
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseGateway.cs
@@ -0,0 +1,60 @@
+using System.Collections.Generic;
+using System.Data;
+using Marina.DataAccess.Builders;
+using Marina.Infrastructure;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess {
+ public class DatabaseGateway : IDatabaseGateway {
+ private readonly IDatabaseConnectionFactory _connectionFactory;
+
+ public DatabaseGateway() : this( Resolve.DependencyFor< IDatabaseConnectionFactory >( ) ) {}
+
+ public DatabaseGateway( IDatabaseConnectionFactory connectionFactory ) {
+ _connectionFactory = connectionFactory;
+ }
+
+ public DataTable LoadTableUsing( string sqlQuery ) {
+ using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) {
+ IDatabaseCommand command = connection.CreateCommandFor( sqlQuery );
+ return ( null != command ) ? command.ExecuteQuery( ) : null;
+ }
+ }
+
+ public IEnumerable< IDatabaseRow > FindAllRowsMatching( IQuery query ) {
+ using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) {
+ DataTable table = connection.CreateCommandFor( query ).ExecuteQuery( );
+ if ( null != table ) {
+ foreach ( DataRow row in table.Rows ) {
+ yield return new DatabaseRow( row );
+ }
+ }
+ }
+ }
+
+ public void Execute( params IQuery[] queries ) {
+ Execute( ListFactory.From( queries ) );
+ }
+
+ public void Execute( IEnumerable< IQuery > queries ) {
+ using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) {
+ foreach ( IQuery query in queries ) {
+ connection.CreateCommandFor( query ).ExecuteQuery( );
+ }
+ }
+ }
+
+ public long ExecuteScalar( IQuery query ) {
+ using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) {
+ return connection.CreateCommandFor( query ).ExecuteScalarQuery( );
+ }
+ }
+
+ public IDatabaseRow LoadRowUsing( IQuery query ) {
+ using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) {
+ DataTable table = connection.CreateCommandFor( query ).ExecuteQuery( );
+ return table.Rows.Count > 0 ? new DatabaseRow( table.Rows[ 0 ] ) : DatabaseRow.Blank;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseProviderFactory.cs b/slips/src/app/Marina/DataAccess/DatabaseProviderFactory.cs
new file mode 100644
index 0000000..f93d964
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseProviderFactory.cs
@@ -0,0 +1,10 @@
+using System.Data;
+using System.Data.Common;
+
+namespace Marina.DataAccess {
+ public class DatabaseProviderFactory : IDatabaseProviderFactory {
+ public IDbConnection CreateConnectionFor( string providerName ) {
+ return DbProviderFactories.GetFactory( providerName ).CreateConnection( );
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseRow.cs b/slips/src/app/Marina/DataAccess/DatabaseRow.cs
new file mode 100644
index 0000000..53d0b45
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseRow.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Data;
+
+namespace Marina.DataAccess {
+ public class DatabaseRow : IDatabaseRow {
+ public DatabaseRow( DataRow row ) {
+ _row = row;
+ }
+
+ public static readonly IDatabaseRow Blank = new BlankDatabaseRow( );
+
+ public T From< T >( DatabaseColumn column ) {
+ return ( T )Convert.ChangeType( _row[ column.ColumnName ], typeof( T ) );
+ }
+
+ private readonly DataRow _row;
+
+ public class BlankDatabaseRow : IDatabaseRow {
+ public T From< T >( DatabaseColumn column ) {
+ return default( T );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/DatabaseTransaction.cs b/slips/src/app/Marina/DataAccess/DatabaseTransaction.cs
new file mode 100644
index 0000000..78d87cf
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/DatabaseTransaction.cs
@@ -0,0 +1,19 @@
+using System.Transactions;
+
+namespace Marina.DataAccess {
+ internal class DatabaseTransaction : IDatabaseTransaction {
+ public DatabaseTransaction() {
+ _scope = new TransactionScope( );
+ }
+
+ public void Commit() {
+ _scope.Complete( );
+ }
+
+ public void Dispose() {
+ _scope.Dispose( );
+ }
+
+ private readonly TransactionScope _scope;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Exceptions/ObjectAlreadyAddedToIdentityMapException.cs b/slips/src/app/Marina/DataAccess/Exceptions/ObjectAlreadyAddedToIdentityMapException.cs
new file mode 100644
index 0000000..a2cf8c9
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Exceptions/ObjectAlreadyAddedToIdentityMapException.cs
@@ -0,0 +1,9 @@
+using System;
+using Marina.Domain.Interfaces;
+
+namespace Marina.DataAccess.Exceptions {
+ public class ObjectAlreadyAddedToIdentityMapException : Exception {
+ public ObjectAlreadyAddedToIdentityMapException( IDomainObject domainObject )
+ : base( "With ID Of: " + domainObject.ID( ) ) {}
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IDatabaseCommand.cs b/slips/src/app/Marina/DataAccess/IDatabaseCommand.cs
new file mode 100644
index 0000000..ef6fbd4
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IDatabaseCommand.cs
@@ -0,0 +1,9 @@
+using System.Data;
+
+namespace Marina.DataAccess {
+ public interface IDatabaseCommand {
+ DataTable ExecuteQuery();
+
+ long ExecuteScalarQuery();
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IDatabaseConfiguration.cs b/slips/src/app/Marina/DataAccess/IDatabaseConfiguration.cs
new file mode 100644
index 0000000..2fb0637
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IDatabaseConfiguration.cs
@@ -0,0 +1,7 @@
+namespace Marina.DataAccess {
+ public interface IDatabaseConfiguration {
+ string ConnectionString();
+
+ string ProviderName();
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IDatabaseConnection.cs b/slips/src/app/Marina/DataAccess/IDatabaseConnection.cs
new file mode 100644
index 0000000..2316741
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IDatabaseConnection.cs
@@ -0,0 +1,10 @@
+using System;
+using Marina.DataAccess.Builders;
+
+namespace Marina.DataAccess {
+ public interface IDatabaseConnection : IDisposable {
+ IDatabaseCommand CreateCommandFor( string sqlQuery );
+
+ IDatabaseCommand CreateCommandFor( IQuery query );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IDatabaseConnectionFactory.cs b/slips/src/app/Marina/DataAccess/IDatabaseConnectionFactory.cs
new file mode 100644
index 0000000..4672c9a
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IDatabaseConnectionFactory.cs
@@ -0,0 +1,5 @@
+namespace Marina.DataAccess {
+ public interface IDatabaseConnectionFactory {
+ IDatabaseConnection Create();
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IDatabaseGateway.cs b/slips/src/app/Marina/DataAccess/IDatabaseGateway.cs
new file mode 100644
index 0000000..f52ea21
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IDatabaseGateway.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using System.Data;
+using Marina.DataAccess.Builders;
+
+namespace Marina.DataAccess {
+ public interface IDatabaseGateway {
+ DataTable LoadTableUsing( string sqlQuery );
+
+ IEnumerable< IDatabaseRow > FindAllRowsMatching( IQuery query );
+
+ void Execute( params IQuery[] queries );
+
+ void Execute( IEnumerable< IQuery > queries );
+
+ long ExecuteScalar( IQuery query );
+
+ IDatabaseRow LoadRowUsing( IQuery query );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IDatabaseProviderFactory.cs b/slips/src/app/Marina/DataAccess/IDatabaseProviderFactory.cs
new file mode 100644
index 0000000..2fbb6b8
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IDatabaseProviderFactory.cs
@@ -0,0 +1,7 @@
+using System.Data;
+
+namespace Marina.DataAccess {
+ public interface IDatabaseProviderFactory {
+ IDbConnection CreateConnectionFor( string providerName );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IDatabaseRow.cs b/slips/src/app/Marina/DataAccess/IDatabaseRow.cs
new file mode 100644
index 0000000..baa07ee
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IDatabaseRow.cs
@@ -0,0 +1,5 @@
+namespace Marina.DataAccess {
+ public interface IDatabaseRow {
+ T From< T >( DatabaseColumn column );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IDatabaseTransaction.cs b/slips/src/app/Marina/DataAccess/IDatabaseTransaction.cs
new file mode 100644
index 0000000..22d83a6
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IDatabaseTransaction.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace Marina.DataAccess {
+ internal interface IDatabaseTransaction : IDisposable {
+ void Commit();
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IIdentityMap.cs b/slips/src/app/Marina/DataAccess/IIdentityMap.cs
new file mode 100644
index 0000000..28ad56e
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IIdentityMap.cs
@@ -0,0 +1,9 @@
+namespace Marina.DataAccess {
+ public interface IIdentityMap< T > {
+ void Add( T domainObject );
+
+ bool ContainsObjectWithIdOf( long idOfObjectToFind );
+
+ T FindObjectWithIdOf( long idOfObjectToFind );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/IdentityMap.cs b/slips/src/app/Marina/DataAccess/IdentityMap.cs
new file mode 100644
index 0000000..c251379
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/IdentityMap.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+using Marina.DataAccess.Exceptions;
+using Marina.Domain.Interfaces;
+
+namespace Marina.DataAccess {
+ public class IdentityMap< T > : IIdentityMap< T > where T : IDomainObject {
+ public IdentityMap() {
+ _items = new List< T >( );
+ }
+
+ public void Add( T domainObject ) {
+ EnsureObjectHasNotAlreadyBeenAdded( domainObject );
+ _items.Add( domainObject );
+ }
+
+ public bool ContainsObjectWithIdOf( long idOfObjectToFind ) {
+ foreach ( T item in _items ) {
+ if ( item.ID( ).Equals( idOfObjectToFind ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public T FindObjectWithIdOf( long idOfObjectToFind ) {
+ foreach ( T item in _items ) {
+ if ( item.ID( ).Equals( idOfObjectToFind ) ) {
+ return item;
+ }
+ }
+ return default( T );
+ }
+
+ private void EnsureObjectHasNotAlreadyBeenAdded( T domainObject ) {
+ if ( ContainsObjectWithIdOf( domainObject.ID( ) ) ) {
+ throw new ObjectAlreadyAddedToIdentityMapException( domainObject );
+ }
+ }
+
+ private readonly IList< T > _items;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Repositories/CustomerRepository.cs b/slips/src/app/Marina/DataAccess/Repositories/CustomerRepository.cs
new file mode 100644
index 0000000..ade3e83
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Repositories/CustomerRepository.cs
@@ -0,0 +1,51 @@
+using Marina.DataAccess.DataMappers;
+using Marina.Domain;
+using Marina.Domain.Interfaces;
+using Marina.Domain.Repositories;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.Repositories {
+ public class CustomerRepository : ICustomerRepository {
+ public CustomerRepository()
+ : this( new IdentityMap< ICustomer >( ), Resolve.DependencyFor< ICustomerDataMapper >( ) ) {}
+
+ public CustomerRepository( IIdentityMap< ICustomer > identityMap, ICustomerDataMapper mapper ) {
+ _identityMap = identityMap;
+ _mapper = mapper;
+ }
+
+ public ICustomer FindBy( long customerId ) {
+ if ( _identityMap.ContainsObjectWithIdOf( customerId ) ) {
+ return _identityMap.FindObjectWithIdOf( customerId );
+ }
+ return FindCustomerBy( customerId );
+ }
+
+ public ICustomer FindBy( string username ) {
+ return _mapper.FindBy( username );
+ }
+
+ public void Save( ICustomer customer ) {
+ if ( _identityMap.ContainsObjectWithIdOf( customer.ID( ) ) ) {
+ _mapper.Update( customer );
+ }
+ else {
+ _mapper.Insert( customer );
+ _identityMap.Add( customer );
+ }
+ }
+
+ public ICustomer NewCustomer() {
+ return new Customer( );
+ }
+
+ private ICustomer FindCustomerBy( long customerId ) {
+ ICustomer customer = _mapper.FindBy( customerId );
+ _identityMap.Add( customer );
+ return customer;
+ }
+
+ private readonly IIdentityMap< ICustomer > _identityMap;
+ private readonly ICustomerDataMapper _mapper;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Repositories/DockRepository.cs b/slips/src/app/Marina/DataAccess/Repositories/DockRepository.cs
new file mode 100644
index 0000000..747ebc2
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Repositories/DockRepository.cs
@@ -0,0 +1,20 @@
+using Marina.DataAccess.DataMappers;
+using Marina.Domain.Interfaces;
+using Marina.Domain.Repositories;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.Repositories {
+ public class DockRepository : IDockRepository {
+ public DockRepository() : this( Resolve.DependencyFor< IDockDataMapper >( ) ) {}
+
+ public DockRepository( IDockDataMapper mapper ) {
+ this.mapper = mapper;
+ }
+
+ public IDock FindBy( long dockId ) {
+ return mapper.FindBy( dockId );
+ }
+
+ private readonly IDockDataMapper mapper;
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Repositories/SlipsRepository.cs b/slips/src/app/Marina/DataAccess/Repositories/SlipsRepository.cs
new file mode 100644
index 0000000..c6f0b3a
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Repositories/SlipsRepository.cs
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using Marina.DataAccess.DataMappers;
+using Marina.Domain.Interfaces;
+using Marina.Domain.Repositories;
+using Marina.Infrastructure;
+using Marina.Infrastructure.Container;
+
+namespace Marina.DataAccess.Repositories {
+ public class SlipsRepository : ISlipsRepository {
+ public SlipsRepository() : this( Resolve.DependencyFor< ISlipDataMapper >( ) ) {}
+
+ public SlipsRepository( ISlipDataMapper mapper ) {
+ this.mapper = mapper;
+ }
+
+ public IEnumerable< ISlip > AllAvailableSlips() {
+ return mapper.AllSlips( ).Where( Is.NotLeased( ) );
+ }
+
+ public IEnumerable< ISlip > AllAvailableSlipsFor( IDock dock ) {
+ return mapper.AllSlips( ).Where( Is.NotLeased( ).And( Is.OnDock( dock ) ) );
+ }
+
+ public ISlip FindBy( long slipId ) {
+ return mapper.FindBy( slipId );
+ }
+
+ private readonly ISlipDataMapper mapper;
+
+ private static class Is {
+ public static ISpecificationBuilder< ISlip > NotLeased() {
+ return new SpecificationBuilder< ISlip >( new IsNotLeased( ) );
+ }
+
+ public static ISpecificationBuilder< ISlip > OnDock( IDock dock ) {
+ return new SpecificationBuilder< ISlip >( new OnDockSpecification( dock ) );
+ }
+
+ private class IsNotLeased : ISpecification< ISlip > {
+ public bool IsSatisfiedBy( ISlip slip ) {
+ return !slip.IsLeased( );
+ }
+ }
+
+ private class OnDockSpecification : ISpecification< ISlip > {
+ private readonly IDock _dock;
+
+ public OnDockSpecification( IDock dock ) {
+ _dock = dock;
+ }
+
+ public bool IsSatisfiedBy( ISlip item ) {
+ return _dock.ID( ).Equals( item.Dock( ).ID( ) );
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Schemas/AuthorizationTable.cs b/slips/src/app/Marina/DataAccess/Schemas/AuthorizationTable.cs
new file mode 100644
index 0000000..73be973
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Schemas/AuthorizationTable.cs
@@ -0,0 +1,9 @@
+namespace Marina.DataAccess.Schemas {
+ public static class AuthorizationTable {
+ public const string TableName = "Authorize";
+ public static readonly DatabaseColumn AuthID = new DatabaseColumn( TableName, "AuthID" );
+ public static readonly DatabaseColumn UserName = new DatabaseColumn( TableName, "UserName" );
+ public static readonly DatabaseColumn Password = new DatabaseColumn( TableName, "Password" );
+ public static readonly DatabaseColumn CustomerID = new DatabaseColumn( TableName, "CustomerID" );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Schemas/BoatTable.cs b/slips/src/app/Marina/DataAccess/Schemas/BoatTable.cs
new file mode 100644
index 0000000..3d4fe6b
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Schemas/BoatTable.cs
@@ -0,0 +1,11 @@
+namespace Marina.DataAccess.Schemas {
+ public static class BoatTable {
+ public const string TableName = "Boat";
+ public static readonly DatabaseColumn BoatID = new DatabaseColumn( TableName, "BoatID" );
+ public static readonly DatabaseColumn RegistrationNumber = new DatabaseColumn( TableName, "RegistrationNumber" );
+ public static readonly DatabaseColumn Manufacturer = new DatabaseColumn( TableName, "Manufacturer" );
+ public static readonly DatabaseColumn ModelYear = new DatabaseColumn( TableName, "ModelYear" );
+ public static readonly DatabaseColumn Length = new DatabaseColumn( TableName, "Length" );
+ public static readonly DatabaseColumn CustomerID = new DatabaseColumn( TableName, "CustomerID" );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Schemas/CustomerTable.cs b/slips/src/app/Marina/DataAccess/Schemas/CustomerTable.cs
new file mode 100644
index 0000000..b719a75
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Schemas/CustomerTable.cs
@@ -0,0 +1,10 @@
+namespace Marina.DataAccess.Schemas {
+ public static class CustomerTable {
+ public const string TableName = "Customer";
+ public static readonly DatabaseColumn CustomerID = new DatabaseColumn( TableName, "CustomerID" );
+ public static readonly DatabaseColumn FirstName = new DatabaseColumn( TableName, "FirstName" );
+ public static readonly DatabaseColumn LastName = new DatabaseColumn( TableName, "LastName" );
+ public static readonly DatabaseColumn Phone = new DatabaseColumn( TableName, "Phone" );
+ public static readonly DatabaseColumn City = new DatabaseColumn( TableName, "City" );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Schemas/DockTable.cs b/slips/src/app/Marina/DataAccess/Schemas/DockTable.cs
new file mode 100644
index 0000000..1350e82
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Schemas/DockTable.cs
@@ -0,0 +1,10 @@
+namespace Marina.DataAccess.Schemas {
+ public static class DockTable {
+ public const string TableName = "Dock";
+ public static readonly DatabaseColumn DockID = new DatabaseColumn( TableName, "DockID" );
+ public static readonly DatabaseColumn DockName = new DatabaseColumn( TableName, "DockName" );
+ public static readonly DatabaseColumn LocationId = new DatabaseColumn( TableName, "LocationId" );
+ public static readonly DatabaseColumn WaterService = new DatabaseColumn( TableName, "WaterService" );
+ public static readonly DatabaseColumn ElectricalService = new DatabaseColumn( TableName, "ElectricalService" );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Schemas/LeaseTable.cs b/slips/src/app/Marina/DataAccess/Schemas/LeaseTable.cs
new file mode 100644
index 0000000..2581372
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Schemas/LeaseTable.cs
@@ -0,0 +1,11 @@
+namespace Marina.DataAccess.Schemas {
+ public static class LeaseTable {
+ public const string TableName = "Lease";
+ public static readonly DatabaseColumn ID = new DatabaseColumn( TableName, "LeaseID" );
+ public static readonly DatabaseColumn StartDate = new DatabaseColumn( TableName, "StartDate" );
+ public static readonly DatabaseColumn EndDate = new DatabaseColumn( TableName, "EndDate" );
+ public static readonly DatabaseColumn SlipID = new DatabaseColumn( TableName, "SlipID" );
+ public static readonly DatabaseColumn CustomerID = new DatabaseColumn( TableName, "CustomerID" );
+ public static readonly DatabaseColumn LeaseTypeID = new DatabaseColumn( TableName, "LeaseTypeID" );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Schemas/LeaseType.cs b/slips/src/app/Marina/DataAccess/Schemas/LeaseType.cs
new file mode 100644
index 0000000..c36cae9
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Schemas/LeaseType.cs
@@ -0,0 +1,8 @@
+namespace Marina.DataAccess.Schemas {
+ public static class LeaseType {
+ public const string TableName = "LeaseType";
+ public static readonly DatabaseColumn LeaseTypeID = new DatabaseColumn( TableName, "LeaseTypeID" );
+ public static readonly DatabaseColumn LeaseTypeName = new DatabaseColumn( TableName, "LeaseTypeName" );
+ public static readonly DatabaseColumn StandardRateAmount = new DatabaseColumn( TableName, "StandardRateAmount" );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Schemas/LocationTable.cs b/slips/src/app/Marina/DataAccess/Schemas/LocationTable.cs
new file mode 100644
index 0000000..eadee0b
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Schemas/LocationTable.cs
@@ -0,0 +1,7 @@
+namespace Marina.DataAccess.Schemas {
+ public class LocationTable {
+ public const string TableName = "Location";
+ public static readonly DatabaseColumn ID = new DatabaseColumn( TableName, "LocationId" );
+ public static readonly DatabaseColumn Name = new DatabaseColumn( TableName, "LocationName" );
+ }
+} \ No newline at end of file
diff --git a/slips/src/app/Marina/DataAccess/Schemas/SlipTable.cs b/slips/src/app/Marina/DataAccess/Schemas/SlipTable.cs
new file mode 100644
index 0000000..fd69733
--- /dev/null
+++ b/slips/src/app/Marina/DataAccess/Schemas/SlipTable.cs
@@ -0,0 +1,9 @@
+namespace Marina.DataAccess.Schemas {
+ public static class SlipTable {
+ public const string TableName = "Slip";
+ public static readonly DatabaseColumn ID = new DatabaseColumn( TableName, "SlipID" );
+ public static readonly DatabaseColumn Width = new DatabaseColumn( TableName, "SlipWidth" );
+ public static readonly DatabaseColumn Length = new DatabaseColumn( TableName, "SlipLength" );
+ public static readonly DatabaseColumn DockID = new DatabaseColumn( TableName, "DockID" );
+ }
+} \ No newline at end of file