Merge with Kayone.

pull/4/head
Mark McDowall 14 years ago
commit a31858bb4c

@ -0,0 +1,914 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Migrator.Framework</name>
</assembly>
<members>
<member name="T:Migrator.Framework.Migration">
<summary>
A migration is a group of transformation applied to the database schema
(or sometimes data) to port the database from one version to another.
The <c>Up()</c> method must apply the modifications (eg.: create a table)
and the <c>Down()</c> method must revert, or rollback the modifications
(eg.: delete a table).
<para>
Each migration must be decorated with the <c>[Migration(0)]</c> attribute.
Each migration number (0) must be unique, or else a
<c>DuplicatedVersionException</c> will be trown.
</para>
<para>
All migrations are executed inside a transaction. If an exception is
thrown, the transaction will be rolledback and transformations wont be
applied.
</para>
<para>
It is best to keep a limited number of transformation inside a migration
so you can easely move from one version of to another with fine grain
modifications.
You should give meaningful name to the migration class and prepend the
migration number to the filename so they keep ordered, eg.:
<c>002_CreateTableTest.cs</c>.
</para>
<para>
Use the <c>Database</c> property to apply transformation and the
<c>Logger</c> property to output informations in the console (or other).
For more details on transformations see
<see cref="T:Migrator.Framework.ITransformationProvider">ITransformationProvider</see>.
</para>
</summary>
<example>
The following migration creates a new Customer table.
(File <c>003_AddCustomerTable.cs</c>)
<code>
[Migration(3)]
public class AddCustomerTable : Migration
{
public override void Up()
{
Database.AddTable("Customer",
new Column("Name", typeof(string), 50),
new Column("Address", typeof(string), 100)
);
}
public override void Down()
{
Database.RemoveTable("Customer");
}
}
</code>
</example>
</member>
<member name="M:Migrator.Framework.IMigration.Up">
<summary>
Defines tranformations to port the database to the current version.
</summary>
</member>
<member name="M:Migrator.Framework.IMigration.AfterUp">
<summary>
This is run after the Up transaction has been committed
</summary>
</member>
<member name="M:Migrator.Framework.IMigration.Down">
<summary>
Defines transformations to revert things done in <c>Up</c>.
</summary>
</member>
<member name="M:Migrator.Framework.IMigration.AfterDown">
<summary>
This is run after the Down transaction has been committed
</summary>
</member>
<member name="M:Migrator.Framework.IMigration.InitializeOnce(System.String[])">
<summary>
This gets called once on the first migration object.
</summary>
</member>
<member name="P:Migrator.Framework.IMigration.Database">
<summary>
Represents the database.
<see cref="T:Migrator.Framework.ITransformationProvider"></see>.
</summary>
<seealso cref="T:Migrator.Framework.ITransformationProvider">Migration.Framework.ITransformationProvider</seealso>
</member>
<member name="M:Migrator.Framework.Migration.Up">
<summary>
Defines tranformations to port the database to the current version.
</summary>
</member>
<member name="M:Migrator.Framework.Migration.AfterUp">
<summary>
This is run after the Up transaction has been committed
</summary>
</member>
<member name="M:Migrator.Framework.Migration.Down">
<summary>
Defines transformations to revert things done in <c>Up</c>.
</summary>
</member>
<member name="M:Migrator.Framework.Migration.AfterDown">
<summary>
This is run after the Down transaction has been committed
</summary>
</member>
<member name="M:Migrator.Framework.Migration.InitializeOnce(System.String[])">
<summary>
This gets called once on the first migration object.
</summary>
</member>
<member name="P:Migrator.Framework.Migration.Database">
<summary>
Represents the database.
<see cref="T:Migrator.Framework.ITransformationProvider"></see>.
</summary>
<seealso cref="T:Migrator.Framework.ITransformationProvider">Migration.Framework.ITransformationProvider</seealso>
</member>
<member name="M:Migrator.Framework.ILogger.Started(System.Collections.Generic.List{System.Int64},System.Int64)">
<summary>
Log that we have started a migration
</summary>
<param name="currentVersion">Start list of versions</param>
<param name="finalVersion">Final Version</param>
</member>
<member name="M:Migrator.Framework.ILogger.MigrateUp(System.Int64,System.String)">
<summary>
Log that we are migrating up
</summary>
<param name="version">Version we are migrating to</param>
<param name="migrationName">Migration name</param>
</member>
<member name="M:Migrator.Framework.ILogger.MigrateDown(System.Int64,System.String)">
<summary>
Log that we are migrating down
</summary>
<param name="version">Version we are migrating to</param>
<param name="migrationName">Migration name</param>
</member>
<member name="M:Migrator.Framework.ILogger.Skipping(System.Int64)">
<summary>
Inform that a migration corresponding to the number of
version is untraceable (not found?) and will be ignored.
</summary>
<param name="version">Version we couldnt find</param>
</member>
<member name="M:Migrator.Framework.ILogger.RollingBack(System.Int64)">
<summary>
Log that we are rolling back to version
</summary>
<param name="originalVersion">
version
</param>
</member>
<member name="M:Migrator.Framework.ILogger.ApplyingDBChange(System.String)">
<summary>
Log a Sql statement that changes the schema or content of the database as part of a migration
</summary>
<remarks>
SELECT statements should not be logged using this method as they do not alter the data or schema of the
database.
</remarks>
<param name="sql">The Sql statement to log</param>
</member>
<member name="M:Migrator.Framework.ILogger.Exception(System.Int64,System.String,System.Exception)">
<summary>
Log that we had an exception on a migration
</summary>
<param name="version">The version of the migration that caused the exception.</param>
<param name="migrationName">The name of the migration that caused the exception.</param>
<param name="ex">The exception itself</param>
</member>
<member name="M:Migrator.Framework.ILogger.Exception(System.String,System.Exception)">
<summary>
Log that we had an exception on a migration
</summary>
<param name="message">An informative message to show to the user.</param>
<param name="ex">The exception itself</param>
</member>
<member name="M:Migrator.Framework.ILogger.Finished(System.Collections.Generic.List{System.Int64},System.Int64)">
<summary>
Log that we have finished a migration
</summary>
<param name="currentVersion">List of versions with which we started</param>
<param name="finalVersion">Final Version</param>
</member>
<member name="M:Migrator.Framework.ILogger.Log(System.String,System.Object[])">
<summary>
Log a message
</summary>
<param name="format">The format string ("{0}, blabla {1}").</param>
<param name="args">Parameters to apply to the format string.</param>
</member>
<member name="M:Migrator.Framework.ILogger.Warn(System.String,System.Object[])">
<summary>
Log a Warning
</summary>
<param name="format">The format string ("{0}, blabla {1}").</param>
<param name="args">Parameters to apply to the format string.</param>
</member>
<member name="M:Migrator.Framework.ILogger.Trace(System.String,System.Object[])">
<summary>
Log a Trace Message
</summary>
<param name="format">The format string ("{0}, blabla {1}").</param>
<param name="args">Parameters to apply to the format string.</param>
</member>
<member name="T:Migrator.Framework.MigrationException">
<summary>
Base class for migration errors.
</summary>
</member>
<member name="M:Migrator.Framework.Support.Inflector.Pluralize(System.String)">
<summary>
Return the plural of a word.
</summary>
<param name="word">The singular form</param>
<returns>The plural form of <paramref name="word"/></returns>
</member>
<member name="M:Migrator.Framework.Support.Inflector.Singularize(System.String)">
<summary>
Return the singular of a word.
</summary>
<param name="word">The plural form</param>
<returns>The singular form of <paramref name="word"/></returns>
</member>
<member name="M:Migrator.Framework.Support.Inflector.Capitalize(System.String)">
<summary>
Capitalizes a word.
</summary>
<param name="word">The word to be capitalized.</param>
<returns><paramref name="word"/> capitalized.</returns>
</member>
<member name="M:Migrator.Framework.StringUtils.ToHumanName(System.String)">
<summary>
Convert a classname to something more readable.
ex.: CreateATable => Create a table
</summary>
<param name="className"></param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.StringUtils.ReplaceOnce(System.String,System.String,System.String)">
<summary>
</summary>
<param name="template"></param>
<param name="placeholder"></param>
<param name="replacement"></param>
<returns></returns>
</member>
<member name="T:Migrator.Framework.Loggers.ILogWriter">
<summary>
Handles writing a message to the log medium (i.e. file, console)
</summary>
</member>
<member name="M:Migrator.Framework.Loggers.ILogWriter.Write(System.String,System.Object[])">
<summary>
Write this message
</summary>
<param name="message"></param>
<param name="args"></param>
</member>
<member name="M:Migrator.Framework.Loggers.ILogWriter.WriteLine(System.String,System.Object[])">
<summary>
Write this message, as a line
</summary>
<param name="message"></param>
<param name="args"></param>
</member>
<member name="T:Migrator.Framework.ColumnProperty">
<summary>
Represents a table column properties.
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.Null">
<summary>
Null is allowable
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.NotNull">
<summary>
Null is not allowable
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.Identity">
<summary>
Identity column, autoinc
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.Unique">
<summary>
Unique Column
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.Indexed">
<summary>
Indexed Column
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.Unsigned">
<summary>
Unsigned Column
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.ForeignKey">
<summary>
Foreign Key
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.PrimaryKey">
<summary>
Primary Key
</summary>
</member>
<member name="F:Migrator.Framework.ColumnProperty.PrimaryKeyWithIdentity">
<summary>
Primary key. Make the column a PrimaryKey and unsigned
</summary>
</member>
<member name="T:Migrator.Framework.JoiningTableTransformationProviderExtensions">
<summary>
A set of extension methods for the transformation provider to make it easier to
build many-to-many joining tables (takes care of adding the joining table and foreign
key constraints as necessary.
<remarks>This functionality was useful when bootstrapping a number of projects a few years ago, but
now that most changes are brown-field I'm thinking of removing these methods as it's easier to maintain
code that creates the tables etc. directly within migration.</remarks>
</summary>
</member>
<member name="T:Migrator.Framework.MigrationAttribute">
<summary>
Describe a migration
</summary>
</member>
<member name="M:Migrator.Framework.MigrationAttribute.#ctor(System.Int64)">
<summary>
Describe the migration
</summary>
<param name="version">The unique version of the migration.</param>
</member>
<member name="P:Migrator.Framework.MigrationAttribute.Version">
<summary>
The version reflected by the migration
</summary>
</member>
<member name="P:Migrator.Framework.MigrationAttribute.Ignore">
<summary>
Set to <c>true</c> to ignore this migration.
</summary>
</member>
<member name="T:Migrator.Framework.ITransformationProvider">
<summary>
The main interface to use in Migrations to make changes on a database schema.
</summary>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32,Migrator.Framework.ColumnProperty,System.Object)">
<summary>
Add a column to an existing table
</summary>
<param name="table">The name of the table that will get the new column</param>
<param name="column">The name of the new column</param>
<param name="type">The data type for the new columnd</param>
<param name="size">The precision or size of the column</param>
<param name="property">Properties that can be ORed together</param>
<param name="defaultValue">The default value of the column if no value is given in a query</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddColumn(System.String,System.String,System.Data.DbType)">
<summary>
Add a column to an existing table
</summary>
<param name="table">The name of the table that will get the new column</param>
<param name="column">The name of the new column</param>
<param name="type">The data type for the new columnd</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32)">
<summary>
Add a column to an existing table
</summary>
<param name="table">The name of the table that will get the new column</param>
<param name="column">The name of the new column</param>
<param name="type">The data type for the new columnd</param>
<param name="size">The precision or size of the column</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32,Migrator.Framework.ColumnProperty)">
<summary>
Add a column to an existing table
</summary>
<param name="table">The name of the table that will get the new column</param>
<param name="column">The name of the new column</param>
<param name="type">The data type for the new columnd</param>
<param name="size">The precision or size of the column</param>
<param name="property">Properties that can be ORed together</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,Migrator.Framework.ColumnProperty)">
<summary>
Add a column to an existing table
</summary>
<param name="table">The name of the table that will get the new column</param>
<param name="column">The name of the new column</param>
<param name="type">The data type for the new columnd</param>
<param name="property">Properties that can be ORed together</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Object)">
<summary>
Add a column to an existing table with the default column size.
</summary>
<param name="table">The name of the table that will get the new column</param>
<param name="column">The name of the new column</param>
<param name="type">The data type for the new columnd</param>
<param name="defaultValue">The default value of the column if no value is given in a query</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddColumn(System.String,Migrator.Framework.Column)">
<summary>
Add a column to an existing table
</summary>
<param name="table">The name of the table that will get the new column</param>
<param name="column">An instance of a <see cref="T:Migrator.Framework.Column">Column</see> with the specified properties</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddForeignKey(System.String,System.String,System.String[],System.String,System.String[])">
<summary>
Add a foreign key constraint
</summary>
<param name="name">The name of the foreign key. e.g. FK_TABLE_REF</param>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="foreignColumns">The columns that are the foreign keys (eg. FK_id)</param>
<param name="primaryTable">The table that holds the primary keys (eg. Table.PK_id)</param>
<param name="primaryColumns">The columns that are the primary keys (eg. PK_id)</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddForeignKey(System.String,System.String,System.String[],System.String,System.String[],Migrator.Framework.ForeignKeyConstraint)">
<summary>
Add a foreign key constraint
</summary>
<param name="name">The name of the foreign key. e.g. FK_TABLE_REF</param>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="foreignColumns">The columns that are the foreign keys (eg. FK_id)</param>
<param name="primaryTable">The table that holds the primary keys (eg. Table.PK_id)</param>
<param name="primaryColumns">The columns that are the primary keys (eg. PK_id)</param>
<param name="constraint">Constraint parameters</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddForeignKey(System.String,System.String,System.String,System.String,System.String)">
<summary>
Add a foreign key constraint
</summary>
<param name="name">The name of the foreign key. e.g. FK_TABLE_REF</param>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="foreignColumn">The column that is the foreign key (eg. FK_id)</param>
<param name="primaryTable">The table that holds the primary keys (eg. Table.PK_id)</param>
<param name="primaryColumn">The column that is the primary key (eg. PK_id)</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddForeignKey(System.String,System.String,System.String,System.String,System.String,Migrator.Framework.ForeignKeyConstraint)">
<summary>
Add a foreign key constraint
</summary>
<param name="name">The name of the foreign key. e.g. FK_TABLE_REF</param>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="foreignColumn">The column that is the foreign key (eg. FK_id)</param>
<param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
<param name="primaryColumn">The column that is the primary key (eg. PK_id)</param>
<param name="constraint">Constraint parameters</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GenerateForeignKey(System.String,System.String,System.String,System.String)">
<summary>
Add a foreign key constraint when you don't care about the name of the constraint.
Warning: This will prevent you from dropping the constraint since you won't know the name.
</summary>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="foreignColumn">The column that is the foreign key (eg. FK_id)</param>
<param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
<param name="primaryColumn">The column that is the primary key (eg. PK_id)</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GenerateForeignKey(System.String,System.String[],System.String,System.String[])">
<summary>
Add a foreign key constraint when you don't care about the name of the constraint.
Warning: This will prevent you from dropping the constraint since you won't know the name.
</summary>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="foreignColumns">The columns that are the foreign keys (eg. FK_id)</param>
<param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
<param name="primaryColumns">The column that is the primary key (eg. PK_id)</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GenerateForeignKey(System.String,System.String[],System.String,System.String[],Migrator.Framework.ForeignKeyConstraint)">
<summary>
Add a foreign key constraint when you don't care about the name of the constraint.
Warning: This will prevent you from dropping the constraint since you won't know the name.
</summary>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="foreignColumns">The columns that are the foreign keys (eg. FK_id)</param>
<param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
<param name="primaryColumns">The columns that are the primary keys (eg. PK_id)</param>
<param name="constraint">Constraint parameters</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GenerateForeignKey(System.String,System.String,System.String,System.String,Migrator.Framework.ForeignKeyConstraint)">
<summary>
Add a foreign key constraint when you don't care about the name of the constraint.
Warning: This will prevent you from dropping the constraint since you won't know the name.
</summary>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="foreignColumn">The columns that are the foreign keys (eg. FK_id)</param>
<param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
<param name="primaryColumn">The column that is the primary key (eg. PK_id)</param>
<param name="constraint">Constraint parameters</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GenerateForeignKey(System.String,System.String)">
<summary>
Add a foreign key constraint when you don't care about the name of the constraint.
Warning: This will prevent you from dropping the constraint since you won't know the name.
The current expectations are that there is a column named the same as the foreignTable present in
the table. This is subject to change because I think it's not a good convention.
</summary>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GenerateForeignKey(System.String,System.String,Migrator.Framework.ForeignKeyConstraint)">
<summary>
Add a foreign key constraint when you don't care about the name of the constraint.
Warning: This will prevent you from dropping the constraint since you won't know the name.
The current expectations are that there is a column named the same as the foreignTable present in
the table. This is subject to change because I think it's not a good convention.
</summary>
<param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
<param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
<param name="constraint"></param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddPrimaryKey(System.String,System.String,System.String[])">
<summary>
Add a primary key to a table
</summary>
<param name="name">The name of the primary key to add.</param>
<param name="table">The name of the table that will get the primary key.</param>
<param name="columns">The name of the column or columns that are in the primary key.</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddUniqueConstraint(System.String,System.String,System.String[])">
<summary>
Add a constraint to a table
</summary>
<param name="name">The name of the constraint to add.</param>
<param name="table">The name of the table that will get the constraint</param>
<param name="columns">The name of the column or columns that will get the constraint.</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddCheckConstraint(System.String,System.String,System.String)">
<summary>
Add a constraint to a table
</summary>
<param name="name">The name of the constraint to add.</param>
<param name="table">The name of the table that will get the constraint</param>
<param name="checkSql">The check constraint definition.</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddTable(System.String,Migrator.Framework.Column[])">
<summary>
Add a table
</summary>
<param name="name">The name of the table to add.</param>
<param name="columns">The columns that are part of the table.</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.AddTable(System.String,System.String,Migrator.Framework.Column[])">
<summary>
Add a table
</summary>
<param name="name">The name of the table to add.</param>
<param name="engine">The name of the database engine to use. (MySQL)</param>
<param name="columns">The columns that are part of the table.</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.BeginTransaction">
<summary>
Start a transction
</summary>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.ChangeColumn(System.String,Migrator.Framework.Column)">
<summary>
Change the definition of an existing column.
</summary>
<param name="table">The name of the table that will get the new column</param>
<param name="column">An instance of a <see cref="T:Migrator.Framework.Column">Column</see> with the specified properties and the name of an existing column</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.ColumnExists(System.String,System.String)">
<summary>
Check to see if a column exists
</summary>
<param name="table"></param>
<param name="column"></param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Commit">
<summary>
Commit the running transction
</summary>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.ConstraintExists(System.String,System.String)">
<summary>
Check to see if a constraint exists
</summary>
<param name="name">The name of the constraint</param>
<param name="table">The table that the constraint lives on.</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.PrimaryKeyExists(System.String,System.String)">
<summary>
Check to see if a primary key constraint exists on the table
</summary>
<param name="name">The name of the primary key</param>
<param name="table">The table that the constraint lives on.</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.ExecuteNonQuery(System.String)">
<summary>
Execute an arbitrary SQL query
</summary>
<param name="sql">The SQL to execute.</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.ExecuteQuery(System.String)">
<summary>
Execute an arbitrary SQL query
</summary>
<param name="sql">The SQL to execute.</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.ExecuteScalar(System.String)">
<summary>
Execute an arbitrary SQL query
</summary>
<param name="sql">The SQL to execute.</param>
<returns>A single value that is returned.</returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GetColumns(System.String)">
<summary>
Get the information about the columns in a table
</summary>
<param name="table">The table name that you want the columns for.</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GetColumnByName(System.String,System.String)">
<summary>
Get information about a single column in a table
</summary>
<param name="table">The table name that you want the columns for.</param>
<param name="column">The column name for which you want information.</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GetTables">
<summary>
Get the names of all of the tables
</summary>
<returns>The names of all the tables.</returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Insert(System.String,System.String[],System.Object[])">
<summary>
Insert data into a table
</summary>
<param name="table">The table that will get the new data</param>
<param name="columns">The names of the columns</param>
<param name="values">The values in the same order as the columns</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Delete(System.String,System.String[],System.String[])">
<summary>
Delete data from a table
</summary>
<param name="table">The table that will have the data deleted</param>
<param name="columns">The names of the columns used in a where clause</param>
<param name="values">The values in the same order as the columns</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Delete(System.String,System.String,System.String)">
<summary>
Delete data from a table
</summary>
<param name="table">The table that will have the data deleted</param>
<param name="whereColumn">The name of the column used in a where clause</param>
<param name="whereValue">The value for the where clause</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.MigrationApplied(System.Int64)">
<summary>
Marks a Migration version number as having been applied
</summary>
<param name="version">The version number of the migration that was applied</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.MigrationUnApplied(System.Int64)">
<summary>
Marks a Migration version number as having been rolled back from the database
</summary>
<param name="version">The version number of the migration that was removed</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.RemoveColumn(System.String,System.String)">
<summary>
Remove an existing column from a table
</summary>
<param name="table">The name of the table to remove the column from</param>
<param name="column">The column to remove</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.RemoveForeignKey(System.String,System.String)">
<summary>
Remove an existing foreign key constraint
</summary>
<param name="table">The table that contains the foreign key.</param>
<param name="name">The name of the foreign key to remove</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.RemoveConstraint(System.String,System.String)">
<summary>
Remove an existing constraint
</summary>
<param name="table">The table that contains the foreign key.</param>
<param name="name">The name of the constraint to remove</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.RemoveTable(System.String)">
<summary>
Remove an existing table
</summary>
<param name="tableName">The name of the table</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.RenameTable(System.String,System.String)">
<summary>
Rename an existing table
</summary>
<param name="oldName">The old name of the table</param>
<param name="newName">The new name of the table</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.RenameColumn(System.String,System.String,System.String)">
<summary>
Rename an existing table
</summary>
<param name="tableName">The name of the table</param>
<param name="oldColumnName">The old name of the column</param>
<param name="newColumnName">The new name of the column</param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Rollback">
<summary>
Rollback the currently running transaction.
</summary>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Select(System.String,System.String,System.String)">
<summary>
Get values from a table
</summary>
<param name="what">The columns to select</param>
<param name="from">The table to select from</param>
<param name="where">The where clause to limit the selection</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Select(System.String,System.String)">
<summary>
Get values from a table
</summary>
<param name="what">The columns to select</param>
<param name="from">The table to select from</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.SelectScalar(System.String,System.String,System.String)">
<summary>
Get a single value from a table
</summary>
<param name="what">The columns to select</param>
<param name="from">The table to select from</param>
<param name="where"></param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.SelectScalar(System.String,System.String)">
<summary>
Get a single value from a table
</summary>
<param name="what">The columns to select</param>
<param name="from">The table to select from</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.TableExists(System.String)">
<summary>
Check if a table already exists
</summary>
<param name="tableName">The name of the table that you want to check on.</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Update(System.String,System.String[],System.String[])">
<summary>
Update the values in a table
</summary>
<param name="table">The name of the table to update</param>
<param name="columns">The names of the columns.</param>
<param name="columnValues">The values for the columns in the same order as the names.</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Update(System.String,System.String[],System.String[],System.String)">
<summary>
Update the values in a table
</summary>
<param name="table">The name of the table to update</param>
<param name="columns">The names of the columns.</param>
<param name="values">The values for the columns in the same order as the names.</param>
<param name="where">A where clause to limit the update</param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.GetCommand">
<summary>
Get a command instance
</summary>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.ExecuteSchemaBuilder(Migrator.Framework.SchemaBuilder.SchemaBuilder)">
<summary>
Execute a schema builder
</summary>
<param name="schemaBuilder"></param>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.QuoteColumnNamesIfRequired(System.String[])">
<summary>
Quote a multiple column names, if required
</summary>
<param name="columnNames"></param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.QuoteColumnNameIfRequired(System.String)">
<summary>
Quaote column if required
</summary>
<param name="name"></param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.QuoteTableNameIfRequired(System.String)">
<summary>
Quote table name if required
</summary>
<param name="name"></param>
<returns></returns>
</member>
<member name="M:Migrator.Framework.ITransformationProvider.Encode(System.Guid)">
<summary>
Encodes a guid value as a string, suitable for inclusion in sql statement
</summary>
<param name="guid"></param>
<returns></returns>
</member>
<member name="P:Migrator.Framework.ITransformationProvider.Item(System.String)">
<summary>
Get this provider or a NoOp provider if you are not running in the context of 'provider'.
</summary>
</member>
<member name="P:Migrator.Framework.ITransformationProvider.AppliedMigrations">
<summary>
The list of Migrations currently applied to the database.
</summary>
</member>
<member name="P:Migrator.Framework.ITransformationProvider.Logger">
<summary>
Logger used to log details of operations performed during migration
</summary>
</member>
<member name="T:Migrator.Framework.Loggers.IAttachableLogger">
<summary>
ILogger interface.
Implicit in this interface is that the logger will delegate actual
logging to the <see cref="T:Migrator.Framework.Loggers.ILogWriter"/>(s) that have been attached
</summary>
</member>
<member name="M:Migrator.Framework.Loggers.IAttachableLogger.Attach(Migrator.Framework.Loggers.ILogWriter)">
<summary>
Attach an <see cref="T:Migrator.Framework.Loggers.ILogWriter"/>
</summary>
<param name="writer"></param>
</member>
<member name="M:Migrator.Framework.Loggers.IAttachableLogger.Detach(Migrator.Framework.Loggers.ILogWriter)">
<summary>
Detach an <see cref="T:Migrator.Framework.Loggers.ILogWriter"/>
</summary>
<param name="writer"></param>
</member>
<member name="T:Migrator.Framework.Column">
<summary>
Represents a table column.
</summary>
</member>
<member name="M:Migrator.Framework.SchemaBuilder.SchemaBuilder.AddTable(System.String)">
<summary>
Adds a Table to be created to the Schema
</summary>
<param name="name">Table name to be created</param>
<returns>SchemaBuilder for chaining</returns>
</member>
<member name="M:Migrator.Framework.SchemaBuilder.SchemaBuilder.WithTable(System.String)">
<summary>
Reference an existing table.
</summary>
<param name="name">Table to reference</param>
<returns>SchemaBuilder for chaining</returns>
</member>
<member name="M:Migrator.Framework.SchemaBuilder.SchemaBuilder.RenameTable(System.String)">
<summary>
Reference an existing table.
</summary>
<param name="newName">Table to reference</param>
<returns>SchemaBuilder for chaining</returns>
</member>
<member name="M:Migrator.Framework.SchemaBuilder.SchemaBuilder.AddColumn(System.String)">
<summary>
Adds a Column to be created
</summary>
<param name="name">Column name to be added</param>
<returns>IColumnOptions to restrict chaining</returns>
</member>
<member name="T:Migrator.Framework.Loggers.Logger">
<summary>
Text logger for the migration mediator
</summary>
</member>
</members>
</doc>

