/// <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 }
/// <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); }