/// <summary> /// Convierte una cláusula de INSERT a string. /// Si el INSERT devuelve valores. /// /// Devuelve ya sea un <see cref="InsertNoReturningStrResult"/> o un <see cref="InsertReturningToStr"/> /// </summary> public static StatementToStrResult InsertToString(InsertClause clause, ParamMode paramMode, SqlParamDic paramDic) { var b = new StringBuilder(); b.Append("INSERT INTO "); b.Append($"\"{clause.Table}\" "); if ((clause.Value == null) == (clause.Query == null)) { throw new ArgumentException("Query debe de ser null si value no es null"); } if (clause.Value != null) { b.Append(InsertValueToString(clause, paramMode, paramDic)); } else { //Query var sqlQuery = SqlSelect.SelectToStringScalar(clause.Query, paramMode, paramDic); //Texto de las columnas: b.Append("("); b.Append(string.Join(", ", sqlQuery.Columns)); b.AppendLine(")"); b.Append(sqlQuery.Sql); } if (clause.OnConflict != null) { b.AppendLine(); b.Append(OnConflict(clause.OnConflict, paramMode, paramDic, clause.Table)); } //Columnas del returning IReadOnlyList <string> columns = null; if (clause.Returning != null) { b.AppendLine(); var returning = ReturningToString(clause.Returning, paramMode, paramDic, clause.Table); b.Append(returning.sql); columns = returning.cols; } var sql = b.ToString(); if (columns != null) { return(new InsertReturningToStr(sql, columns)); } return(new InsertNoReturningStrResult(sql)); }
/// <summary> /// Convierte a string la parte del VALUE de un INSERT /// </summary> static string InsertValueToString(InsertClause clause, ParamMode paramMode, SqlParamDic paramDic) { var b = new StringBuilder(); //Note que aquí el fromAlias no afecta ya se se usan directamente los nombres de las columnas //y no se puede referenciar a la tabla de origen en los VALUES var pars = new SqlExprParams(null, null, false, null, new SqlFromList.ExprStrRawSql[0], paramMode, paramDic); //Hacer el rewrite en todo el body: var visitor = new SqlRewriteVisitor(pars); var body = visitor.Visit(clause.Value); var exprs = SqlSelect .ExtractInitExpr(body) .Select(x => (x.mem, sql: SqlExpression.ExprToSqlStar(x.expr, pars, false))) ; if (exprs.Any(y => y.sql.star)) { throw new ArgumentException("No esta soportado una expresión star '*' en la asignación de los valores de un INSERT"); } var subpaths = exprs.SelectMany(x => x.sql.sql, (parent, child) => (member: parent.mem, subpath: child)); //Nombres de las columnas del INSERT var columns = subpaths .Select(x => SqlSelect.MemberToColumnName(x.member, x.subpath)) .Select(SqlSelect.ColNameToStr); ; //Valores: var values = subpaths.Select(x => x.subpath.Sql); //Texto de las columnas: b.Append("("); b.Append(string.Join(", ", columns)); b.AppendLine(")"); //Texto de los vaues: b.Append("VALUES ("); b.Append(string.Join(", ", values)); b.Append(")"); return(b.ToString()); }
public InsertBuilder(InsertClause clause) { Clause = clause; }