@ -0,0 +1,389 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Migrator.Providers</name>
</assembly>
<members>
<member name="T:Migrator.Providers.SQLite.SQLiteTransformationProvider">
<summary>
Summary description for SQLiteTransformationProvider.
</summary>
</member>
<member name="T:Migrator.Providers.TransformationProvider">
<summary>
Base class for every transformation providers.
A 'tranformation' is an operation that modifies the database.
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddTable(System.String,Migrator.Framework.Column[])">
<summary>
Add a new table
</summary>
<param name="name">Table name</param>
<param name="columns">Columns</param>
<example>
Adds the Test table with two columns:
<code>
Database.AddTable("Test",
new Column("Id", typeof(int), ColumnProperty.PrimaryKey),
new Column("Title", typeof(string), 100)
);
</code>
</example>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddTable(System.String,System.String,Migrator.Framework.Column[])">
<summary>
Add a new table
</summary>
<param name="name">Table name</param>
<param name="columns">Columns</param>
<param name="engine">the database storage engine to use</param>
<example>
Adds the Test table with two columns:
<code>
Database.AddTable("Test", "INNODB",
new Column("Id", typeof(int), ColumnProperty.PrimaryKey),
new Column("Title", typeof(string), 100)
);
</code>
</example>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32,Migrator.Framework.ColumnProperty,System.Object)">
<summary>
Add a new column to an existing table.
</summary>
<param name="table">Table to which to add the column</param>
<param name="column">Column name</param>
<param name="type">Date type of the column</param>
<param name="size">Max length of the column</param>
<param name="property">Properties of the column, see <see cref="T:Migrator.Framework.ColumnProperty">ColumnProperty</see>,</param>
<param name="defaultValue">Default value</param>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType)">
<summary>
<see cref="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32,Migrator.Framework.ColumnProperty,System.Object)">
AddColumn(string, string, Type, int, ColumnProperty, object)
</see>
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32)">
<summary>
<see cref="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32,Migrator.Framework.ColumnProperty,System.Object)">
AddColumn(string, string, Type, int, ColumnProperty, object)
</see>
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,Migrator.Framework.ColumnProperty)">
<summary>
<see cref="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32,Migrator.Framework.ColumnProperty,System.Object)">
AddColumn(string, string, Type, int, ColumnProperty, object)
</see>
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32,Migrator.Framework.ColumnProperty)">
<summary>
<see cref="M:Migrator.Providers.TransformationProvider.AddColumn(System.String,System.String,System.Data.DbType,System.Int32,Migrator.Framework.ColumnProperty,System.Object)">
AddColumn(string, string, Type, int, ColumnProperty, object)
</see>
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddPrimaryKey(System.String,System.String,System.String[])">
<summary>
Append a primary key to a table.
</summary>
<param name="name">Constraint name</param>
<param name="table">Table name</param>
<param name="columns">Primary column names</param>
</member>
<member name="M:Migrator.Providers.TransformationProvider.GenerateForeignKey(System.String,System.String,System.String,System.String)">
<summary>
Guesses the name of the foreign key and add it
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.GenerateForeignKey(System.String,System.String[],System.String,System.String[])">
<summary>
Guesses the name of the foreign key and add it
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.GenerateForeignKey(System.String,System.String,System.String,System.String,Migrator.Framework.ForeignKeyConstraint)">
<summary>
Guesses the name of the foreign key and add it
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.GenerateForeignKey(System.String,System.String[],System.String,System.String[],Migrator.Framework.ForeignKeyConstraint)">
<summary>
Guesses the name of the foreign key and add it
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddForeignKey(System.String,System.String,System.String,System.String,System.String)">
<summary>
Append a foreign key (relation) between two tables.
tables.
</summary>
<param name="name">Constraint name</param>
<param name="primaryTable">Table name containing the primary key</param>
<param name="primaryColumn">Primary key column name</param>
<param name="refTable">Foreign table name</param>
<param name="refColumn">Foreign column name</param>
</member>
<member name="M:Migrator.Providers.TransformationProvider.AddForeignKey(System.String,System.String,System.String[],System.String,System.String[])">
<summary>
<see cref="M:Migrator.Framework.ITransformationProvider.AddForeignKey(System.String,System.String,System.String,System.String,System.String)">
AddForeignKey(string, string, string, string, string)
</see>
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.ConstraintExists(System.String,System.String)">
<summary>
Determines if a constraint exists.
</summary>
<param name="name">Constraint name</param>
<param name="table">Table owning the constraint</param>
<returns><c>true</c> if the constraint exists.</returns>
</member>
<member name="M:Migrator.Providers.TransformationProvider.ExecuteQuery(System.String)">
<summary>
Execute an SQL query returning results.
</summary>
<param name="sql">The SQL command.</param>
<returns>A data iterator, <see cref="T:System.Data.IDataReader">IDataReader</see>.</returns>
</member>
<member name="M:Migrator.Providers.TransformationProvider.BeginTransaction">
<summary>
Starts a transaction. Called by the migration mediator.
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.Rollback">
<summary>
Rollback the current migration. Called by the migration mediator.
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.Commit">
<summary>
Commit the current transaction. Called by the migrations mediator.
</summary>
</member>
<member name="M:Migrator.Providers.TransformationProvider.MigrationApplied(System.Int64)">
<summary>
Marks a Migration version number as having been applied
</summary>
<param name="version">The version number of the migration that was applied</param>
</member>
<member name="M:Migrator.Providers.TransformationProvider.MigrationUnApplied(System.Int64)">
<summary>
Marks a Migration version number as having been rolled back from the database
</summary>
<param name="version">The version number of the migration that was removed</param>
</member>
<member name="P:Migrator.Providers.TransformationProvider.Logger">
<summary>
Returns the event logger
</summary>
</member>
<member name="P:Migrator.Providers.TransformationProvider.AppliedMigrations">
<summary>
The list of Migrations currently applied to the database.
</summary>
</member>
<member name="M:Migrator.Providers.SQLite.SQLiteTransformationProvider.ParseSqlForColumnNames(System.String)">
<summary>
Turn something like 'columnName INTEGER NOT NULL' into just 'columnName'
</summary>
</member>
<member name="M:Migrator.Providers.SQLite.SQLiteTransformationProvider.ExtractNameFromColumnDef(System.String)">
<summary>
Name is the first value before the space.
</summary>
<param name="columnDef"></param>
<returns></returns>
</member>
<member name="T:Migrator.Providers.NoOpTransformationProvider">
<summary>
No Op (Null Object Pattern) implementation of the ITransformationProvider
</summary>
</member>
<member name="T:Migrator.Providers.Dialect">
<summary>
Defines the implementations specific details for a particular database.
</summary>
</member>
<member name="M:Migrator.Providers.Dialect.RegisterColumnType(System.Data.DbType,System.Int32,System.String)">
<summary>
Subclasses register a typename for the given type code and maximum
column length. <c>$l</c> in the type name will be replaced by the column
length (if appropriate)
</summary>
<param name="code">The typecode</param>
<param name="capacity">Maximum length of database type</param>
<param name="name">The database type name</param>
</member>
<member name="M:Migrator.Providers.Dialect.RegisterColumnType(System.Data.DbType,System.String)">
<summary>
Suclasses register a typename for the given type code. <c>$l</c> in the
typename will be replaced by the column length (if appropriate).
</summary>
<param name="code">The typecode</param>
<param name="name">The database type name</param>
</member>
<member name="M:Migrator.Providers.Dialect.GetTypeName(System.Data.DbType)">
<summary>
Get the name of the database type associated with the given
</summary>
<param name="type">The DbType</param>
<returns>The database type name used by ddl.</returns>
</member>
<member name="M:Migrator.Providers.Dialect.GetTypeName(System.Data.DbType,System.Int32)">
<summary>
Get the name of the database type associated with the given
</summary>
<param name="type">The DbType</param>
<returns>The database type name used by ddl.</returns>
<param name="length"></param>
</member>
<member name="M:Migrator.Providers.Dialect.GetTypeName(System.Data.DbType,System.Int32,System.Int32,System.Int32)">
<summary>
Get the name of the database type associated with the given
</summary>
<param name="type">The DbType</param>
<returns>The database type name used by ddl.</returns>
<param name="length"></param>
<param name="precision"></param>
<param name="scale"></param>
</member>
<member name="M:Migrator.Providers.Dialect.RegisterUnsignedCompatible(System.Data.DbType)">
<summary>
Subclasses register which DbTypes are unsigned-compatible (ie, available in signed and unsigned variants)
</summary>
<param name="type"></param>
</member>
<member name="M:Migrator.Providers.Dialect.IsUnsignedCompatible(System.Data.DbType)">
<summary>
Determine if a particular database type has an unsigned variant
</summary>
<param name="type">The DbType</param>
<returns>True if the database type has an unsigned variant, otherwise false</returns>
</member>
<member name="T:Migrator.Providers.SqlServer.SqlServerCeTransformationProvider">
<summary>
Migration transformations provider for Microsoft SQL Server.
</summary>
</member>
<member name="T:Migrator.Providers.SqlServer.SqlServerTransformationProvider">
<summary>
Migration transformations provider for Microsoft SQL Server.
</summary>
</member>
<member name="T:Migrator.Providers.PostgreSQL.PostgreSQLTransformationProvider">
<summary>
Migration transformations provider for PostgreSql (using NPGSql .Net driver)
</summary>
</member>
<member name="T:Migrator.Providers.ColumnPropertiesMapper">
<summary>
This is basically a just a helper base class
per-database implementors may want to override ColumnSql
</summary>
</member>
<member name="F:Migrator.Providers.ColumnPropertiesMapper.type">
<summary>The SQL type</summary>
</member>
<member name="F:Migrator.Providers.ColumnPropertiesMapper.name">
<summary>The name of the column</summary>
</member>
<member name="F:Migrator.Providers.ColumnPropertiesMapper.columnSql">
<summary>
the type of the column
</summary>
</member>
<member name="F:Migrator.Providers.ColumnPropertiesMapper.indexed">
<summary>
Sql if This column is Indexed
</summary>
</member>
<member name="F:Migrator.Providers.ColumnPropertiesMapper.defaultVal">
<summary>
Sql if this column has a default value
</summary>
</member>
<member name="P:Migrator.Providers.ColumnPropertiesMapper.ColumnSql">
<summary>
The sql for this column, override in database-specific implementation classes
</summary>
</member>
<member name="T:Migrator.Providers.TypeNames">
<summary>
This class maps a DbType to names.
</summary>
<remarks>
Associations may be marked with a capacity. Calling the <c>Get()</c>
method with a type and actual size n will return the associated
name with smallest capacity >= n, if available and an unmarked
default type otherwise.
Eg, setting
<code>
Names.Put(DbType, "TEXT" );
Names.Put(DbType, 255, "VARCHAR($l)" );
Names.Put(DbType, 65534, "LONGVARCHAR($l)" );
</code>
will give you back the following:
<code>
Names.Get(DbType) // --> "TEXT" (default)
Names.Get(DbType,100) // --> "VARCHAR(100)" (100 is in [0:255])
Names.Get(DbType,1000) // --> "LONGVARCHAR(1000)" (100 is in [256:65534])
Names.Get(DbType,100000) // --> "TEXT" (default)
</code>
On the other hand, simply putting
<code>
Names.Put(DbType, "VARCHAR($l)" );
</code>
would result in
<code>
Names.Get(DbType) // --> "VARCHAR($l)" (will cause trouble)
Names.Get(DbType,100) // --> "VARCHAR(100)"
Names.Get(DbType,1000) // --> "VARCHAR(1000)"
Names.Get(DbType,10000) // --> "VARCHAR(10000)"
</code>
</remarks>
</member>
<member name="M:Migrator.Providers.TypeNames.Get(System.Data.DbType)">
<summary>
Get default type name for specified type
</summary>
<param name="typecode">the type key</param>
<returns>the default type name associated with the specified key</returns>
</member>
<member name="M:Migrator.Providers.TypeNames.Get(System.Data.DbType,System.Int32,System.Int32,System.Int32)">
<summary>
Get the type name specified type and size
</summary>
<param name="typecode">the type key</param>
<param name="size">the SQL length </param>
<param name="scale">the SQL scale </param>
<param name="precision">the SQL precision </param>
<returns>
The associated name with smallest capacity >= size if available and the
default type name otherwise
</returns>
</member>
<member name="M:Migrator.Providers.TypeNames.Put(System.Data.DbType,System.Int32,System.String)">
<summary>
Set a type name for specified type key and capacity
</summary>
<param name="typecode">the type key</param>
<param name="capacity">the (maximum) type size/length</param>
<param name="value">The associated name</param>
</member>
<member name="M:Migrator.Providers.TypeNames.Put(System.Data.DbType,System.String)">
<summary>
</summary>
<param name="typecode"></param>
<param name="value"></param>
</member>
<member name="T:Migrator.Providers.Mysql.MySqlTransformationProvider">
<summary>
Summary description for MySqlTransformationProvider.
</summary>
</member>
</members>
</doc>

