T4 code generation template not behaving - code-generation

I have a template fragment that looks like this:
<#+
if (length == "0")
#> return record.Substring(offset);
<#+
else
#> return record.Substring(offset, <#= length #>);
When length != "0" it works fine, but when it is "0" it emits the record.Substring(offset); code ok but is then followed by the text "0);" (without the double-quotes) on the next line. It looks like it is emitting the fragment "<#= length #>);" from the else block. I don't understand why?

You should always use brackets in T4.
return record.Substring(offset, <#= length #>);
translates to something like
Write("return record.Substring(offset, ");
Write(length);
Write(");");
This is why "else" outputs only the first part.
Your code should be like this:
<#+ if (length == "0") { #>
return record.Substring(offset);
<#+ } else { #>
return record.Substring(offset, <#= length #>);
<#+ } #>

Related

How to pass dynamic variable in object while parsing json

I have been trying to parse a object ,using Foreach ,
it works good when i use :
this.parsedUserInfo.info.tw // or discord any.. from the below list.
I want to make the code small using foreach loop but the dyanmic value 'social' is not getting added to the parse statement in if else loop.
My code below:
this.parsedUserInfo = UserInfo.fromJson(jsonDecode(value.data)),
['tw', 'discord', 'telegram', 'fb', 'tumblr'].forEach((social) {
if (('this.parsedUserInfo.info.' + social != '')) { //if loop is not working properly.
this
.parsedPlatforms
.data[this
.parsedPlatforms
.data
.indexWhere((row) => row.socid == social)]
.connected = true;
}

Column of Binary Type -1 for MAX value

I am building a VS solution and using BIML, I have created tiers and c# code files.
When I run each individual biml file they compile and generate outputs in the viewer.
When I check for errors it throws up this error
"Column of binary type must specify positive Length or -1 to represent the MAX value.
In one of my c# code files I am doing a case statement on data type to switch into SQL data types.
In this code page I specify that the length of a binary column is -1 but I still getting the error.
Any help would be appreciated.
I have tried changing the -1 to 10 and also 1 but still get same error.
DataRow.cs FILE CONTENTS
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Varigence.Biml.Extensions;
public static class DataRow
{
public static string GetBiml(this System.Data.DataRow dataRow)
{
StringBuilder biml = new StringBuilder("");
biml.Append("<Column Name=\"")
.Append(dataRow["ColumnName"])
.Append("\" DataType=\"")
.Append(dataRow["DataTypeBiml"])
.Append("\"");
if (dataRow["DataTypeBiml"].ToString().Contains("String"))
biml.Append(" Length=\"").Append(dataRow["CharLength"]).Append("\"");
else if (dataRow["DataTypeBiml"] == "Decimal")
biml.Append(" Precision=\"").Append(dataRow["NumericPrecision"]).Append("\" Scale=\"").Append(dataRow["NumericScale"]).Append("\"");
else if (dataRow["DataTypeBiml"] == "Binary")
biml.Append(" Length=\"-1 \" ");
if (dataRow["IsNullable"] != "NO")
biml.Append(" IsNullable=\"true\"");
else
biml.Append(" IsNullable=\"false\"");
biml.Append(" />");
return biml.ToString();
}
}
1-ReadMetaData.biml
<## template tier="10" #>
<## import namespace="System.Data"#>
<## import namespace="System.Data.SqlClient"#>
<## code file="Helper.cs" #>
<## code file="DataRow.cs" #>
<#
string targetConnection = #"Data Source=SERVER;Initial Catalog=DATABASE;Integrated Security=SSPI;";
#>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Tables>
<#
var sourceTables = Helper.GetIncludedSourceTablesList();
// Loop through each source table in the included source tables list
foreach (Table sourceTable in sourceTables)
{
#>
<Table Name="<#=sourceTable.Name#>" SchemaName="schema">
<#
string targetQuery = #"SELECT OrdinalPosition = col.ORDINAL_POSITION,
ColumnName = col.COLUMN_NAME,
DataType = col.DATA_TYPE,
CharLength = ISNULL(col.CHARACTER_MAXIMUM_LENGTH, 0),
NumericPrecision = col.NUMERIC_PRECISION,
NumericScale = col.NUMERIC_SCALE,
IsNullable = col.IS_NULLABLE,
DataTypeBiml = CASE col.DATA_TYPE
WHEN 'bigint' THEN 'Int64'
WHEN 'bit' THEN 'Boolean'
WHEN 'char' THEN 'AnsiStringFixedLength'
WHEN 'datetime' THEN 'DateTime'
WHEN 'decimal' THEN 'Decimal'
WHEN 'float' THEN 'Double'
WHEN 'int' THEN 'Int32'
WHEN 'nchar' THEN 'StringFixedLength'
WHEN 'nvarchar' THEN 'String'
WHEN 'smallint' THEN 'Int16'
WHEN 'timestamp' THEN 'Binary'
WHEN 'tinyint' THEN 'Byte'
WHEN 'varchar' THEN 'AnsiString'
WHEN 'uniqueidentifier' THEN 'Guid'
ELSE 'Unknown'
END
FROM (
SELECT lkup.TABLE_SCHEMA,
lkup.TABLE_NAME,
ORDINAL_POSITION_MAX = MAX(lkup.ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS AS lkup
WHERE lkup.TABLE_SCHEMA = 'dbo'
AND lkup.TABLE_NAME = '" + sourceTable.Name + #"'
GROUP BY lkup.TABLE_SCHEMA,
lkup.TABLE_NAME
) AS maxord
INNER JOIN INFORMATION_SCHEMA.COLUMNS AS col ON (maxord.TABLE_SCHEMA = col.TABLE_SCHEMA
AND maxord.TABLE_NAME = col.TABLE_NAME)
ORDER BY col.ORDINAL_POSITION;";
DataTable targetTable = new DataTable();
SqlDataAdapter targetAdapter = new SqlDataAdapter(targetQuery,targetConnection);
targetAdapter.Fill(targetTable);
#>
<Columns>
<# foreach (DataRow targetRow in targetTable.Rows) {#>
<#=targetRow.GetBiml()#>
<# } #>
</Columns>
</Table>
<# } #>
</Tables>
</Biml>
TableList.cs FILE CONTENTS
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Varigence.Biml.Extensions;
public class Helper
{
public static List<Table> GetIncludedSourceTablesList()
{
var tablesList = new List<Table>
{
new Table() { Name = "Tab1"},
new Table() { Name = "Tab2" },
new Table() { Name = "Tab3" },
new Table() { Name = "Tab4" },
new Table() { Name = "Tab5" },
new Table() { Name = "Tab6" }
};
return tablesList;
}
}
public class Table
{
public string Name { get; set; }
}
this is the part of the output in the viewer of the ReadMetaData.biml file which is not putting the length against the binary column
<Column Name="RowVers" DataType="Binary" IsNullable="true" />
Looking at your code, it may be as simple as that you have a trailing space after your -1, which could be discarding the Length property as it has an invalid value:
So this:
biml.Append(" Length=\"-1 \" ");
Should become this:
biml.Append(" Length=\"-1\" ");
I figured the mistake out, I Had not converted the DataTypeBiml to a string to compare it once I did the length was put out correctly.
else if (dataRow["DataTypeBiml"].ToString() == "Binary")
biml.Append(" Length=\"-1\"");
Thanks for your suggestions

how to setup a for loop inside if statement with correct syntax Play framework Scala Template

I am trying to setup a variable in the scala template. Loop through the roles that user have , if found out the user is customer , then do something with the input. If not then do something else.
But scala isnt that simple , it won't compile on following code.
#var = #{ if(user != null){
#for(role <- user.roles.filter(_.getName()=="customer")) {
var=#customer(input)
}
}
}
#if( var == null){
var=#others(input)
}
It gives me two errors
t.scala.html:275:: identifier expected but 'for' found.
[error] #for(role <- user.roles.filter(_.getName()=="customer"))
t.scala.html:278: expected start of definition
Also , is there a better way to do this in scala ? Thanks
My reference : Scala template set variable
Update:
My goal was trying to do something like below , but in scala template:
result=null
for role in User.roles:
if(role == "customer"):
result=customer(xyz)
break
if(result==null):
result = others(xyz)
To set up a for loop inside of an if statement in a Scala template, you don't need to assign a variable. You can simply use an if block in the template where you want to display stuff. For example
#if(user != null) {
#for(role <- user.roles.filter(_.getName()=="customer")) {
#customer(input)
#* Do other stuff related to 'role' and 'input' here *#
}
} else {
#* Do something else *#
}
For further reference I encourage you to look at the documentation for Play templates. If you really want to define a variable you could do it using the defining helper:
#defining(user.getFirstName() + " " + user.getLastName()) { fullName =>
<div>Hello #fullName</div>
}
Instead of defining a variable you could also define a resusable block, which might be useful in your case. For example,
#customer_loop(input: String) = {
#if(user != null) {
#for(role <- user.roles.filter(_.getName()=="customer")) {
#customer(input)
#* Do other stuff related to 'role' and 'input' here *#
}
} else {
#* Do something else *#
}
}
To declare a variable do
#import scala.Any; var result:Any=null //where Any is the datatype accoding to your requirement
To reassign its value do
#{result = "somevalue"}
So the solution accoding to the pseudo you provided
#import java.lang.String; var result:String=null
#import scala.util.control._;val loop = new Breaks;
#loop.breakable {
#for(role <- roleList) {
#if(role.equals("customer")) {
#{
result = "somevalue"
}
#{loop.break};
}
}
}
#if(result==null){
#{result="notfound"}
}
Also check Similar1,Similar2

