Beispiel #1
0
        internal TableInfo(Database db, string name)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }

            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            this.name = name;

            using (View columnsView = db.OpenView("SELECT * FROM `{0}`", name))
            {
                this.columns = new ColumnCollection(columnsView);
            }

            this.primaryKeys = new ReadOnlyCollection<string>(
                TableInfo.GetTablePrimaryKeys(db, name));
        }
Beispiel #2
0
        internal MergeException(Database db, string conflictsTableName)
            : base("Merge failed.")
        {
            if (conflictsTableName != null)
            {
                IList<string> conflictTableList = new List<string>();
                IList<int> conflictCountList = new List<int>();

                using (View view = db.OpenView("SELECT `Table`, `NumRowMergeConflicts` FROM `" + conflictsTableName + "`"))
                {
                    view.Execute();

                    foreach (Record rec in view) using (rec)
                    {
                        conflictTableList.Add(rec.GetString(1));
                        conflictCountList.Add((int) rec.GetInteger(2));
                    }
                }

                this.conflictTables = conflictTableList;
                this.conflictCounts = conflictCountList;
            }
        }
Beispiel #3
0
        internal static Session OpenPackage(Database database, bool ignoreMachineState)
        {
            if (database == null)
            {
            throw new ArgumentNullException("database");
            }

            return Installer.OpenPackage(
            String.Format(CultureInfo.InvariantCulture, "#{0}", database.Handle),
            ignoreMachineState);
        }
Beispiel #4
0
 /// <summary>
 /// Merges another database with this database.
 /// </summary>
 /// <param name="otherDatabase">The database to be merged into this database</param>
 /// <exception cref="MergeException">merge failed due to a schema difference or data conflict</exception>
 /// <exception cref="InvalidHandleException">the Database handle is invalid</exception>
 /// <remarks><p>
 /// MsiDatabaseMerge does not copy over embedded cabinet files or embedded transforms from
 /// the reference database into the target database. Embedded data streams that are listed in
 /// the Binary table or Icon table are copied from the reference database to the target database.
 /// Storage embedded in the reference database are not copied to the target database.
 /// </p><p>
 /// The Merge method merges the data of two databases. These databases must have the same
 /// codepage. The merge fails if any tables or rows in the databases conflict. A conflict exists
 /// if the data in any row in the first database differs from the data in the corresponding row
 /// of the second database. Corresponding rows are in the same table of both databases and have
 /// the same primary key in both databases. The tables of non-conflicting databases must have
 /// the same number of primary keys, same number of columns, same column types, same column names,
 /// and the same data in rows with identical primary keys. Temporary columns however don't matter
 /// in the column count and corresponding tables can have a different number of temporary columns
 /// without creating conflict as long as the persistent columns match.
 /// </p><p>
 /// If the number, type, or name of columns in corresponding tables are different, the
 /// schema of the two databases are incompatible and the installer will stop processing tables
 /// and the merge fails. The installer checks that the two databases have the same schema before
 /// checking for row merge conflicts. If the schemas are incompatible, the databases have be
 /// modified.
 /// </p><p>
 /// Win32 MSI API:
 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msidatabasemerge.asp">MsiDatabaseMerge</a>
 /// </p></remarks>
 internal void Merge(Database otherDatabase)
 {
     this.Merge(otherDatabase, null);
 }
Beispiel #5
0
        internal void Merge(Database otherDatabase, string errorTable)
        {
            if (otherDatabase == null)
            {
                throw new ArgumentNullException("otherDatabase");
            }

            uint ret = NativeMethods.MsiDatabaseMerge((int) this.Handle, (int) otherDatabase.Handle, errorTable);
            if (ret != 0)
            {
                if (ret == (uint) NativeMethods.Error.FUNCTION_FAILED)
                {
                    throw new MergeException(this, errorTable);
                }
                else if (ret == (uint) NativeMethods.Error.DATATYPE_MISMATCH)
                {
                    throw new MergeException("Schema difference between the two databases.");
                }
                else
                {
                    throw InstallerException.ExceptionFromReturnCode(ret);
                }
            }
        }
Beispiel #6
0
        private static IList<string> GetTablePrimaryKeys(Database db, string table)
        {
            if (table == "_Tables")
            {
                return new string[] { "Name" };
            }
            else if (table == "_Columns")
            {
                return new string[] { "Table", "Number" };
            }
            else if (table == "_Storages")
            {
                return new string[] { "Name" };
            }
            else if (table == "_Streams")
            {
                return new string[] { "Name" };
            }
            else
            {
                int hrec;
                uint ret = RemotableNativeMethods.MsiDatabaseGetPrimaryKeys(
                    (int) db.Handle, table, out hrec);
                if (ret != 0)
                {
                    throw InstallerException.ExceptionFromReturnCode(ret);
                }

                using (Record rec = new Record((IntPtr) hrec, true, null))
                {
                    string[] keys = new string[rec.FieldCount];
                    for (int i = 0; i < keys.Length; i++)
                    {
                        keys[i] = rec.GetString(i + 1);
                    }

                    return keys;
                }
            }
        }
Beispiel #7
0
 /// <summary>
 /// Closes the session handle.  Also closes the active database handle, if it is open.
 /// After closing a handle, further method calls may throw an <see cref="InvalidHandleException"/>.
 /// </summary>
 /// <param name="disposing">If true, the method has been called directly
 /// or indirectly by a user's code, so managed and unmanaged resources will
 /// be disposed. If false, only unmanaged resources will be disposed.</param>
 internal override void Dispose(bool disposing)
 {
     try
     {
         if (disposing)
         {
             if (this.database != null)
             {
                 this.database.Dispose();
                 this.database = null;
             }
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }
Beispiel #8
0
        internal void CreateTransformSummaryInfo(
            Database referenceDatabase,
            string transformFile,
            TransformErrors errors,
            TransformValidations validations)
        {
            if (referenceDatabase == null)
            {
                throw new ArgumentNullException("referenceDatabase");
            }

            if (String.IsNullOrEmpty(transformFile))
            {
                throw new ArgumentNullException("transformFile");
            }

            uint ret = NativeMethods.MsiCreateTransformSummaryInfo(
                (int) this.Handle,
                (int) referenceDatabase.Handle,
                transformFile,
                (int) errors,
                (int) validations);
            if (ret != 0)
            {
                throw InstallerException.ExceptionFromReturnCode(ret);
            }
        }
Beispiel #9
0
        internal bool GenerateTransform(Database referenceDatabase, string transformFile)
        {
            if (referenceDatabase == null)
            {
                throw new ArgumentNullException("referenceDatabase");
            }

            if (String.IsNullOrEmpty(transformFile))
            {
                throw new ArgumentNullException("transformFile");
            }

            uint ret = NativeMethods.MsiDatabaseGenerateTransform((int) this.Handle, (int) referenceDatabase.Handle, transformFile, 0, 0);
            if (ret == (uint) NativeMethods.Error.NO_DATA)
            {
                return false;
            }
            else if (ret != 0)
            {
                throw InstallerException.ExceptionFromReturnCode(ret);
            }
            return true;
        }