@ -5,6 +5,7 @@ using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
@ -18,122 +19,78 @@ namespace NzbDrone.Core.Test
public class DiskScanProviderTest : TestBase
{
[Test]
public void import_new_file()
public void import_new_file_should_succeed()
{
//Arrange
/////////////////////////////////////////
const string newFile = @"WEEDS.S03E01.DUAL.dvd.HELLYWOOD.avi";
//Constants
const string fileName = @"WEEDS.S03E01.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
const int seasonNumber = 3;
const int episodeNumner = 1;
const int size = 12345;
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew()
.With(c => c.SeriesId = fakeSeries.SeriesId)
.With(c => c.SeasonNumber = seasonNumber)
.Build();
var fakeEpisode = Builder<Episode>.CreateNew().Build();
//Mocks
var mocker = new AutoMoqer();
mocker.GetMock<DiskProvider>()
.Setup(e => e.GetSize(fileName)).Returns(12345).Verifiable();
var database = mocker.GetMock<IDatabase>(MockBehavior.Strict);
database.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>(), It.IsAny<object>())).Returns(false).Verifiable();
database.Setup(r => r.Insert(It.IsAny<EpisodeFile>())).Returns(1).Verifiable();
.Setup(e => e.GetSize(newFile)).Returns(12345).Verifiable();
mocker.GetMock<MediaFileProvider>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(e => e.GetEpisode(fakeSeries.SeriesId, seasonNumber, episodeNumner)).Returns(fakeEpisode);
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), false)).Returns(new List<Episode> { fakeEpisode });
//Act
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, newFile);
//Assert
Assert.IsNotNull(result);
mocker.GetMock<IDatabase>().Verify(r => r.Insert(result), Times.Once());
mocker.VerifyAllMocks();
VerifyFileImport(result, mocker, fakeEpisode, 12345);
result.SeasonNumber.Should().Be(fakeEpisode.SeasonNumber);
Assert.AreEqual(fakeEpisode.SeriesId, result.SeriesId);
Assert.AreEqual(QualityTypes.DVD, result.Quality);
Assert.AreEqual(Parser.NormalizePath(fileName), result.Path);
Assert.AreEqual(size, result.Size);
Assert.AreEqual(false, result.Proper);
Assert.AreNotEqual(new DateTime(), result.DateAdded);
}
[TestCase(QualityTypes.SDTV, true)]
[TestCase(QualityTypes.SDTV, false)]
[TestCase(QualityTypes.DVD, true)]
[TestCase(QualityTypes.HDTV, false)]
public void import_new_file_with_better_same_quality(QualityTypes currentFileQuality, bool currentFileProper)
public void import_new_file_with_better_same_quality_should_succeed(QualityTypes currentFileQuality, bool currentFileProper)
{
const string newFile = @"WEEDS.S03E01.DUAL.1080p.-HELLYWOOD.mkv";
const int seasonNumber = 3;
const int episodeNumner = 1;
const string newFile = @"WEEDS.S03E01.DUAL.1080p.HELLYWOOD.mkv";
const int size = 12345;
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew()
.With(c => c.SeriesId = fakeSeries.SeriesId)
.With(c => c.SeasonNumber = seasonNumber)
.With(e => e.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(g => g.Quality = (QualityTypes)currentFileQuality)
.And(g => g.Proper = currentFileProper).Build()
)
.Build();
).Build();
//Mocks
var mocker = new AutoMoqer();
mocker.GetMock<DiskProvider>()
.Setup(e => e.GetSize(newFile)).Returns(12345).Verifiable();
var database = mocker.GetMock<IDatabase>(MockBehavior.Strict);
database.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>(), It.IsAny<object>())).Returns(false).Verifiable();
database.Setup(r => r.Insert(It.IsAny<EpisodeFile>())).Returns(1).Verifiable();
mocker.GetMock<EpisodeProvider>()
.Setup(e => e.GetEpisode(fakeSeries.SeriesId, seasonNumber, episodeNumner)).Returns(fakeEpisode);
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), false)).Returns(new List<Episode> { fakeEpisode });
//Act
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, newFile);
//Assert
Assert.IsNotNull(result);
mocker.GetMock<IDatabase>().Verify(r => r.Insert(result), Times.Once());
mocker.VerifyAllMocks();
VerifyFileImport(result, mocker, fakeEpisode, size);
}
result.SeasonNumber.Should().Be(fakeEpisode.SeasonNumber);
Assert.AreEqual(fakeEpisode.SeriesId, result.SeriesId);
Assert.AreEqual(QualityTypes.HDTV, result.Quality);
Assert.AreEqual(Parser.NormalizePath(newFile), result.Path);
Assert.AreEqual(size, result.Size);
Assert.AreEqual(false, result.Proper);
Assert.AreNotEqual(new DateTime(), result.DateAdded);
}
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.SDTV.XviD.AC3.-HELLYWOOD.avi")]
public void import_new_file_skip_if_episode_has_same_or_better_quality(string fileName)
public void import_new_file_episode_has_same_or_better_quality_should_skip(string fileName)
{
const int seasonNumber = 3;
const int episodeNumner = 1;
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew()
.With(c => c.SeriesId = fakeSeries.SeriesId)
.With(c => c.SeasonNumber = seasonNumber)
.With(c => c.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(e => e.Quality = QualityTypes.Bluray720p).Build()
)
@ -145,116 +102,34 @@ namespace NzbDrone.Core.Test
mocker.GetMock<DiskProvider>()
.Setup(e => e.GetSize(fileName)).Returns(12345).Verifiable();
var database = mocker.GetMock<IDatabase>(MockBehavior.Strict);
database.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>(), It.IsAny<object>())).Returns(false).Verifiable();
mocker.GetMock<MediaFileProvider>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(e => e.GetEpisode(fakeSeries.SeriesId, seasonNumber, episodeNumner)).Returns(fakeEpisode);
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), false)).Returns(new List<Episode> { fakeEpisode });
//Act
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
//Assert
result.Should().BeNull();
mocker.GetMock<IDatabase>().Verify(r => r.Insert(result), Times.Never());
mocker.VerifyAllMocks();
VerifySkipImport(result, mocker);
}
[Test]
public void import_new_daily_file()
{
//Arrange
/////////////////////////////////////////
//Constants
const string fileName = @"2011.01.10 - Denis Leary - HD TV.mkv";
var airDate = new DateTime(2011, 01, 10);
const int size = 12345;
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew().With(c => c.SeriesId = fakeSeries.SeriesId).Build();
//Mocks
var mocker = new AutoMoqer();
var database = mocker.GetMock<IDatabase>(MockBehavior.Strict);
database.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>(), It.IsAny<object>())).Returns(false).Verifiable();
database.Setup(r => r.Insert(It.IsAny<EpisodeFile>())).Returns(1).Verifiable();
mocker.GetMock<EpisodeProvider>()
.Setup(e => e.GetEpisode(fakeSeries.SeriesId, airDate)).Returns(fakeEpisode).
Verifiable();
mocker.GetMock<DiskProvider>()
.Setup(e => e.GetSize(fileName)).Returns(size).Verifiable();
//Act
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
//Assert
Assert.IsNotNull(result);
mocker.GetMock<IDatabase>().VerifyAll();
mocker.GetMock<IDatabase>().Verify(r => r.Insert(result), Times.Once());
mocker.GetMock<EpisodeProvider>().VerifyAll();
mocker.GetMock<DiskProvider>().VerifyAll();
//Currently can't verify this since the list of episodes are loaded
//Dynamically by SubSonic
//Assert.AreEqual(fakeEpisode, result.EpisodeNumbers[0]);
Assert.AreEqual(fakeEpisode.SeriesId, result.SeriesId);
Assert.AreEqual(QualityTypes.HDTV, result.Quality);
Assert.AreEqual(Parser.NormalizePath(fileName), result.Path);
Assert.AreEqual(size, result.Size);
Assert.AreEqual(false, result.Proper);
Assert.AreNotEqual(new DateTime(), result.DateAdded);
}
[Test]
public void import_existing_season_file_should_skip()
public void import_unparsable_file_should_skip()
{
//Arrange
/////////////////////////////////////////
//Constants
const string fileName = @"WEEDS.S03E01.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
//Mocks
var mocker = new AutoMoqer();
mocker.GetMock<IDatabase>(MockBehavior.Strict)
.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>(), It.IsAny<object>())).Returns(true).Verifiable();
//Act
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
//Assert
mocker.VerifyAllMocks();
result.Should().BeNull();
}
[Test]
public void import_unparsable_file()
{
//Arrange
/////////////////////////////////////////
//Constants
const string fileName = @"WEEDS.avi";
const int size = 12345;
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
//Mocks
var mocker = new AutoMoqer();
mocker.GetMock<IDatabase>(MockBehavior.Strict)
.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>(), It.IsAny<object>())).Returns(false).Verifiable();
mocker.GetMock<MediaFileProvider>()
.Setup(p => p.Exists(It.IsAny<String>())).Returns(false);
mocker.GetMock<DiskProvider>()
.Setup(e => e.GetSize(fileName)).Returns(size).Verifiable();
@ -263,103 +138,81 @@ namespace NzbDrone.Core.Test
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
//Assert
mocker.VerifyAllMocks();
Assert.IsNull(result);
VerifySkipImport(result, mocker);
ExceptionVerification.ExcpectedWarns(1);
}
[Test]
public void import_sample_file()
public void import_sample_file_should_skip()
{
//Arrange
/////////////////////////////////////////
//Constants
const string fileName = @"2011.01.10 - Denis Leary - sample - HD TV.mkv";
var airDate = new DateTime(2011, 01, 10);
const int size = 12345;
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew().With(c => c.SeriesId = fakeSeries.SeriesId).Build();
//Mocks
var mocker = new AutoMoqer();
mocker.GetMock<IDatabase>()
.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>())).Returns(false).Verifiable();
mocker.GetMock<IDatabase>()
.Setup(r => r.Insert(It.IsAny<EpisodeFile>())).Returns(0).Verifiable();
mocker.GetMock<EpisodeProvider>()
.Setup(e => e.GetEpisode(fakeSeries.SeriesId, airDate)).Returns(fakeEpisode).
Verifiable();
mocker.GetMock<MediaFileProvider>()
.Setup(p => p.Exists(It.IsAny<String>())).Returns(false);
mocker.GetMock<DiskProvider>()
.Setup(e => e.GetSize(fileName)).Returns(size).Verifiable();
//Act
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
//Assert
Assert.IsNull(result);
VerifySkipImport(result, mocker);
}
[Test]
public void import_existing_file()
public void import_existing_file_should_skip()
{
const string fileName = "WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
var fakeSeries = Builder<Series>.CreateNew().Build();
var mocker = new AutoMoqer();
mocker.GetMock<IDatabase>(MockBehavior.Strict)
.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>(), It.IsAny<object>())).Returns(true).Verifiable();
mocker.GetMock<EpisodeProvider>(MockBehavior.Strict);
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<MediaFileProvider>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(true);
//Act
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
//Assert
result.Should().BeNull();
mocker.GetMock<IDatabase>().Verify(r => r.Insert(result), Times.Never());
mocker.VerifyAllMocks();
VerifySkipImport(result, mocker);
}
[Test]
public void import_file_with_no_episode_in_db_should_return_null()
public void import_file_with_no_episode_in_db_should_skip()
{
//Constants
const string fileName = "WEEDS.S03E01.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
const int seasonNumber = 3;
const int episodeNumner = 01;
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
//Mocks
var mocker = new AutoMoqer();
mocker.GetMock<IDatabase>(MockBehavior.Strict)
.Setup(r => r.Exists<EpisodeFile>(It.IsAny<string>(), It.IsAny<object>())).Returns(false).Verifiable();
mocker.GetMock<EpisodeProvider>(MockBehavior.Strict)
.Setup(e => e.GetEpisode(fakeSeries.SeriesId, seasonNumber, episodeNumner)).Returns<Episode>(null).
Verifiable();
mocker.GetMock<MediaFileProvider>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
mocker.GetMock<DiskProvider>(MockBehavior.Strict)
.Setup(e => e.GetSize(fileName)).Returns(90000000000);
mocker.GetMock<EpisodeProvider>()
.Setup(c => c.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), false))
.Returns(new List<Episode>());
//Act
var result = mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
//Assert
mocker.VerifyAllMocks();
result.Should().BeNull();
mocker.GetMock<IDatabase>().Verify(r => r.Insert(result), Times.Never());
ExceptionVerification.ExcpectedWarns(1);
VerifySkipImport(result, mocker);
}
[Test]
@ -384,5 +237,30 @@ namespace NzbDrone.Core.Test
mocker.VerifyAllMocks();
}
private static void VerifyFileImport(EpisodeFile result, AutoMoqer mocker, Episode fakeEpisode, int size)
{
mocker.VerifyAllMocks();
result.Should().NotBeNull();
result.SeriesId.Should().Be(fakeEpisode.SeriesId);
result.Size.Should().Be(size);
result.DateAdded.Should().HaveDay(DateTime.Now.Day);
mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Once());
//Get the count of episodes linked
var count = mocker.GetMock<EpisodeProvider>().Object.GetEpisodesByParseResult(null, false).Count;
mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.Is<Episode>(e => e.EpisodeFileId == result.EpisodeFileId)), Times.Exactly(count));
}
private static void VerifySkipImport(EpisodeFile result, AutoMoqer mocker)
{
mocker.VerifyAllMocks();
result.Should().BeNull();
mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Never());
mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.IsAny<Episode>()), Times.Never());
}
}
}