Perl index function to extract a certain substring

Given a certain sequence A stored in an array, I have to find if a larger sequence B contains sequence A.
I am stuck at the index part... and i'm getting an error that argument "TGACCA" isn't numeric in array element in line 69 which is:
if (index($record_r1[1], $r2_seq[$check]) != -1)
The code is:
foreach my $check (#r2_seq)
{
if (index($record_r1[1], $r2_seq[$check]) != -1)
{
$matches= $matches + 1;
print "Matched";
}
else
{
}
}
foreach my $check (#r2_seq)
$check takes on the value of each element in #r2_seq. It is not the index.
$r2_seq[$check]
This is attempting to use an element of #r2_seq as the index into #r2_seq. It is unlikely what you want. More probably, you want to use
$check
as in
if (index($record_r1[1], $check) != -1)
.
I believe you wanted $check to be index, so then use the following code:
foreach my $index (0..$#r2_seq)
{
if (index($record_r1[1], $r2_seq[$index]) != -1)
{
$matches= $matches + 1;
print "Matched";
}
else
{
}
}

FunctionImport in entity framework 4 issue

I'm using entity framework 4.
I have a stored procedure that just updates one value in my table, namely the application state ID. So I created a stored procedure that looks like this:
ALTER PROCEDURE [dbo].[UpdateApplicationState]
(
#ApplicationID INT,
#ApplicationStateID INT
)
AS
BEGIN
UPDATE
[Application]
SET
ApplicationStateID = #ApplicationStateID
WHERE
ApplicationID = #ApplicationID;
END
I created a function import called UpdateApplicationState. I had initially set its return type to null, but then it wasn't created in the context. So I changed its return type to int. Now it was created in the context. Is it wise to return something from my stored procedure?
Here is my method in my ApplicationRepository class:
public void UpdateApplicationState(int applicationID, int applicationStateID)
{
var result = context.UpdateApplicationState(applicationID, applicationStateID);
}
Here is my calling code to this method in my view:
applicationRepository.UpdateApplicationState(id, newApplicationStateID);
When I run it then I get the following error:
The data reader returned by the store
data provider does not have enough
columns for the query requested.
Any idea/advise on what I can do to get this to work?
Thanks
To get POCO to work with function imports that return null, you can customize the .Context.tt file like this.
Find the "Function Imports" named region (the section that starts with region.Begin("Function Imports"); and ends with region.End();) in the .Context.tt file and replace that whole section with the following:
region.Begin("Function Imports");
foreach (EdmFunction edmFunction in container.FunctionImports)
{
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, code, ef);
string paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray());
var isReturnTypeVoid = edmFunction.ReturnParameter == null;
string returnTypeElement = String.Empty;
if (!isReturnTypeVoid)
returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));
#>
<# if (isReturnTypeVoid) { #>
<#=Accessibility.ForMethod(edmFunction)#> void <#=code.Escape(edmFunction)#>(<#=paramList#>)
<# } else { #>
<#=Accessibility.ForMethod(edmFunction)#> ObjectResult<<#=returnTypeElement#>> <#=code.Escape(edmFunction)#>(<#=paramList#>)
<# } #>
{
<#
foreach (var parameter in parameters)
{
if (!parameter.NeedsLocalVariable)
{
continue;
}
#>
ObjectParameter <#=parameter.LocalVariableName#>;
if (<#=parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"#>)
{
<#=parameter.LocalVariableName#> = new ObjectParameter("<#=parameter.EsqlParameterName#>", <#=parameter.FunctionParameterName#>);
}
else
{
<#=parameter.LocalVariableName#> = new ObjectParameter("<#=parameter.EsqlParameterName#>", typeof(<#=parameter.RawClrTypeName#>));
}
<#
}
#>
<# if (isReturnTypeVoid) { #>
base.ExecuteFunction("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
<# } else { #>
return base.ExecuteFunction<<#=returnTypeElement#>>("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
<# } #>
}
<#
}
region.End();
What I'm doing here is instead of ignoring all function imports that return null, I'm creating a method that returns null. I hope this is helpful.
It is because you do not actually returning anything from your stored procedure. Add a line like below to your SP (SELECT ##ROWCOUNT), and it will be executing properly.
BEGIN
...
SELECT ##ROWCOUNT
END
While this solution will address your issue and actually returns the number of effected rows by your SP, I am not clear on why this is an issue for you:
I had initially set its return type to null, but then it wasn't created in the context.
When doing a Function Import, you can select "None" as return type and it will generate a new method on your ObjectContext with a return type of int. This method basically executes a stored procedure that is defined in the data source; discards any results returned from the function; and returns the number of rows affected by the execution.
EDIT: Why a Function without return value is ignored in a POCO Scenario:
Drilling into ObjectContext T4 template file coming with ADO.NET C# POCO Entity Generator reveals why you cannot see your Function in your ObjectContext class: Simply it's ignored! They escape to the next iteration in the foreach loop that generates the functions.
The workaround for this is to change the T4 template to actually generate a method for Functions without return type or just returning something based on the first solution.
region.Begin("Function Imports");
foreach (EdmFunction edmFunction in container.FunctionImports)
{
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, code, ef);
string paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray());
// Here is why a Function without return value is ignored:
if (edmFunction.ReturnParameter == null)
{
continue;
}
string returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));
...