예제 #1
0
        /// <summary>
        /// Parse a single table column row.
        /// </summary>
        /// <param name="sql">The SQL statement</param>
        /// <returns>The DbColumn instance for the column.</returns>
        private static DbColumn ParseColumn(ref string sql)
        {
            // In case this is a PRIMARY KEY constraint - return null immediatly
            if (sql.TrimStart(' ', '\t', '\n', '\r').StartsWith("PRIMARY KEY"))
            {
                return(null);
            }

            string   columnName      = null;
            DbType   columnType      = DbType.Int32;
            int      columnSize      = -1;
            int      columnPrecision = -1;
            DbColumn res             = new DbColumn();

            if (ParseColumnNameType(ref sql, ref columnName, ref columnType, ref columnSize, ref columnPrecision))
            {
                res.ColumnName      = columnName;
                res.ColumnSize      = columnSize;
                res.ColumnType      = columnType;
                res.ColumnPrecision = columnPrecision;

                int index = FindClosingRightParens(sql);
                if (index == -1)
                {
                    throw DbUpgradeException.SchemaIsNotSupported();
                }
                int index2 = sql.IndexOf(",");
                if (index2 != -1 && index2 < index)
                {
                    index = index2;
                }
                string rest = sql.Substring(0, index);
                sql = sql.Substring(index);

                // TRUE by default
                res.IsNullable = true;

                // Parse the list of column constraints
                Match m = _columnConstraints.Match(rest);
                while (m.Success)
                {
                    if (m.Groups[2].Success)
                    {
                        if (m.Groups[2].Value == "NOT NULL")
                        {
                            res.IsNullable = false;
                        }
                        else
                        {
                            res.IsNullable = true;
                        }
                    }
                    else if (m.Groups[1].Success)
                    {
                        res.IsPrimaryKey = true;
                    }
                    else if (m.Groups[5].Success)
                    {
                        res.DefaultValue    = null;
                        res.DefaultFunction = m.Groups[5].Value;
                    }
                    else if (m.Groups[7].Success)
                    {
                        res.DefaultValue    = m.Groups[7].Value;
                        res.DefaultFunction = null;
                    }
                    else if (m.Groups[9].Success)
                    {
                        res.DefaultValue    = double.Parse(m.Groups[9].Value);
                        res.DefaultFunction = null;
                    }
                    else if (m.Groups[11].Success)
                    {
                        res.DefaultValue    = int.Parse(m.Groups[11].Value);
                        res.DefaultFunction = null;
                    }
                    else if (m.Groups[13].Success)
                    {
                        res.Collation = m.Groups[13].Value;
                    }
                    else if (m.Groups[14].Success)
                    {
                        res.IsUnique = true;
                    }
                    else if (m.Groups[15].Success)
                    {
                        res.IsAutoIncrement = true;
                    }
                    else
                    {
                        throw DbUpgradeException.InternalSoftwareError();
                    }

                    rest = rest.Substring(m.Index + m.Length);
                    m    = _columnConstraints.Match(rest);
                } // while

                return(res);
            } // if
            else
            {
                // This is not a column - maybe it is a primary key declaration
                return(null);
            } // else
        }
예제 #2
0
        /// <summary>
        /// Parse the table columns section of the CREATE TABLE DDL statement.
        /// </summary>
        /// <param name="sql">The SQL statement to parse</param>
        /// <param name="tableName">Name of the table.</param>
        /// <returns>
        /// The list of DbColumn objects that represent the meta
        /// data about all table columns.
        /// </returns>
        public static List <DbColumn> ParseTableColumns(ref string sql, string tableName)
        {
            // Skip '('
            if (!ScanToken(ref sql, "("))
            {
                throw DbUpgradeException.SchemaIsNotSupported();
            }

            List <string>   primaryKeys = new List <string>();
            List <DbColumn> res         = new List <DbColumn>();

            do
            {
                if (sql.Trim().StartsWith(")"))
                {
                    break;
                }
                DbColumn col = ParseColumn(ref sql);
                if (col != null)
                {
                    res.Add(col);
                    if (!ScanToken(ref sql, ","))
                    {
                        if (ScanToken(ref sql, ")"))
                        {
                            break;
                        }
                        else
                        {
                            DbUpgradeException.SchemaIsNotSupported();
                        }
                    } // if
                }
                else
                {
                    // Try to parse as a PRIMARY KEY section
                    List <string> keys = ParsePrimaryKeys(ref sql);
                    if (keys != null)
                    {
                        primaryKeys.AddRange(keys);
                    }
                    else
                    {
                        throw DbUpgradeException.SchemaIsNotSupported();
                    }
                } // else
            } while (true);

            // Apply any primary keys found
            foreach (string pkey in primaryKeys)
            {
                bool found = false;
                foreach (DbColumn col in res)
                {
                    if (col.ColumnName == pkey)
                    {
                        col.IsPrimaryKey = true;
                        found            = true;
                        break;
                    }
                } // foreach

                if (!found)
                {
                    throw DbUpgradeException.InvalidPrimaryKeySection(tableName);
                }
            } // foreach

            return(res);
        }