/// <summary> /// Fetches the next sequential record from the view, or null if there are no more records. /// </summary> /// <exception cref="InstallerException">the View is not in an active state</exception> /// <exception cref="InvalidHandleException">the View handle is invalid</exception> /// <remarks><p> /// The Record object should be <see cref="InstallerHandle.Close"/>d after use. /// It is best that the handle be closed manually as soon as it is no longer /// needed, as leaving lots of unused handles open can degrade performance. /// </p><p> /// Win32 MSI API: /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiviewfetch.asp">MsiViewFetch</a> /// </p></remarks> public Record Fetch() { int recordHandle; uint ret = RemotableNativeMethods.MsiViewFetch((int)this.Handle, out recordHandle); if (ret == (uint)NativeMethods.Error.NO_MORE_ITEMS) { return(null); } else if (ret != 0) { throw InstallerException.ExceptionFromReturnCode(ret); } Record r = new Record((IntPtr)recordHandle, true, this); r.IsFormatStringInvalid = true; return(r); }
/// <summary> /// Gets the count of all rows in the table that satisfy a given condition. /// </summary> /// <param name="table">Name of the table whose rows are to be counted</param> /// <param name="where">Conditional expression, such as could be placed on the end of a SQL WHERE clause</param> /// <returns>The count of all rows in the table satisfying the condition</returns> /// <exception cref="BadQuerySyntaxException">the SQL WHERE syntax is invalid</exception> /// <exception cref="InstallerException">the View could not be executed</exception> /// <exception cref="InvalidHandleException">the Database handle is invalid</exception> public int CountRows(string table, string where) { if (string.IsNullOrWhiteSpace(table)) { throw new ArgumentNullException("table"); } int count; using (View view = this.OpenView( "SELECT `{0}` FROM `{1}`{2}", this.Tables[table].PrimaryKeys[0], table, (where != null && where.Length != 0 ? " WHERE " + where : ""))) { view.Execute(); for (count = 0; ; count++) { // Avoid creating unnecessary Record objects by not calling View.Fetch(). int recordHandle; uint ret = RemotableNativeMethods.MsiViewFetch((int)view.Handle, out recordHandle); if (ret == (uint)NativeMethods.Error.NO_MORE_ITEMS) { break; } if (ret != 0) { throw InstallerException.ExceptionFromReturnCode(ret); } RemotableNativeMethods.MsiCloseHandle(recordHandle); } } return(count); }