using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Data; using ServerExplorer.Code; namespace ServerExplorer { public class CodeGen { private static string FixNombre(string strIn) { return strIn.Replace(' ', '_'); } public static void GeneraDTO(Config config, TablaDesc t) { string nombreObj = FixNombre(t.Esquema) + "_" + FixNombre(t.Nombre); string nombreFichero = config.PathDTO + "/" + nombreObj + "_DTO.cs"; EscritorCodigo escritor = new EscritorCodigo(nombreFichero); // Cabecera escritor.Escribe("using System;"); escritor.Escribe("using System.Data;"); escritor.Escribe(""); escritor.EscribeInd("namespace " + config.NamespaceDTO); // El objeto de la tabla escritor.EscribeInd("public partial class " + nombreObj); foreach (ColumnaDesc c in t.Columnas) { string nombre = FixNombre(c.Nombre); TipoCol tipo = c.GetTipo(); string sTipo = null; // Determinar el tipo a usar switch (tipo) { case TipoCol.Numerico: sTipo = "int"; break; case TipoCol.Texto: sTipo = "string"; break; case TipoCol.AproxNumerico: sTipo = "double"; break; case TipoCol.Tiempo: sTipo = "DateTime"; break; case TipoCol.Booleano: sTipo = "bool"; break; case TipoCol.Binario: sTipo = "byte[]"; break; } if (sTipo == null) { continue; } // El atributo privado para cada columna escritor.Escribe("private " + sTipo + " _" + nombre + ";"); // La propiedad publica para cada columna escritor.EscribeInd("public " + sTipo + " " + nombre); escritor.EscribeInd("get"); escritor.Escribe("return _" + nombre + ";"); escritor.DeInd(); escritor.EscribeInd("set"); escritor.Escribe("_" + nombre + " = value;"); escritor.DeInd(); escritor.DeInd(); escritor.Escribe(""); } escritor.DeInd(); // El Pie escritor.DeInd(); // Cerrar ficheros escritor.Cerrar(); } private static void GenerarDALParametrosTabla (TablaDesc t, String varPrm, String varCmd, String varDTO, bool input, EscritorCodigo escritor) { foreach (ColumnaDesc c in t.Columnas) { string nombre = FixNombre(c.Nombre); TipoCol tipo = c.GetTipo(); // Establecer el tipo del parametro switch (tipo) { case TipoCol.Numerico: escritor.Escribe(varPrm + " = new SqlParameter(\"@[" + c.Nombre + "]\",SqlDbType.Int);"); break; case TipoCol.Texto: escritor.Escribe(varPrm + " = new SqlParameter(\"@[" + c.Nombre + "]\", " + "SqlDbType.VarChar, " + c.Tamanho + ");"); break; case TipoCol.AproxNumerico: escritor.Escribe(varPrm + " = new SqlParameter(\"@[" + c.Nombre + "]\", SqlDbType.Real);"); break; case TipoCol.Tiempo: escritor.Escribe(varPrm + " = new SqlParameter(\"@[" + c.Nombre + "]\", SqlDbType.DateTime);"); break; case TipoCol.Booleano: escritor.Escribe(varPrm + " = new SqlParameter(\"@[" + c.Nombre + "]\", SqlDbType.Bit);"); break; case TipoCol.Binario: if (c.Tamanho > 0) { escritor.Escribe(varPrm + " = new SqlParameter(\"@[" + c.Nombre + "]\", " + "SqlDbType.VarBinary, " + c.Tamanho + ");"); } else { escritor.Escribe(varPrm + " = new SqlParameter(\"@[" + c.Nombre + "]\", SqlDbType.Binary);"); } break; default: continue; } if (input) { escritor.Escribe(varPrm + ".Direction = ParameterDirection.Input;"); } else { escritor.Escribe(varPrm + ".Direction = ParameterDirection.Output;"); } escritor.Escribe(varPrm + ".Value = " + varDTO + "." + nombre + ";"); escritor.Escribe(varCmd + ".Parameters.Add(" + varPrm + ");"); } escritor.Escribe(""); } private static void GenerarDALInsert(Config config, TablaDesc t, EscritorCodigo escritor) { string nombreObj = FixNombre(t.Esquema) + "_" + FixNombre(t.Nombre); string strInsert1, strInsert2; // Cabecera y variables del metodo escritor.EscribeInd("public bool Insertar(" + nombreObj + " reg)"); escritor.Escribe("SqlCommand cmd;"); escritor.Escribe("SqlParameter prm;"); escritor.Escribe("int nRows;"); escritor.Escribe(""); // Preparacion del comando strInsert1 = String.Empty; strInsert2 = String.Empty; foreach (ColumnaDesc c in t.Columnas) { TipoCol tipo = c.GetTipo(); if (tipo == TipoCol.Otro) continue; if (strInsert1 == String.Empty) { // Primera columna strInsert1 += "[" + c.Nombre + "]"; strInsert2 += "@[" + c.Nombre + "]"; } else { // Cualquier otra columna strInsert1 += ", [" + c.Nombre + "]"; strInsert2 += ", @[" + c.Nombre + "]"; } } escritor.Escribe("cmd = new SqlCommand(\"INSERT INTO [" + t.Esquema + "].[" + t.Nombre + "] " + "(" + strInsert1 + ") " + "VALUES (" + strInsert2 + "\");"); escritor.Escribe(""); // Preparacion de los parametros GenerarDALParametrosTabla(t, "prm", "cmd", "reg", true, escritor); // Ejecucion escritor.Escribe("cnx.Open();"); escritor.Escribe("nRows = cmd.ExecuteNonQuery()"); escritor.Escribe("cnx.Close();"); escritor.Escribe(""); // Pie escritor.Escribe("return (nRows>0);"); escritor.DeInd(); escritor.Escribe(""); } private static void GenerarDALActualizar(Config config, TablaDesc t, EscritorCodigo escritor) { string nombreObj = FixNombre(t.Esquema) + "_" + FixNombre(t.Nombre); string strActualizar, strFiltroPrimario; // Cabecera y variables del metodo escritor.EscribeInd("public bool Actualizar(" + nombreObj + " reg)"); escritor.Escribe("SqlCommand cmd;"); escritor.Escribe("SqlParameter prm;"); escritor.Escribe("int nRows;"); escritor.Escribe(""); // Preparacion del comando strActualizar = String.Empty; foreach (ColumnaDesc c in t.Columnas) { TipoCol tipo = c.GetTipo(); if (tipo == TipoCol.Otro) continue; if (c.Primaria) continue; if (strActualizar != String.Empty) { strActualizar += ","; } strActualizar += "[" + c.Nombre + "]=@[" + c.Nombre + "]"; } strFiltroPrimario = String.Empty; foreach (ColumnaDesc c in t.Columnas) { TipoCol tipo = c.GetTipo(); if (!c.Primaria) continue; if (strFiltroPrimario != String.Empty) { strFiltroPrimario += " AND "; } strFiltroPrimario += "[" + c.Nombre + "]=@[" + c.Nombre + "]"; } escritor.Escribe("cmd = new SqlCommand(\"UPDATE [" + t.Esquema + "].[" + t.Nombre + "] " + "SET " + strActualizar + " " + "WHERE " + strFiltroPrimario + "\");"); escritor.Escribe(""); // Preparacion de los parametros GenerarDALParametrosTabla(t, "prm", "cmd", "reg", true, escritor); // Ejecucion escritor.Escribe("cnx.Open();"); escritor.Escribe("nRows = cmd.ExecuteNonQuery();"); escritor.Escribe("cnx.Close();"); escritor.Escribe(""); // Pie escritor.Escribe("return (nRows>0);"); escritor.DeInd(); escritor.Escribe(""); } public static void GeneraDAL(Config config, TablaDesc t) { string nombreObj = FixNombre(t.Esquema) + "_" + FixNombre(t.Nombre); string nombreDAL = FixNombre(t.Esquema) + "_" + FixNombre(t.Nombre) + "_DAL"; string nombreFichero = config.PathDTO + "/" + nombreDAL + ".cs"; EscritorCodigo escritor = new EscritorCodigo(nombreFichero); // Cabecera. escritor.Escribe("using System;"); escritor.Escribe("using System.Data;"); escritor.Escribe("using System.Data.Sql;"); escritor.Escribe("using System.Data.SqlClient;"); escritor.Escribe(""); escritor.Escribe("using " + config.NamespaceDTO + ";"); escritor.Escribe(""); escritor.EscribeInd("namespace " + config.NamespaceDAL); // El objeto DAL. escritor.EscribeInd("public partial class " + nombreDAL); // Atributos internos escritor.Escribe("SqlConnexion cnx;"); escritor.Escribe(""); // Constructor escritor.EscribeInd("public " + nombreDAL + "(SqlConnexion cnx)"); escritor.Escribe("this.cnx = cnx;"); escritor.DeInd(); escritor.Escribe(""); // Metodo Insertar. GenerarDALInsert(config, t, escritor); // Metodo Actualizar. GenerarDALActualizar(config, t, escritor); // FIXME: Metodo Borrar. // FIXME: Metodo Leer. // FIXME: Metodo LeerTodos // Cerrar objeto DAL. escritor.DeInd(); // El Pie escritor.DeInd(); // Cerrar ficheros. escritor.Cerrar(); } public static Boolean GenerarCodigo(Config config, DatabaseDesc database) { // Asegura la existencia de los directorios destinos if (!Directory.Exists(config.PathRaiz)) { Utiles.CrearDirectorio(config.PathRaiz); } if (!Directory.Exists(config.PathDTO)) { Utiles.CrearDirectorio(config.PathDTO); } if (!Directory.Exists(config.PathDAL)) { Utiles.CrearDirectorio(config.PathDAL); } if (!Directory.Exists(config.PathExtra)) { Utiles.CrearDirectorio(config.PathExtra); } // Itera por cada tabla para crear sus DTO y DAL foreach (TablaDesc t in database.Tablas) { GeneraDTO(config, t); GeneraDAL(config, t); } return true; } private class Indentado { private int indentado = 0; private StringBuilder sb = new StringBuilder(); public void Inc() { indentado++; } public void Dec() { indentado--; if (indentado < 0) { indentado = 0; } } public string Str() { sb.Remove(0, sb.Length); for (int i = 0; i < indentado; i++) { sb.Append("\t"); } return sb.ToString(); } } private class EscritorCodigo { StreamWriter escritor; Indentado indentado; public EscritorCodigo(string nombreFichero) { escritor = new StreamWriter(nombreFichero); indentado = new Indentado(); } public void Cerrar() { escritor.Close(); } public void Escribe(String str) { escritor.WriteLine(indentado.Str() + str); } public void EscribeInd(String str) { escritor.WriteLine(indentado.Str() + str); escritor.WriteLine(indentado.Str() + "{"); indentado.Inc(); } public void DeInd() { indentado.Dec(); escritor.WriteLine(indentado.Str() + "}"); } } } }