@ -21,13 +21,15 @@ namespace NzbDrone.Core.Test
{
var mocker = new AutoMoqer(MockBehavior.Strict);
var parseResult = Builder<EpisodeParseResult>.CreateNew()
.With(e => e.Episodes = Builder<Episode>.CreateListOfSize(2)
.With(c => c.Quality = new Quality(QualityTypes.DVD, false))
.Build();
var episodes = Builder<Episode>.CreateListOfSize(2)
.WhereTheFirst(1).Has(s => s.EpisodeId = 12)
.AndTheNext(1).Has(s => s.EpisodeId = 99)
.WhereAll().Has(s => s.SeriesId = 5)
.Build())
.With(c => c.Quality = new Quality(QualityTypes.DVD, false))
.Build();
.Build();
const string sabTitle = "My fake sab title";
mocker.GetMock<SabProvider>()
@ -47,6 +49,9 @@ namespace NzbDrone.Core.Test
mocker.GetMock<HistoryProvider>()
.Setup(s => s.Add(It.Is<History>(h => h.EpisodeId == 99 && h.SeriesId == 5)));
mocker.GetMock<EpisodeProvider>()
.Setup(c => c.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), false)).Returns(episodes);
mocker.Resolve<DownloadProvider>().DownloadReport(parseResult);
mocker.VerifyAllMocks();

