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