|
using System;
using Pfz.Databasing.Filtering;
namespace Pfz.Databasing.Managers
{
/// <summary>
/// This interface is responsible for managing all transitions from
/// Databases to Objects, and is also the point where you can "start"
/// your business logic, as all the actions (select, insert, update and
/// delete) pass throght this object.
/// </summary>
public interface IDatabaseManager
{
/// <summary>
/// Gets the type of the RecordClassGenerator used by this database manager.
/// </summary>
Type RecordClassGeneratorType { get; }
/// <summary>
/// Creates a new connection.
/// The server can use the name param to select the appropriate connection string or, if it only uses
/// one database, can ignore it.
/// </summary>
/// <param name="name">The name of the connection.</param>
/// <returns>A connection object.</returns>
IDatabaseConnection CreateConnection(string name);
/// <summary>
/// Tries to load a record by it's primary key.
/// Returns null if it is not found.
/// </summary>
/// <typeparam name="T">The type of the record to load.</typeparam>
/// <param name="connection">The connection and transaction to use for loading.</param>
/// <param name="primaryKeyValues">The primaryKeyValues in order.</param>
/// <returns>The loaded record or null.</returns>
T TryLoadByPrimaryKey<T>(IDatabaseConnection connection, params object[] primaryKeyValues)
where
T: class, IRecord;
/// <summary>
/// Creates a new (insert) record of the given type.
/// </summary>
/// <typeparam name="T">The type of the record. Must be a persisted one.</typeparam>
/// <param name="connection">A connection if they are needed
/// during object initialization.</param>
/// <returns>The new created record, or throws an exception.</returns>
T Create<T>(IDatabaseConnection connection)
where
T: class, IRecord;
/// <summary>
/// Applies the given record to the database.
/// Returns a new record which any modifications done to fully apply the
/// record, like auto-numbering. This can be the original record or a clone of it.
/// </summary>
T Apply<T>(IDatabaseConnection connection, T record)
where
T: class, IRecord;
/// <summary>
/// Gets a value indicating if the cloning is necessary before apply.
/// For example, when calling it remotelly the object on the remote side is already a clone,
/// so no clonning is needed.
/// </summary>
bool MustCloneBeforeApply { get; }
/// <summary>
/// Executes a select for the given record type.
/// The automatic created part of the select includes all fields, the from and the tablename.
/// You can add the where clause or even some join. An order by is not indicated,
/// as if child classes exist, they will be loaded after the main class, ignoring
/// the order by.
/// </summary>
/// <typeparam name="T">The type of the record to build the select field list.</typeparam>
/// <param name="connection">The connection to use for reading.</param>
/// <param name="sql">The partialSql. You have two options of special parameters:<br/>
/// [CSharpPropertyName] - This is converted into the database field name, if it is different;<br/>
/// {CSharpPropertyName} - This will create a parameter with the right type for the given
/// CSharpPropertyName. In this case, you need to give a parameterValue for it.
/// </param>
/// <param name="parameterValues">The values, in order, for each C#
/// parameter declared in the sql clause using the {}.</param>
/// <returns>An enumerable collection of read-only records.</returns>
IFastEnumerator<T> FastLoadByPartialSql<T>(IDatabaseConnection connection, string sql, params object[] parameterValues)
where
T: class, IRecord;
/// <summary>
/// Loads records using the given filter group.
/// Joins must by created implicity if other records are referenced.
/// </summary>
IFastEnumerator<T> FastLoadByFilterGroup<T>(IDatabaseConnection connection, FilterGroup filterGroup)
where
T: class, IRecord;
/// <summary>
/// Count the number of records of the given type that matches the filter.
/// </summary>
/// <typeparam name="T">The type of the record to count.</typeparam>
/// <param name="connection">The connection to use.</param>
/// <param name="filterGroup">A filter group, or null to count all records.</param>
/// <returns>The number of found records.</returns>
int CountRecordsByFilterGroup<T>(IDatabaseConnection connection, FilterGroup filterGroup)
where
T: class, IRecord;
/// <summary>
/// Gets an enumerator that selects the property values of the given
/// properties/propertypaths. Utilizes the initialRecordType to know where
/// the select begins.
/// </summary>
/// <param name="connection">The connection used to load.</param>
/// <param name="parameters">The parameters used for this advanced load call.</param>
/// <returns>An enumerable collection of value arrays.</returns>
IFastEnumerator<object[]> AdvancedLoad(IDatabaseConnection connection, AdvancedLoadParameters parameters);
/// <summary>
/// Creates the UserImplementation object for the given non-IRecord type.
/// </summary>
/// <typeparam name="T">The type of the interface that is not an IRecord.</typeparam>
/// <param name="record">The record object that also has this interface.</param>
/// <returns>The UserImplementation class which implements such methods.</returns>
T CreateUserImplementation<T>(T record)
where
T: class;
/// <summary>
/// Gets the type of the implemented class for the given
/// record type.
/// </summary>
Type GetImplementedTypeFor(Type recordInterfaceType);
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I started to program computers when I was 11 years old, as a hobbyist, programming in AMOS Basic and Blitz Basic for Amiga.
At 12 I had my first try with assembler, but it was too difficult at the time. Then, in the same year, I learned C and, after learning C, I was finally able to learn assembler (for Motorola 680x0).
Not sure, but probably between 12 and 13, I started to learn C++. I always programmed "in an object oriented way", but using function pointers instead of virtual methods.
At 15 I started to learn Pascal at school and to use Delphi. At 16 I started my first internship (using Delphi). At 18 I started to work professionally using C++ and since then I've developed my programming skills as a professional developer in C++ and C#, generally creating libraries that help other developers do their work easier, faster and with less errors.
Want more info or simply want to contact me?
Take a look at:
http://paulozemek.azurewebsites.net/
Or e-mail me at: paulozemek@outlook.com
Codeproject MVP 2012, 2015 & 2016
Microsoft MVP 2013-2014 (in October 2014 I started working at Microsoft, so I can't be a Microsoft MVP anymore).