@ -588,6 +588,22 @@ namespace NzbDrone.Core.Test
episodes.Should().NotBeEmpty();
}
[Test]
public void GetEpisode_by_Season_Episode_none_existing()
{
var mocker = new AutoMoqer();
var db = MockLib.GetEmptyDatabase();
mocker.SetConstant(db);
//Act
var episode = mocker.Resolve<EpisodeProvider>().GetEpisode(1, 1, 1);
//Assert
episode.Should().BeNull();
}
[Test]
public void GetEpisode_by_Season_Episode_with_EpisodeFile()
{
@ -644,6 +660,9 @@ namespace NzbDrone.Core.Test
episode.EpisodeFile.Should().BeNull();
}
[Test]
public void GetEpisode_by_AirDate_with_EpisodeFile()
{
@ -697,5 +716,8 @@ namespace NzbDrone.Core.Test
episode.Series.ShouldHave().AllProperties().EqualTo(fakeSeries);
episode.EpisodeFile.Should().BeNull();
}
}
}

@ -0,0 +1,190 @@
// ReSharper disable RedundantUsingDirective
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMoq;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
using NzbDrone.Core.Test.Framework;
using PetaPoco;
using TvdbLib.Data;
namespace NzbDrone.Core.Test
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class EpisodeProviderTest_GetEpisodesByParseResult : TestBase
{
[Test]
public void Single_GetSeason_Episode_Exists()
{
var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer();
mocker.SetConstant(db);
var fakeEpisode = Builder<Episode>.CreateNew()
.With(e => e.SeriesId = 1)
.With(e => e.SeasonNumber = 2)
.With(e => e.EpisodeNumber = 10)
.Build();
var fakeSeries = Builder<Series>.CreateNew().Build();
db.Insert(fakeEpisode);
db.Insert(fakeSeries);
var parseResult = new EpisodeParseResult
{
Series = fakeSeries,
SeasonNumber = 2,
EpisodeNumbers = new List<int> { 10 }
};
var ep = mocker.Resolve<EpisodeProvider>().GetEpisodesByParseResult(parseResult);
ep.Should().HaveCount(1);
ep.First().ShouldHave().AllPropertiesBut(e => e.Series);
}
[Test]
public void Single_GetSeason_Episode_Doesnt_exists_should_not_add()
{
var mocker = new AutoMoqer();
var db = MockLib.GetEmptyDatabase();
mocker.SetConstant(db);
var fakeSeries = Builder<Series>.CreateNew().Build();
var parseResult = new EpisodeParseResult
{
Series = fakeSeries,
SeasonNumber = 2,
EpisodeNumbers = new List<int> { 10 }
};
var ep = mocker.Resolve<EpisodeProvider>().GetEpisodesByParseResult(parseResult);
ep.Should().BeEmpty();
db.Fetch<Episode>().Should().HaveCount(0);
}
[Test]
public void Single_GetSeason_Episode_Doesnt_exists_should_add()
{
var mocker = new AutoMoqer();
var db = MockLib.GetEmptyDatabase();
mocker.SetConstant(db);
var fakeSeries = Builder<Series>.CreateNew().Build();
var parseResult = new EpisodeParseResult
{
Series = fakeSeries,
SeasonNumber = 2,
EpisodeNumbers = new List<int> { 10 }
};
var ep = mocker.Resolve<EpisodeProvider>().GetEpisodesByParseResult(parseResult, true);
ep.Should().HaveCount(1);
db.Fetch<Episode>().Should().HaveCount(1);
}
[Test]
public void Multi_GetSeason_Episode_Exists()
{
var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer();
mocker.SetConstant(db);
var fakeEpisode = Builder<Episode>.CreateNew()
.With(e => e.SeriesId = 1)
.With(e => e.SeasonNumber = 2)
.With(e => e.EpisodeNumber = 10)
.Build();
var fakeEpisode2 = Builder<Episode>.CreateNew()
.With(e => e.SeriesId = 1)
.With(e => e.SeasonNumber = 2)
.With(e => e.EpisodeNumber = 11)
.Build();
var fakeSeries = Builder<Series>.CreateNew().Build();
db.Insert(fakeEpisode);
db.Insert(fakeEpisode2);
db.Insert(fakeSeries);
var parseResult = new EpisodeParseResult
{
Series = fakeSeries,
SeasonNumber = 2,
EpisodeNumbers = new List<int> { 10, 11 }
};
var ep = mocker.Resolve<EpisodeProvider>().GetEpisodesByParseResult(parseResult);
ep.Should().HaveCount(2);
db.Fetch<Episode>().Should().HaveCount(2);
ep.First().ShouldHave().AllPropertiesBut(e => e.Series);
}
[Test]
public void Multi_GetSeason_Episode_Doesnt_exists_should_not_add()
{
var mocker = new AutoMoqer();
var db = MockLib.GetEmptyDatabase();
mocker.SetConstant(db);
var fakeSeries = Builder<Series>.CreateNew().Build();
var parseResult = new EpisodeParseResult
{
Series = fakeSeries,
SeasonNumber = 2,
EpisodeNumbers = new List<int> { 10, 11 }
};
var ep = mocker.Resolve<EpisodeProvider>().GetEpisodesByParseResult(parseResult);
ep.Should().BeEmpty();
db.Fetch<Episode>().Should().HaveCount(0);
}
[Test]
public void Multi_GetSeason_Episode_Doesnt_exists_should_add()
{
var mocker = new AutoMoqer();
var db = MockLib.GetEmptyDatabase();
mocker.SetConstant(db);
var fakeSeries = Builder<Series>.CreateNew().Build();
var parseResult = new EpisodeParseResult
{
Series = fakeSeries,
SeasonNumber = 2,
EpisodeNumbers = new List<int> { 10, 11 }
};
var ep = mocker.Resolve<EpisodeProvider>().GetEpisodesByParseResult(parseResult, true);
ep.Should().HaveCount(2);
db.Fetch<Episode>().Should().HaveCount(2);
}
}
}

