#region License // Copyright 2005-2019 Paul Kohler (https://github.com/paulkohler/minisqlquery). All rights reserved. // This source code is made available under the terms of the GNU Lesser General Public License v3.0 // https://github.com/paulkohler/minisqlquery/blob/master/LICENSE #endregion using System.Collections.Generic; using System.IO; namespace MiniSqlQuery.Core.DbModel { /// The sql writer. public class SqlWriter : ISqlWriter { /// Initializes a new instance of the class. public SqlWriter() { // todo - format options? IncludeComments = true; InsertLineBreaksBetweenColumns = true; } /// Gets or sets a value indicating whether IncludeComments. /// The include comments. public bool IncludeComments { get; set; } /// Gets or sets a value indicating whether InsertLineBreaksBetweenColumns. /// The insert line breaks between columns. public bool InsertLineBreaksBetweenColumns { get; set; } /// /// Gets or sets a value indicating whether to include read-only columns in the export SQL. /// /// /// true if including read-only columns in the export; otherwise, false. /// public bool IncludeReadOnlyColumnsInExport { get; set; } /// The write create. /// The writer. /// The column. public virtual void WriteCreate(TextWriter writer, DbModelColumn column) { writer.Write("{0} {1} ", MakeSqlFriendly(column.Name), column.DbType.Summary); if (!column.Nullable) { writer.Write("not "); } writer.Write("null"); } /// The write delete. /// The writer. /// The table or view. public virtual void WriteDelete(TextWriter writer, DbModelTable tableOrView) { writer.WriteLine("DELETE FROM"); writer.Write("\t"); writer.WriteLine(MakeSqlFriendly(tableOrView.FullName)); writer.WriteLine("WHERE"); for (int i = 0; i < tableOrView.PrimaryKeyColumns.Count; i++) { var column = tableOrView.PrimaryKeyColumns[i]; writer.Write("\t{0} = ", MakeSqlFriendly(column.Name)); if (i < tableOrView.PrimaryKeyColumns.Count - 1) { writer.Write(" /*value:{0}*/ AND", column.Name); writer.WriteLine(); } else { writer.Write("/*value:{0}*/", column.Name); } } writer.WriteLine(); } /// The write insert. /// The writer. /// The table or view. public virtual void WriteInsert(TextWriter writer, DbModelTable tableOrView) { writer.Write("INSERT INTO "); writer.Write(MakeSqlFriendly(tableOrView.FullName)); if (InsertLineBreaksBetweenColumns) { writer.WriteLine(); writer.Write("\t"); } writer.Write("("); // get all columns that are "writable" including PKs that are not auto generated (unless specified) List writableColumns = null; if (IncludeReadOnlyColumnsInExport) { writableColumns = tableOrView.Columns; } else { writableColumns = tableOrView.Columns.FindAll(c => c.IsWritable); } for (int i = 0; i < writableColumns.Count; i++) { var column = writableColumns[i]; writer.Write(MakeSqlFriendly(column.Name)); if (i < writableColumns.Count - 1) { if (InsertLineBreaksBetweenColumns) { writer.WriteLine(","); writer.Write("\t"); } else { writer.Write(", "); } } } writer.WriteLine(")"); writer.Write("VALUES"); if (InsertLineBreaksBetweenColumns) { writer.WriteLine(); writer.Write("\t"); } writer.Write("("); for (int i = 0; i < writableColumns.Count; i++) { var column = writableColumns[i]; writer.Write(column.DbType.ToDDLValue(column.Nullable)); if (IncludeComments) { writer.Write(" /*{0},{1}*/", column.Name, column.DbType.Summary); } if (i < writableColumns.Count - 1) { if (InsertLineBreaksBetweenColumns) { writer.WriteLine(","); writer.Write("\t"); } else { writer.Write(", "); } } } writer.WriteLine(")"); } /// The write select. /// The writer. /// The table or view. public virtual void WriteSelect(TextWriter writer, DbModelTable tableOrView) { writer.Write("SELECT"); writer.WriteLine(); for (int i = 0; i < tableOrView.Columns.Count; i++) { writer.Write("\t"); writer.Write(MakeSqlFriendly(tableOrView.Columns[i].Name)); if (i < tableOrView.Columns.Count - 1) { writer.Write(","); writer.WriteLine(); } } writer.WriteLine(); writer.Write("FROM {0}", MakeSqlFriendly(tableOrView.FullName)); writer.WriteLine(); } /// The write select count. /// The writer. /// The table or view. public virtual void WriteSelectCount(TextWriter writer, DbModelTable tableOrView) { writer.Write("SELECT COUNT(*) FROM {0}", MakeSqlFriendly(tableOrView.FullName)); writer.WriteLine(); } /// The write summary. /// The writer. /// The column. public void WriteSummary(TextWriter writer, DbModelColumn column) { writer.Write("{0} ({1} ", MakeSqlFriendly(column.Name), column.DbType.Summary); if (!column.Nullable) { writer.Write("not "); } writer.Write("null)"); } /// The write update. /// The writer. /// The table or view. public virtual void WriteUpdate(TextWriter writer, DbModelTable tableOrView) { writer.Write("UPDATE "); writer.WriteLine(MakeSqlFriendly(tableOrView.FullName)); writer.WriteLine("SET"); // get all columns that are "writable" excluding keys that are not auto generated var writableColumns = tableOrView.Columns.FindAll(c => c.IsWritable && !c.IsKey); for (int i = 0; i < writableColumns.Count; i++) { var column = writableColumns[i]; writer.Write("\t{0} = {1}", MakeSqlFriendly(column.Name), column.DbType.ToDDLValue(column.Nullable)); if (i < writableColumns.Count - 1) { writer.Write(","); writer.WriteLine(); } } writer.WriteLine(); writer.WriteLine("WHERE"); for (int i = 0; i < tableOrView.PrimaryKeyColumns.Count; i++) { var column = tableOrView.PrimaryKeyColumns[i]; writer.Write("\t{0} = ", MakeSqlFriendly(column.Name)); if (i < tableOrView.PrimaryKeyColumns.Count - 1) { writer.Write(" /*value:{0},{1}*/ AND", column.Name, column.DbType.Summary); writer.WriteLine(); } else { writer.Write("/*value:{0},{1}*/", column.Name, column.DbType.Summary); } } writer.WriteLine(); } /// The make the sql friendly, e.g. "[TableName]". /// The name of the object. /// The make sql friendly name. protected string MakeSqlFriendly(string name) { return Utility.MakeSqlFriendly(name); } } }