diff --git a/NzbDrone.Core/Datastore/Connection.cs b/NzbDrone.Core/Datastore/Connection.cs
index e8eedf736..1c45779db 100644
--- a/NzbDrone.Core/Datastore/Connection.cs
+++ b/NzbDrone.Core/Datastore/Connection.cs
@@ -1,4 +1,6 @@
 using System;
+using System.Data;
+using System.Data.Common;
 using System.Data.SQLite;
 using System.IO;
 using MvcMiniProfiler.Data;
@@ -58,9 +60,12 @@ namespace NzbDrone.Core.Datastore
         public static IDatabase GetPetaPocoDb(string connectionString)
         {
             var profileConnection = ProfiledDbConnection.Get(new SQLiteConnection(connectionString));
-            PetaPoco.Database.Mapper = new CustomeMapper();
-            var db = new PetaPoco.Database(profileConnection);
-            db.OpenSharedConnection();
+
+            Database.Mapper = new CustomeMapper();
+            var db = new Database(profileConnection);
+
+            if (profileConnection.State != ConnectionState.Open)
+                profileConnection.Open();
 
             return db;
         }
diff --git a/NzbDrone.Core/Datastore/PetaPoco/PetaPoco.cs b/NzbDrone.Core/Datastore/PetaPoco/PetaPoco.cs
index 8abc47cc4..415faaa9c 100644
--- a/NzbDrone.Core/Datastore/PetaPoco/PetaPoco.cs
+++ b/NzbDrone.Core/Datastore/PetaPoco/PetaPoco.cs
@@ -1,5 +1,5 @@
 /* PetaPoco v4.0.2 - A Tiny ORMish thing for your POCO's.
- * Copyright © 2011 Topten Software.  All Rights Reserved.
+ * Copyright © 2011 Topten Software.  All Rights Reserved.
  * 
  * Apache License 2.0 - http://www.toptensoftware.com/petapoco/license
  * 
@@ -24,7 +24,6 @@ using System.Reflection.Emit;
 using System.Linq.Expressions;
 
 
-// ReSharper disable
 namespace PetaPoco
 {
     // Poco's marked [Explicit] require all column properties to be marked
@@ -182,6 +181,8 @@ namespace PetaPoco
         List<T> Fetch<T>(long page, long itemsPerPage, Sql sql);
         Page<T> Page<T>(long page, long itemsPerPage, string sql, params object[] args);
         Page<T> Page<T>(long page, long itemsPerPage, Sql sql);
+        List<T> SkipTake<T>(long skip, long take, string sql, params object[] args);
+        List<T> SkipTake<T>(long skip, long take, Sql sql);
         List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args);
         List<TRet> Fetch<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args);
         List<TRet> Fetch<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args);
@@ -221,13 +222,14 @@ namespace PetaPoco
         T FirstOrDefault<T>(Sql sql);
         bool Exists<T>(object primaryKey);
         int OneTimeCommandTimeout { get; set; }
+        bool Exists<T>(string sql, params object[] args);
     }
 
     public interface IDatabase : IDatabaseQuery
     {
         void Dispose();
         IDbConnection Connection { get; }
-        Transaction GetTransaction();
+        ITransaction GetTransaction();
         void BeginTransaction();
         void AbortTransaction();
         void CompleteTransaction();
@@ -240,6 +242,7 @@ namespace PetaPoco
         int Update(object poco, object primaryKeyValue);
         int Update<T>(string sql, params object[] args);
         int Update<T>(Sql sql);
+        void UpdateMany<T>(IEnumerable<T> pocoList);
         int Delete(string tableName, string primaryKeyName, object poco);
         int Delete(string tableName, string primaryKeyName, object poco, object primaryKeyValue);
         int Delete(object poco);
@@ -248,6 +251,8 @@ namespace PetaPoco
         int Delete<T>(object pocoOrPrimaryKey);
         void Save(string tableName, string primaryKeyName, object poco);
         void Save(object poco);
+        void InsertMany<T>(IEnumerable<T> pocoList);
+        void SaveMany<T>(IEnumerable<T> pocoList);
     }
 
     // Database class ... this is where most of the action happens
@@ -353,19 +358,17 @@ namespace PetaPoco
             {
                 _sharedConnection = _factory.CreateConnection();
                 _sharedConnection.ConnectionString = _connectionString;
+                _sharedConnection.Open();
 
                 if (KeepConnectionAlive)
                     _sharedConnectionDepth++;		// Make sure you call Dispose
             }
-
-            if (_sharedConnection.State != ConnectionState.Open)
-                _sharedConnection.Open();
-
             _sharedConnectionDepth++;
-
         }
 
-        // Close a previously opened connection
+        /// <summary>
+        /// Close a previously opened connection
+        /// </summary>
         public void CloseSharedConnection()
         {
             if (_sharedConnectionDepth > 0)
@@ -386,7 +389,7 @@ namespace PetaPoco
         }
 
         // Helper to create a transaction scope
-        public Transaction GetTransaction()
+        public ITransaction GetTransaction()
         {
             return new Transaction(this);
         }
@@ -750,7 +753,7 @@ namespace PetaPoco
 
         static Regex rxColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?<!,\s+)\bFROM\b", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
         static Regex rxOrderBy = new Regex(@"\bORDER\s+BY\s+(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
-        public static bool SplitSqlForPaging(string sql, out string sqlCount, out string sqlSelectRemoved, out string sqlOrderBy)
+        public static bool SplitSqlForPaging<T>(string sql, out string sqlCount, out string sqlSelectRemoved, out string sqlOrderBy)
         {
             sqlSelectRemoved = null;
             sqlCount = null;
@@ -766,26 +769,32 @@ namespace PetaPoco
             sqlCount = sql.Substring(0, g.Index) + "COUNT(*) " + sql.Substring(g.Index + g.Length);
             sqlSelectRemoved = sql.Substring(g.Index);
 
-            // Look for an "ORDER BY <whatever>" clause
+            // Look for an "ORDER BY <whatever>" clause or primarykey from pocodata
+            var data = PocoData.ForType(typeof(T));
+
             m = rxOrderBy.Match(sqlCount);
-            if (!m.Success)
+            if (!m.Success
+                && (string.IsNullOrEmpty(data.TableInfo.PrimaryKey) ||
+                    (!data.TableInfo.PrimaryKey.Split(',').All(x => data.Columns.Values.Any(y => y.ColumnName.Equals(x, StringComparison.OrdinalIgnoreCase))))))
+            {
                 return false;
+            }
 
             g = m.Groups[0];
-            sqlOrderBy = g.ToString();
+            sqlOrderBy = m.Success ? g.ToString() : "ORDER BY " + data.TableInfo.PrimaryKey;
             sqlCount = sqlCount.Substring(0, g.Index) + sqlCount.Substring(g.Index + g.Length);
 
             return true;
         }
 
-        public void BuildPageQueries<T>(long page, long itemsPerPage, string sql, ref object[] args, out string sqlCount, out string sqlPage)
+        private void BuildPageQueries<T>(long skip, long take, string sql, ref object[] args, out string sqlCount, out string sqlPage)
         {
             // Add auto select clause
             sql = AddSelectClause<T>(sql);
 
             // Split the SQL into the bits we need
             string sqlSelectRemoved, sqlOrderBy;
-            if (!SplitSqlForPaging(sql, out sqlCount, out sqlSelectRemoved, out sqlOrderBy))
+            if (!SplitSqlForPaging<T>(sql, out sqlCount, out sqlSelectRemoved, out sqlOrderBy))
                 throw new Exception("Unable to parse SQL statement for paged query");
             if (_dbType == DBType.Oracle && sqlSelectRemoved.StartsWith("*"))
                 throw new Exception("Query must alias '*' when performing a paged query.\neg. select t.* from table t order by t.id");
@@ -793,20 +802,21 @@ namespace PetaPoco
             // Build the SQL for the actual final result
             if (_dbType == DBType.SqlServer || _dbType == DBType.Oracle)
             {
+                var fromIndex = sqlSelectRemoved.IndexOf("from", StringComparison.OrdinalIgnoreCase);
                 sqlSelectRemoved = rxOrderBy.Replace(sqlSelectRemoved, "");
-                sqlPage = string.Format("SELECT * FROM (SELECT ROW_NUMBER() OVER ({0}) peta_rn, {1}) peta_paged WHERE peta_rn>@{2} AND peta_rn<=@{3}",
-                                        sqlOrderBy, sqlSelectRemoved, args.Length, args.Length + 1);
-                args = args.Concat(new object[] { (page - 1) * itemsPerPage, page * itemsPerPage }).ToArray();
+                sqlPage = string.Format("SELECT * FROM (SELECT {2}, ROW_NUMBER() OVER ({0}) peta_rn {1}) peta_paged WHERE peta_rn>@{3} AND peta_rn<=@{4}",
+                                        sqlOrderBy, sqlSelectRemoved.Substring(fromIndex), sqlSelectRemoved.Substring(0, fromIndex - 1), args.Length, args.Length + 1);
+                args = args.Concat(new object[] { skip, skip + take }).ToArray();
             }
             else if (_dbType == DBType.SqlServerCE)
             {
                 sqlPage = string.Format("{0}\nOFFSET @{1} ROWS FETCH NEXT @{2} ROWS ONLY", sql, args.Length, args.Length + 1);
-                args = args.Concat(new object[] { (page - 1) * itemsPerPage, itemsPerPage }).ToArray();
+                args = args.Concat(new object[] { skip, take }).ToArray();
             }
             else
             {
                 sqlPage = string.Format("{0}\nLIMIT @{1} OFFSET @{2}", sql, args.Length, args.Length + 1);
-                args = args.Concat(new object[] { itemsPerPage, (page - 1) * itemsPerPage }).ToArray();
+                args = args.Concat(new object[] { take, skip }).ToArray();
             }
 
         }
@@ -815,7 +825,11 @@ namespace PetaPoco
         public Page<T> Page<T>(long page, long itemsPerPage, string sql, params object[] args)
         {
             string sqlCount, sqlPage;
-            BuildPageQueries<T>(page, itemsPerPage, sql, ref args, out sqlCount, out sqlPage);
+
+            long skip = (page - 1) * itemsPerPage;
+            long take = itemsPerPage;
+
+            BuildPageQueries<T>(skip, take, sql, ref args, out sqlCount, out sqlPage);
 
             // Save the one-time command time out and use it for both queries
             int saveTimeout = OneTimeCommandTimeout;
@@ -843,6 +857,21 @@ namespace PetaPoco
             return Page<T>(page, itemsPerPage, sql.SQL, sql.Arguments);
         }
 
+        public List<T> SkipTake<T>(long skip, long take, string sql, params object[] args)
+        {
+            string sqlCount, sqlPage;
+
+            BuildPageQueries<T>(skip, take, sql, ref args, out sqlCount, out sqlPage);
+
+            var result = Fetch<T>(sqlPage, args);
+            return result;
+        }
+
+        public List<T> SkipTake<T>(long skip, long take, Sql sql)
+        {
+            return SkipTake<T>(skip, take, sql.SQL, sql.Arguments);
+        }
+
         // Return an enumerable collection of pocos
         public IEnumerable<T> Query<T>(string sql, params object[] args)
         {
@@ -1213,6 +1242,38 @@ namespace PetaPoco
             var primaryKeyValuePairs = GetPrimaryKeyValues(PocoData.ForType(typeof(T)).TableInfo.PrimaryKey, primaryKey);
             return FirstOrDefault<T>(string.Format("WHERE {0}", BuildPrimaryKeySql(primaryKeyValuePairs, ref index)), primaryKeyValuePairs.Select(x => x.Value).ToArray()) != null;
         }
+
+
+        public bool Exists<T>(string sql, params object[] args)
+        {
+            var poco = PocoData.ForType(typeof(T)).TableInfo;
+
+            string existsTemplate;
+
+            switch (_dbType)
+            {
+                case DBType.SQLite:
+                case DBType.MySql:
+                    {
+                        existsTemplate = "SELECT EXISTS (SELECT 1 FROM {0} WHERE {1})";
+                        break;
+                    }
+
+                case DBType.SqlServer:
+                    {
+                        existsTemplate = "IF EXISTS (SELECT 1 FROM {0} WHERE {1}) SELECT 1 ELSE SELECT 0";
+                        break;
+                    }
+                default:
+                    {
+                        existsTemplate = "SELECT COUNT(*) FROM {0} WHERE {1}";
+                        break;
+                    }
+            }
+
+
+            return ExecuteScalar<int>(string.Format(existsTemplate, poco.TableName, sql), args) != 0;
+        }
         public T Single<T>(object primaryKey)
         {
             var index = 0;
@@ -1297,7 +1358,6 @@ namespace PetaPoco
                 {
                     using (var cmd = CreateCommand(_sharedConnection, ""))
                     {
-         
                         var pd = PocoData.ForObject(poco, primaryKeyName);
                         var names = new List<string>();
                         var values = new List<string>();
@@ -1466,6 +1526,19 @@ namespace PetaPoco
             return Insert(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, pd.TableInfo.AutoIncrement, poco);
         }
 
+        public void InsertMany<T>(IEnumerable<T> pocoList)
+        {
+            using (var tran = GetTransaction())
+            {
+                foreach (var poco in pocoList)
+                {
+                    Insert(poco);
+                }
+
+                tran.Complete();
+            }
+        }
+
         // Update a record with values from a poco.  primary key value can be either supplied or read from the poco
         public int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue)
         {
@@ -1617,6 +1690,20 @@ namespace PetaPoco
             return Execute(new Sql(string.Format("UPDATE {0}", EscapeTableName(pd.TableInfo.TableName))).Append(sql));
         }
 
+        public void UpdateMany<T>(IEnumerable<T> pocoList)
+        {
+            using (var tran = GetTransaction())
+            {
+                foreach (var poco in pocoList)
+                {
+                    Update(poco);
+                }
+
+                tran.Complete();
+            }
+        }
+
+
         public int Delete(string tableName, string primaryKeyName, object poco)
         {
             return Delete(tableName, primaryKeyName, poco, null);
@@ -1747,6 +1834,19 @@ namespace PetaPoco
             Save(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, poco);
         }
 
+        public void SaveMany<T>(IEnumerable<T> pocoList)
+        {
+            using (var tran = GetTransaction())
+            {
+                foreach (var poco in pocoList)
+                {
+                    Save(poco);
+                }
+
+                tran.Complete();
+            }
+        }
+
         public int CommandTimeout { get; set; }
         public int OneTimeCommandTimeout { get; set; }
 
@@ -2269,7 +2369,12 @@ namespace PetaPoco
     }
 
     // Transaction object helps maintain transaction depth counts
-    public class Transaction : IDisposable
+    public interface ITransaction : IDisposable
+    {
+        void Complete();
+    }
+
+    public class Transaction : ITransaction
     {
         public Transaction(Database db)
         {