@ -199,7 +199,7 @@ namespace NzbDrone.Core.Test
}
[TestCase(0)]
[TestCase(-1)]
[TestCase(-100)]
@ -245,7 +245,7 @@ namespace NzbDrone.Core.Test
.Returns(indexers);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsQualityNeeded(It.Is<EpisodeParseResult>(d => d.Series != null && d.Episodes.Count != 0))).Returns(false);
.Setup(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
mocker.GetMock<SceneMappingProvider>()
.Setup(s => s.GetSceneName(It.IsAny<int>())).Returns("");
@ -296,7 +296,7 @@ namespace NzbDrone.Core.Test
.Returns(indexers);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsQualityNeeded(It.Is<EpisodeParseResult>(d => d.Series != null && d.Episodes.Count != 0))).Returns(false);
.Setup(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
mocker.GetMock<SceneMappingProvider>()
.Setup(s => s.GetSceneName(71256)).Returns("The Daily Show");
@ -326,7 +326,7 @@ namespace NzbDrone.Core.Test
.With(c => c.SeasonNumber = 12)
.Build();
var mocker = new AutoMoqer(MockBehavior.Strict);
var mocker = new AutoMoqer();
mocker.GetMock<EpisodeProvider>()
.Setup(c => c.GetEpisode(episode.EpisodeId))
@ -342,7 +342,7 @@ namespace NzbDrone.Core.Test
.Throws(new Exception()).Verifiable();
var indexer3 = new Mock<IndexerBase>();
indexer2.Setup(c => c.FetchEpisode(episode.Series.Title, episode.SeasonNumber, episode.EpisodeNumber))
indexer3.Setup(c => c.FetchEpisode(episode.Series.Title, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(parseResults).Verifiable();
@ -353,7 +353,7 @@ namespace NzbDrone.Core.Test
.Returns(indexers);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsQualityNeeded(It.Is<EpisodeParseResult>(d => d.Series != null && d.Episodes.Count != 0))).Returns(false);;
.Setup(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
mocker.GetMock<SceneMappingProvider>()
.Setup(s => s.GetSceneName(It.IsAny<int>())).Returns("");

@ -110,9 +110,9 @@ namespace NzbDrone.Core.Test
mocker.VerifyAllMocks();
}
[Test]
public void IsMonitored_dailyshow_should_do_daily_lookup()
public void IsMonitored_should_return_true()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
@ -121,23 +121,47 @@ namespace NzbDrone.Core.Test
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns<Episode>(null);
.Setup(p => p.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), true))
.Returns(new List<Episode> { episode });
parseResultSingle.Series.Should().BeNull();
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultSingle);
//Assert
result.Should().BeTrue();
parseResultSingle.Series.Should().Be(series);
mocker.VerifyAllMocks();
}
[Test]
public void IsMonitored_ignored_single_episode_should_return_false()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.AirDate))
.Returns(episode);
.Setup(p => p.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), true))
.Returns(new List<Episode> { episode });
episode.Ignored = true;
parseResultSingle.Series.Should().BeNull();
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultSingle);
//Assert
Assert.IsTrue(result);
Assert.AreSame(series, parseResultSingle.Series);
result.Should().BeFalse();
parseResultSingle.Series.Should().Be(series);
mocker.VerifyAllMocks();
}
[Test]
public void none_db_episode_should_be_added()
public void IsMonitored_multi_some_episodes_ignored_should_return_true()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
@ -146,25 +170,75 @@ namespace NzbDrone.Core.Test
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns<Episode>(null);
.Setup(p => p.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), true))
.Returns(new List<Episode> { episode, episode2 });
episode.Ignored = true;
episode2.Ignored = false;
parseResultMulti.Series.Should().BeNull();
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultMulti);
//Assert
result.Should().BeTrue();
parseResultMulti.Series.Should().Be(series);
mocker.VerifyAllMocks();
}
[Test]
public void IsMonitored_multi_all_episodes_ignored_should_return_false()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.AirDate))
.Returns<Episode>(null);
.Setup(p => p.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), true))
.Returns(new List<Episode> { episode, episode2 });
episode.Ignored = true;
episode2.Ignored = true;
parseResultSingle.Series.Should().BeNull();
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultMulti);
//Assert
result.Should().BeFalse();
parseResultMulti.Series.Should().Be(series);
mocker.VerifyAllMocks();
}
[Test]
public void IsMonitored_multi_no_episodes_ignored_should_return_true()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.AddEpisode(It.IsAny<Episode>()));
.Setup(p => p.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), true))
.Returns(new List<Episode> { episode, episode2 });
//Act
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultSingle);
episode.Ignored = false;
episode2.Ignored = false;
parseResultSingle.Series.Should().BeNull();
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultMulti);
//Assert
Assert.IsTrue(result);
Assert.AreSame(series, parseResultSingle.Series);
parseResultSingle.Episodes.Should().HaveCount(1);
Assert.AreEqual("TBD", parseResultSingle.Episodes[0].Title);
result.Should().BeTrue();
parseResultMulti.Series.Should().Be(series);
mocker.VerifyAllMocks();
}
}
}

