Ejemplo n.º 1
0
        /// <summary>
        /// Converts from <see cref="CompareOptions"/> to <see cref="UnicodeIndexFlags"/>.
        /// </summary>
        /// <param name="options">The value to convert.</param>
        /// <returns>A <see cref="UnicodeIndexFlags"/> value equivalent to <paramref name="options"/>.</returns>
        /// <exception cref="System.ArgumentException">CompareOptions.Ordinal is not supported;compareOptions</exception>
        internal static UnicodeIndexFlags UnicodeFlagsFromCompareOptions(CompareOptions options)
        {
            UnicodeIndexFlags unicodeflags = UnicodeIndexFlags.None;

            if (IsCompareOptionSet(options, CompareOptions.IgnoreCase))
            {
                unicodeflags |= UnicodeIndexFlags.CaseInsensitive;
            }

            if (IsCompareOptionSet(options, CompareOptions.IgnoreKanaType))
            {
                unicodeflags |= UnicodeIndexFlags.KanaInsensitive;
            }

            if (IsCompareOptionSet(options, CompareOptions.IgnoreNonSpace))
            {
                unicodeflags |= UnicodeIndexFlags.AccentInsensitive;
            }

            if (IsCompareOptionSet(options, CompareOptions.IgnoreSymbols))
            {
                unicodeflags |= UnicodeIndexFlags.IgnoreSymbols;
            }

            if (IsCompareOptionSet(options, CompareOptions.IgnoreWidth))
            {
                unicodeflags |= UnicodeIndexFlags.WidthInsensitive;
            }

            if (IsCompareOptionSet(options, CompareOptions.StringSort))
            {
                unicodeflags |= UnicodeIndexFlags.StringSort;
            }

            if (IsCompareOptionSet(options, CompareOptions.Ordinal))
            {
                throw new ArgumentException("CompareOptions.Ordinal is not supported", "compareOptions");
            }

            return(unicodeflags);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Converts unicodeIndexFlags to a ulong, suitable for dwMapFlags.
 /// </summary>
 /// <param name="unicodeIndexFlags">A UnicodeIndexFlags value.</param>
 /// <returns>A value suitable for calling by LCMapString.</returns>
 internal static uint MapFlagsFromUnicodeIndexFlags(UnicodeIndexFlags unicodeIndexFlags)
 {
     return((uint)unicodeIndexFlags);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Makes the <see cref="JET_OPENTEMPORARYTABLE"/> object to later open it.
        /// </summary>
        /// <param name="tableDefinition">The table definition.</param>
        /// <returns>The newly created <see cref="JET_OPENTEMPORARYTABLE"/> object.</returns>
        private JET_OPENTEMPORARYTABLE MakeOpenTemporaryTable(TableDefinition tableDefinition)
        {
            JET_OPENTEMPORARYTABLE openTemporaryTable = new JET_OPENTEMPORARYTABLE();

            // allocate room for our columns
            int currentColumndef = 0;

            openTemporaryTable.ccolumn      = tableDefinition.Columns.Count;
            openTemporaryTable.prgcolumndef = new JET_COLUMNDEF[openTemporaryTable.ccolumn];
            openTemporaryTable.prgcolumnid  = new JET_COLUMNID[openTemporaryTable.ccolumn];

            for (int coldef = 0; coldef < openTemporaryTable.ccolumn; ++coldef)
            {
                openTemporaryTable.prgcolumndef[coldef] = new JET_COLUMNDEF();
            }

            // first, collect all the key columns in order and put them as the
            // first columndefs.  we have to do this to guarantee that the TT
            // is sorted properly
            foreach (IndexDefinition indexDefinition in tableDefinition.Indices)
            {
                foreach (KeyColumn keyColumn in indexDefinition.KeyColumns)
                {
                    ColumnDefinition columnDefinition = tableDefinition.Columns[keyColumn.Name];

                    openTemporaryTable.prgcolumndef[currentColumndef].coltyp =
                        DatabaseCommon.ColtypFromColumnDefinition(columnDefinition);
                    openTemporaryTable.prgcolumndef[currentColumndef].cp    = JET_CP.Unicode;
                    openTemporaryTable.prgcolumndef[currentColumndef].cbMax = columnDefinition.MaxLength;
                    openTemporaryTable.prgcolumndef[currentColumndef].grbit = (ColumndefGrbit)columnDefinition.Flags
                                                                              | ColumndefGrbit.TTKey
                                                                              | (keyColumn.IsAscending
                                                                                     ? ColumndefGrbit.None
                                                                                     : ColumndefGrbit.TTDescending);
                    currentColumndef++;
                }
            }

            // next collect the rest of the columns and put them after the key
            // columns, skipping over the columns we already added
            foreach (ColumnDefinition columnDefinition in tableDefinition.Columns)
            {
                bool alreadyAdded = false;
                foreach (IndexDefinition indexDefinition in tableDefinition.Indices)
                {
                    foreach (KeyColumn keyColumn in indexDefinition.KeyColumns)
                    {
                        if (keyColumn.Name.ToLower(CultureInfo.InvariantCulture) == columnDefinition.Name.ToLower(CultureInfo.InvariantCulture))
                        {
                            alreadyAdded = true;
                        }
                    }
                }

                if (!alreadyAdded)
                {
                    openTemporaryTable.prgcolumndef[currentColumndef].coltyp = DatabaseCommon.ColtypFromColumnDefinition(columnDefinition);
                    openTemporaryTable.prgcolumndef[currentColumndef].cp     = JET_CP.Unicode;
                    openTemporaryTable.prgcolumndef[currentColumndef].cbMax  = columnDefinition.MaxLength;
                    openTemporaryTable.prgcolumndef[currentColumndef].grbit  = Converter.ColumndefGrbitFromColumnFlags(columnDefinition.Flags);
                    currentColumndef++;
                }
            }

            // set the index flags
            foreach (IndexDefinition indexDefinition in tableDefinition.Indices)
            {
                openTemporaryTable.pidxunicode = new JET_UNICODEINDEX();

                openTemporaryTable.pidxunicode.lcid = indexDefinition.CultureInfo.LCID;
                UnicodeIndexFlags unicodeIndexFlags = Converter.UnicodeFlagsFromCompareOptions(indexDefinition.CompareOptions);
                openTemporaryTable.pidxunicode.dwMapFlags = Converter.MapFlagsFromUnicodeIndexFlags(unicodeIndexFlags);
            }

            // infer the TT mode of operation and set its grbits accordingly
            bool haveColumnWithLongValue = false;

            foreach (ColumnDefinition columnDefinition in tableDefinition.Columns)
            {
                JET_coltyp coltyp = DatabaseCommon.ColtypFromColumnDefinition(columnDefinition);

                if (coltyp == JET_coltyp.LongText || coltyp == JET_coltyp.LongBinary)
                {
                    haveColumnWithLongValue = true;
                }
            }

            bool haveIndexWithSortNullsHigh = false;

            foreach (IndexDefinition indexDefinition in tableDefinition.Indices)
            {
                if ((indexDefinition.Flags & IndexFlags.SortNullsHigh) != 0)
                {
                    haveIndexWithSortNullsHigh = true;
                }
            }

            if (tableDefinition.Type == TableType.Sort)
            {
                foreach (IndexDefinition indexDefinition in tableDefinition.Indices)
                {
                    if ((indexDefinition.Flags & (IndexFlags.Unique | IndexFlags.Primary)) == 0)
                    {
                        // External Sort without duplicate removal
                        openTemporaryTable.grbit = Server2003Grbits.ForwardOnly
                                                   | (haveColumnWithLongValue
                                                          ? Windows7Grbits.IntrinsicLVsOnly
                                                          : TempTableGrbit.None)
                                                   | (haveIndexWithSortNullsHigh
                                                          ? TempTableGrbit.SortNullsHigh
                                                          : TempTableGrbit.None);
                    }
                    else
                    {
                        // External Sort TT with deferred duplicate removal
                        openTemporaryTable.grbit = TempTableGrbit.Unique
                                                   | (haveColumnWithLongValue
                                                          ? Windows7Grbits.IntrinsicLVsOnly
                                                          : TempTableGrbit.None)
                                                   | (haveIndexWithSortNullsHigh
                                                          ? TempTableGrbit.SortNullsHigh
                                                          : TempTableGrbit.None);
                    }
                }
            }
            else if (tableDefinition.Type == TableType.PreSortTemporary)
            {
                // Pre-sorted B+ Tree TT with deferred duplicate removal
                openTemporaryTable.grbit = TempTableGrbit.Indexed
                                           | TempTableGrbit.Unique
                                           | TempTableGrbit.Updatable
                                           | TempTableGrbit.Scrollable
                                           | (haveColumnWithLongValue
                                                  ? Windows7Grbits.IntrinsicLVsOnly
                                                  : TempTableGrbit.None)
                                           | (haveIndexWithSortNullsHigh
                                                  ? TempTableGrbit.SortNullsHigh
                                                  : TempTableGrbit.None);
            }
            else if (tableDefinition.Type == TableType.Temporary)
            {
                if (tableDefinition.Indices.Count != 0)
                {
                    // B+ Tree TT with immediate duplicate removal
                    openTemporaryTable.grbit = TempTableGrbit.Indexed
                                               | TempTableGrbit.Unique
                                               | TempTableGrbit.Updatable
                                               | TempTableGrbit.Scrollable
                                               | TempTableGrbit.ForceMaterialization
                                               | (haveIndexWithSortNullsHigh
                                                      ? TempTableGrbit.SortNullsHigh
                                                      : TempTableGrbit.None);
                }
                else
                {
                    // B+ Tree TT with a sequential index
                    openTemporaryTable.grbit = TempTableGrbit.Updatable | TempTableGrbit.Scrollable;
                }
            }

            // set the key construction parameters for the TT
            foreach (IndexDefinition indexDefinition in tableDefinition.Indices)
            {
                openTemporaryTable.cbKeyMost   = indexDefinition.MaxKeyLength;
                openTemporaryTable.cbVarSegMac = 0;
            }

            // return the constructed JET_OPENTEMPORARYTABLE (whew!)
            return(openTemporaryTable);
        }