@ -37,7 +37,6 @@ namespace NzbDrone.Core.Test
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date,
Episodes = new List<Episode>()
};
parseResultSingle = new EpisodeParseResult
@ -48,7 +47,6 @@ namespace NzbDrone.Core.Test
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date,
Episodes = new List<Episode>()
};
episodeFile = Builder<EpisodeFile>.CreateNew().With(c => c.Quality = QualityTypes.DVD).Build();
@ -99,9 +97,9 @@ namespace NzbDrone.Core.Test
parseResultMulti.Series = series;
parseResultSingle.Series = series;
parseResultSingle.Episodes.Add(episode);
parseResultMulti.Episodes.Add(episode);
parseResultMulti.Episodes.Add(episode2);
/* parseResultSingle.Episodes.Add(episode);
parseResultMulti.Episodes.Add(episode);
parseResultMulti.Episodes.Add(episode2);*/
base.Setup();
@ -129,9 +127,15 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultMulti.Series.QualityProfile = hdProfile;
parseResultMulti.Episodes[0].EpisodeFile.Quality = QualityTypes.Bluray720p;
parseResultMulti.Quality = new Quality(QualityTypes.HDTV, true);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisodesByParseResult(parseResultMulti, true))
.Returns(new List<Episode> { episode, episode2 });
episode.EpisodeFile.Quality = QualityTypes.Bluray720p;
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultMulti);
@ -147,13 +151,18 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series.QualityProfile = sdProfile;
parseResultSingle.Episodes[0].EpisodeFile.Quality = QualityTypes.SDTV;
parseResultSingle.Quality.QualityType = QualityTypes.DVD;
mocker.GetMock<HistoryProvider>()
.Setup(p => p.GetBestQualityInHistory(episode.EpisodeId))
.Returns(new Quality(QualityTypes.DVD, true));
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisodesByParseResult(parseResultSingle, true))
.Returns(new List<Episode> { episode });
episode.EpisodeFile.Quality = QualityTypes.SDTV;
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultSingle);
@ -168,13 +177,18 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series.QualityProfile = sdProfile;
parseResultSingle.Episodes[0].EpisodeFile.Quality = QualityTypes.SDTV;
parseResultSingle.Quality.QualityType = QualityTypes.DVD;
mocker.GetMock<HistoryProvider>()
.Setup(p => p.GetBestQualityInHistory(episode.EpisodeId))
.Returns(new Quality(QualityTypes.SDTV, true));
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisodesByParseResult(parseResultSingle, true))
.Returns(new List<Episode> { episode });
episode.EpisodeFile.Quality = QualityTypes.SDTV;
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultSingle);
@ -189,13 +203,18 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series.QualityProfile = sdProfile;
parseResultSingle.Episodes[0].EpisodeFile.Quality = QualityTypes.SDTV;
parseResultSingle.Quality.QualityType = QualityTypes.DVD;
mocker.GetMock<HistoryProvider>()
.Setup(p => p.GetBestQualityInHistory(episode.EpisodeId))
.Returns<Quality>(null);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisodesByParseResult(parseResultSingle, true))
.Returns(new List<Episode> { episode });
episode.EpisodeFile.Quality = QualityTypes.SDTV;
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultSingle);

@ -85,6 +85,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="EpisodeProviderTest_GetEpisodesByParseResult.cs" />
<Compile Include="DiskScanProviderTest.cs" />
<Compile Include="FluentTest.cs" />
<Compile Include="LogProviderTest.cs" />
@ -128,18 +129,6 @@
<Compile Include="TvDbProviderTest.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Migrator.net\Migrator.Framework\Migrator.Framework.csproj">
<Project>{5270F048-E580-486C-B14C-E5B9F6E539D4}</Project>
<Name>Migrator.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\Migrator.net\Migrator.Providers\Migrator.Providers.csproj">
<Project>{D58C68E4-D789-40F7-9078-C9F587D4363C}</Project>
<Name>Migrator.Providers</Name>
</ProjectReference>
<ProjectReference Include="..\Migrator.net\Migrator\Migrator.csproj">
<Project>{1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}</Project>
<Name>Migrator</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
<Project>{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}</Project>
<Name>NzbDrone.Core</Name>

@ -259,7 +259,7 @@ namespace NzbDrone.Core.Test
mocker.Resolve<SabProvider>().IsInQueue(String.Empty);
}
[Test]
[TestCase(1, new[] { 2 }, "My Episode Title", QualityTypes.DVD, false, "My Series Name - 1x2 - My Episode Title [DVD]")]
[TestCase(1, new[] { 2 }, "My Episode Title", QualityTypes.DVD, true, "My Series Name - 1x2 - My Episode Title [DVD] [Proper]")]
[TestCase(1, new[] { 2 }, "", QualityTypes.DVD, true, "My Series Name - 1x2 - [DVD] [Proper]")]
@ -274,10 +274,6 @@ namespace NzbDrone.Core.Test
.With(c => c.Path = @"d:\tv shows\My Series Name")
.Build();
var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = title)
.Build();
var parsResult = new EpisodeParseResult()
{
AirDate = DateTime.Now,
@ -285,7 +281,7 @@ namespace NzbDrone.Core.Test
Quality = new Quality(quality, proper),
SeasonNumber = seasons,
Series = series,
Episodes = new List<Episode>() { episode }
EpisodeTitle = title
};
//Act

@ -7,13 +7,15 @@ namespace NzbDrone.Core.Model
public class EpisodeParseResult
{
internal string CleanTitle { get; set; }
public string EpisodeTitle { get; set; }
internal int SeasonNumber { get; set; }
internal List<int> EpisodeNumbers { get; set; }
internal DateTime AirDate { get; set; }
public Quality Quality { get; set; }
public LanguageType Language { get; set; }
@ -24,8 +26,6 @@ namespace NzbDrone.Core.Model
public Series Series { get; set; }
public IList<Episode> Episodes { get; set; }
public String Indexer { get; set; }
public override string ToString()
@ -34,7 +34,7 @@ namespace NzbDrone.Core.Model
return string.Format("{0} - {1} {2}", CleanTitle, AirDate.ToShortDateString(), Quality);
return string.Format("{0} - S{1:00}E{2} {3}", CleanTitle, SeasonNumber,
String.Join("-", EpisodeNumbers),Quality);
String.Join("-", EpisodeNumbers), Quality);
}
}

@ -126,6 +126,18 @@
<HintPath>..\Libraries\Exceptioneer.WindowsFormsClient.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Migrator, Version=0.9.1.26254, Culture=neutral, PublicKeyToken=3b3586e9632ecfce, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libraries\Migrator.NET\Migrator.dll</HintPath>
</Reference>
<Reference Include="Migrator.Framework, Version=0.0.0.0, Culture=neutral, PublicKeyToken=3b3586e9632ecfce, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libraries\Migrator.NET\Migrator.Framework.dll</HintPath>
</Reference>
<Reference Include="Migrator.Providers, Version=0.0.0.0, Culture=neutral, PublicKeyToken=3b3586e9632ecfce, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libraries\Migrator.NET\Migrator.Providers.dll</HintPath>
</Reference>
<Reference Include="MvcMiniProfiler, Version=2.1.4183.14740, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MiniProfiler.1.3\lib\MvcMiniProfiler.dll</HintPath>
@ -279,20 +291,6 @@
<None Include="packages.config" />
<None Include="Properties\AnalysisRules.ruleset" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Migrator.net\Migrator.Framework\Migrator.Framework.csproj">
<Project>{5270F048-E580-486C-B14C-E5B9F6E539D4}</Project>
<Name>Migrator.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\Migrator.net\Migrator.Providers\Migrator.Providers.csproj">
<Project>{D58C68E4-D789-40F7-9078-C9F587D4363C}</Project>
<Name>Migrator.Providers</Name>
</ProjectReference>
<ProjectReference Include="..\Migrator.net\Migrator\Migrator.csproj">
<Project>{1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}</Project>
<Name>Migrator</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>

@ -43,7 +43,7 @@ namespace NzbDrone.Core.Providers.Core
File.Delete(path);
}
public virtual void RenameFile(string sourcePath, string destinationPath)
public virtual void MoveFile(string sourcePath, string destinationPath)
{
File.Move(sourcePath, destinationPath);
}

@ -14,7 +14,6 @@ namespace NzbDrone.Core.Providers
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly string[] MediaExtentions = new[] { ".mkv", ".avi", ".wmv", ".mp4" };
private readonly IDatabase _database;
private readonly DiskProvider _diskProvider;
private readonly EpisodeProvider _episodeProvider;
private readonly MediaFileProvider _mediaFileProvider;
@ -22,14 +21,12 @@ namespace NzbDrone.Core.Providers
[Inject]
public DiskScanProvider(DiskProvider diskProvider, EpisodeProvider episodeProvider,
SeriesProvider seriesProvider, MediaFileProvider mediaFileProvider,
IDatabase database)
SeriesProvider seriesProvider, MediaFileProvider mediaFileProvider)
{
_diskProvider = diskProvider;
_episodeProvider = episodeProvider;
_seriesProvider = seriesProvider;
_mediaFileProvider = mediaFileProvider;
_database = database;
}
@ -86,7 +83,7 @@ namespace NzbDrone.Core.Providers
{
Logger.Trace("Importing file to database [{0}]", filePath);
if (_database.Exists<EpisodeFile>("WHERE Path =@0", Parser.NormalizePath(filePath)))
if (_mediaFileProvider.Exists(filePath))
{
Logger.Trace("[{0}] already exists in the database. skipping.", filePath);
return null;
@ -107,46 +104,15 @@ namespace NzbDrone.Core.Providers
return null;
parseResult.CleanTitle = series.Title; //replaces the nasty path as title to help with logging
parseResult.Series = series;
//Stores the list of episodes to add to the EpisodeFile
var episodes = new List<Episode>();
var episodes = _episodeProvider.GetEpisodesByParseResult(parseResult);
//Check for daily shows
if (parseResult.EpisodeNumbers == null)
{
var episode = _episodeProvider.GetEpisode(series.SeriesId, parseResult.AirDate.Date);
if (episode != null)
{
episodes.Add(episode);
}
else
{
Logger.Warn("Unable to find [{0}] in the database.[{1}]", parseResult, filePath);
}
}
else
{
foreach (var episodeNumber in parseResult.EpisodeNumbers)
{
var episode = _episodeProvider.GetEpisode(series.SeriesId, parseResult.SeasonNumber,
episodeNumber);
if (episode != null)
{
episodes.Add(episode);
}
else
{
Logger.Warn("Unable to find [{0}] in the database.[{1}]", parseResult, filePath);
}
}
}
//Return null if no Episodes exist in the DB for the parsed episodes from file
if (episodes.Count <= 0)
{
Logger.Debug("Can't find any matching episodes in the database. skipping");
return null;
}
if (episodes.Any(e => e.EpisodeFile != null && e.EpisodeFile.QualityWrapper > parseResult.Quality))
{
@ -162,24 +128,22 @@ namespace NzbDrone.Core.Providers
episodeFile.Quality = parseResult.Quality.QualityType;
episodeFile.Proper = parseResult.Quality.Proper;
episodeFile.SeasonNumber = parseResult.SeasonNumber;
int fileId = Convert.ToInt32(_database.Insert(episodeFile));
var fileId = _mediaFileProvider.Add(episodeFile);
//This is for logging + updating the episodes that are linked to this EpisodeFile
string episodeList = String.Empty;
//Link file to all episodes
foreach (var ep in episodes)
{
ep.EpisodeFileId = fileId;
_episodeProvider.UpdateEpisode(ep);
episodeList += String.Format(", {0}", ep.EpisodeId).Trim(' ', ',');
Logger.Trace("Linking file {0} to {1}", filePath, ep);
}
Logger.Trace("File {0}:{1} attached to episode(s): '{2}'", episodeFile.EpisodeFileId, filePath,
episodeList);
return episodeFile;
}
public virtual bool RenameEpisodeFile(EpisodeFile episodeFile)
public virtual bool MoveEpisodeFile(EpisodeFile episodeFile)
{
if (episodeFile == null)
throw new ArgumentNullException("episodeFile");
@ -191,7 +155,7 @@ namespace NzbDrone.Core.Providers
//Do the rename
Logger.Trace("Attempting to rename {0} to {1}", episodeFile.Path, newFile.FullName);
_diskProvider.RenameFile(episodeFile.Path, newFile.FullName);
_diskProvider.MoveFile(episodeFile.Path, newFile.FullName);
//Update the filename in the DB
episodeFile.Path = newFile.FullName;
@ -221,7 +185,7 @@ namespace NzbDrone.Core.Providers
}
//Delete it from the DB
_database.Delete<EpisodeFile>(episodeFile.EpisodeFileId);
_mediaFileProvider.Delete(episodeFile.EpisodeFileId);
}
}
}

@ -39,7 +39,7 @@ namespace NzbDrone.Core.Providers
if (addSuccess)
{
foreach (var episode in parseResult.Episodes)
foreach (var episode in _episodeProvider.GetEpisodesByParseResult(parseResult))
{
var history = new History();
history.Date = DateTime.Now;

@ -35,7 +35,7 @@ namespace NzbDrone.Core.Providers
public virtual Episode GetEpisode(long id)
{
var episode = AttachSeries(_database.Fetch<Episode, EpisodeFile>(@"SELECT * FROM Episodes
var episode = AttachSeries(_database.Fetch<Episode, EpisodeFile>(@"SELECT * FROM Episodes
LEFT JOIN EpisodeFiles ON Episodes.EpisodeFileId = EpisodeFiles.EpisodeFileId
WHERE EpisodeId = @0", id).Single());
@ -86,7 +86,7 @@ namespace NzbDrone.Core.Providers
if (episode.EpisodeFileId == 0)
episode.EpisodeFile = null;
}
return episodes;
}
@ -105,33 +105,46 @@ namespace NzbDrone.Core.Providers
return episodes;
}
public virtual List<Episode> GetEpisodes(EpisodeParseResult parseResult)
{
if (parseResult.Series == null)
{
Logger.Debug("Episode Parse Result is Invalid, skipping");
return new List<Episode>();
}
var episodes = new List<Episode>();
public virtual IList<Episode> GetEpisodesByParseResult(EpisodeParseResult parseResult, Boolean autoAddNew = false)
{
var result = new List<Episode>();
foreach (var ep in parseResult.EpisodeNumbers)
foreach (var episodeNumber in parseResult.EpisodeNumbers)
{
var episode = GetEpisode(parseResult.Series.SeriesId, parseResult.SeasonNumber, ep);
if (episode == null)
return new List<Episode>();
episodes.Add(episode);
}
var episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber);
if (episodeInfo == null)
{
episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.AirDate);
}
//if still null we should add the temp episode
if (episodeInfo == null && autoAddNew)
{
Logger.Debug("Episode {0} doesn't exist in db. adding it now.", parseResult);
episodeInfo = new Episode
{
SeriesId = parseResult.Series.SeriesId,
AirDate = DateTime.Now.Date,
EpisodeNumber = episodeNumber,
SeasonNumber = parseResult.SeasonNumber,
Title = "TBD",
Overview = String.Empty,
};
AddEpisode(episodeInfo);
}
foreach (var episode in episodes)
{
if (episode.EpisodeFileId == 0)
episode.EpisodeFile = null;
if (episodeInfo != null)
{
result.Add(episodeInfo);
}
else
{
Logger.Debug("Unable to file {0}-S{1:00}E{2:00}", parseResult.Series.Title, parseResult.SeasonNumber, episodeNumber);
}
}
return episodes;
return result;
}
public virtual IList<Episode> EpisodesWithoutFiles(bool includeSpecials)

@ -14,12 +14,13 @@ namespace NzbDrone.Core.Providers
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly IDatabase _database;
private IList<IndexerBase> _indexers = new List<IndexerBase>();
private IEnumerable<IndexerBase> _indexers;
[Inject]
public IndexerProvider(IDatabase database)
public IndexerProvider(IDatabase database, IEnumerable<IndexerBase> indexers)
{
_database = database;
_indexers = indexers;
}
public IndexerProvider()

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Ninject;
using NLog;
using NzbDrone.Core.Model;
@ -41,7 +42,6 @@ namespace NzbDrone.Core.Providers
}
parseResult.Series = series;
parseResult.Episodes = new List<Episode>();
if (!series.Monitored)
{
@ -49,34 +49,16 @@ namespace NzbDrone.Core.Providers
return false;
}
foreach (var episodeNumber in parseResult.EpisodeNumbers)
{
var episodeInfo = _episodeProvider.GetEpisode(series.SeriesId, parseResult.SeasonNumber, episodeNumber);
if (episodeInfo == null)
{
episodeInfo = _episodeProvider.GetEpisode(series.SeriesId, parseResult.AirDate);
}
//if still null we should add the temp episode
if (episodeInfo == null)
{
Logger.Debug("Episode {0} doesn't exist in db. adding it now.", parseResult);
episodeInfo = new Episode
{
SeriesId = series.SeriesId,
AirDate = DateTime.Now.Date,
EpisodeNumber = episodeNumber,
SeasonNumber = parseResult.SeasonNumber,
Title = "TBD",
Overview = String.Empty,
};
_episodeProvider.AddEpisode(episodeInfo);
}
var episodes = _episodeProvider.GetEpisodesByParseResult(parseResult, true);
parseResult.Episodes.Add(episodeInfo);
//return monitored if any of the episodes are monitored
if (episodes.Any(episode => !episode.Ignored))
{
return true;
}
return true;
Logger.Debug("All episodes are ignored. skipping.");
return false;
}
/// <summary>
@ -97,7 +79,7 @@ namespace NzbDrone.Core.Providers
var cutoff = parsedReport.Series.QualityProfile.Cutoff;
foreach (var episode in parsedReport.Episodes)
foreach (var episode in _episodeProvider.GetEpisodesByParseResult(parsedReport, true))
{
//Checking File
var file = episode.EpisodeFile;

@ -68,11 +68,11 @@ namespace NzbDrone.Core.Providers.Jobs
{
try
{
notification.CurrentMessage = String.Format("Searching for {0} in {1}", episode, indexer.Name);
//notification.CurrentMessage = String.Format("Searching for {0} in {1}", episode, indexer.Name);
//TODO:Add support for daily episodes, maybe search using both date and season/episode?
var indexerResults = indexer.FetchEpisode(title, episode.SeasonNumber, episode.EpisodeNumber);
reports.AddRange(indexerResults);
}
catch (Exception e)
@ -84,10 +84,12 @@ namespace NzbDrone.Core.Providers.Jobs
Logger.Debug("Finished searching all indexers. Total {0}", reports.Count);
notification.CurrentMessage = "Processing search results";
//TODO:fix this so when search returns more than one episode
//TODO:-its populated with more than the original episode.
reports.ForEach(c =>
{
c.Series = series;
c.Episodes = new List<Episode> { episode };
});
ProcessResults(notification, episode, reports);

@ -83,7 +83,7 @@ namespace NzbDrone.Core.Providers.Jobs
}
var importedFiles = _diskScanProvider.Scan(series, subfolder);
importedFiles.ForEach(file => _diskScanProvider.RenameEpisodeFile(file));
importedFiles.ForEach(file => _diskScanProvider.MoveEpisodeFile(file));
}
Logger.Debug("New Download Scan Job completed successfully");

@ -33,7 +33,7 @@ namespace NzbDrone.Core.Providers.Jobs
public void Start(ProgressNotification notification, int targetId)
{
var episode = _mediaFileProvider.GetEpisodeFile(targetId);
_diskScanProvider.RenameEpisodeFile(episode);
_diskScanProvider.MoveEpisodeFile(episode);
}
}
}

@ -31,11 +31,28 @@ namespace NzbDrone.Core.Providers
{
}
public virtual int Add(EpisodeFile episodeFile)
{
return Convert.ToInt32(_database.Insert(episodeFile));
}
public virtual void Update(EpisodeFile episodeFile)
{
_database.Update(episodeFile);
}
public virtual void Delete(int episodeFileId)
{
_database.Delete(episodeFileId);
}
public virtual bool Exists(string path)
{
return _database.Exists<EpisodeFile>("WHERE Path =@0", Parser.NormalizePath(path));
}
public virtual EpisodeFile GetEpisodeFile(int episodeFileId)
{
return _database.Single<EpisodeFile>(episodeFileId);

@ -126,7 +126,7 @@ namespace NzbDrone.Core.Providers
var epNumberString = String.Join("-", episodeString);
var result = String.Format("{0} - {1} - {2} [{3}]", new DirectoryInfo(parseResult.Series.Path).Name, epNumberString, parseResult.Episodes.FirstOrDefault().Title, parseResult.Quality.QualityType);
var result = String.Format("{0} - {1} - {2} [{3}]", new DirectoryInfo(parseResult.Series.Path).Name, epNumberString, parseResult.EpisodeTitle, parseResult.Quality.QualityType);
if (parseResult.Quality.Proper)
{

@ -135,10 +135,11 @@ namespace NzbDrone.Core.Providers
return series;
}
//This will catch InvalidOperationExceptions that may be thrown for GetSeries due to the series being in SceneMapping, but not in the users Database
catch (InvalidOperationException ex)
catch (InvalidOperationException)
{
Logger.DebugException(ex.Message, ex);
//This will catch InvalidOperationExceptions(Sequence contains no element)
//that may be thrown for GetSeries due to the series being in SceneMapping, but not in the users Database
return null;
}
}

Loading…
Cancel
Save