public void Parse_valid_string_should_return_parsed_text() { string template = "INSERT INTO @{TableName}(@{sel:Name},@{sel:City},@{sel:AcceptNewAnimals}) VALUES(@{prop:Name},@{prop:City},@{prop:AcceptNewAnimals})"; string compiled = "INSERT INTO zoos(Name as zoo_Name,City as zoo_City,AcceptNewAnimals as zoo_AcceptNewAnimals) VALUES($Name,$City,$AcceptNewAnimals)"; string testMapfile = Path.Combine(SessionHelper.BaseDirectory, "TestFiles", "MapConfigTests", "TestFullMap.xml"); MapConfig config = new MapConfig(); config.Load(testMapfile); var zooEntMap = config.EntityConfigs.Where(c => string.Equals(c.Name, "Zoo", StringComparison.Ordinal)) .FirstOrDefault(); StatementMapParser parser = new StatementMapParser(); StatementInputParam inputParam = new StatementInputParam() { Name = "a", ClrType = typeof(WebZoo.Data.Zoo), Type = zooEntMap.FullName, Map = zooEntMap, IsMapped = true }; var statement = parser.Parse(new SqliteDialect(), zooEntMap, template, inputParam); Console.WriteLine(statement.Body); Assert.AreEqual(compiled, statement.Body); Assert.AreEqual(3, statement.ParamPropertyMap.Count); }
void ParseDbParameters(SqlDialect dialect, CompiledStatement statement, QueryParam[] dbParameters) { if (dbParameters == null) { dbParameters = new QueryParam[] { } } ; foreach (var param in dbParameters) { statement.Body = statement.Body.Replace("@{" + param.Name + "}", dialect.CreateParameterName(param.Name)); } } string ParseEntityMapAllowedProperties(EntityMap entMap, string text) { Dictionary <string, string> values = ExtractTags(string.Empty, text); foreach (var m in values) { string value = null; switch (m.Value) { case "TableName": value = entMap.TableName; break; case "Name": value = entMap.Name; break; case "FullName": value = entMap.FullName; break; case "Namespace": value = entMap.Namespace; break; case "TableAlias": value = entMap.TableAlias; break; case "SchemaName": value = entMap.SchemaName; break; default: throw new GoliathDataException(string.Format("Unrecognized tag name {0}", m.Key)); } text = text.Replace(m.Key, value); } return(text); } string ParseEntityMapAllowedProperties(MapConfig config, IDictionary <string, StatementInputParam> inputParams, string text) { Dictionary <string, string> values = ExtractTags(string.Empty, text); foreach (var m in values) { string value = null; var varInfo = ExtractVariables(m.Value); StatementInputParam inputVariable = new StatementInputParam(); if (inputParams.TryGetValue(varInfo.VarName, out inputVariable)) { EntityMap entMap = config.GetEntityMap(inputVariable.Type); switch (varInfo.PropName) { case "TableName": value = entMap.TableName; break; case "Name": value = entMap.Name; break; case "FullName": value = entMap.FullName; break; case "Namespace": value = entMap.Namespace; break; case "TableAlias": value = entMap.TableAlias; break; case "SchemaName": value = entMap.SchemaName; break; default: throw new GoliathDataException(string.Format("Unrecognized tag name {0}", m.Key)); } text = text.Replace(m.Key, value); } else { throw new GoliathDataException(string.Format("No input parameter of name {0} defined.", varInfo.VarName)); } } return(text); } string ReplaceColumnText(SqlDialect dialect, EntityMap entMap, Property prop, string key, string text) { if (prop == null) { throw new GoliathDataException(string.Format("Tag {0} does not match any property for entity {1}", key, entMap.FullName)); } string columnText = string.Empty; if (key.StartsWith(@"@{col:") || (entMap is DynamicEntityMap)) { columnText = prop.ColumnName; } else { //var clmn = dialect.Escape(string.Format("{0}.{1}", entMap.TableAlias, prop.ColumnName)); //TODO: regex to read content between SELECT and FROM and build TableQueryMap columnText = string.Format("{0}.{1} AS \"{0}.{2}\" ", entMap.TableAlias, prop.ColumnName, prop.PropertyName); } return(text.Replace(key, columnText));; } string ParseColumnTag(SqlDialect dialect, EntityMap entMap, string text) { Dictionary <string, string> values = ExtractTags("(col|sel)", 3, text); foreach (var m in values) { var prop = entMap[m.Value]; text = ReplaceColumnText(dialect, entMap, prop, m.Key, text); } return(text); } string ParseColumnTag(SqlDialect dialect, MapConfig config, IDictionary <string, StatementInputParam> inputParams, string text) { Dictionary <string, string> values = ExtractTags("(col|sel)", 3, text); foreach (var m in values) { var info = ExtractVariables(m.Value); StatementInputParam inputVariable = new StatementInputParam(); if (inputParams.TryGetValue(info.VarName, out inputVariable)) { var prop = inputVariable.Map[info.PropName]; text = ReplaceColumnText(dialect, inputVariable.Map, prop, m.Key, text); } else { throw new GoliathDataException(string.Format("No input parameter of name {0} defined.", info.VarName)); } } return(text); } CompiledStatement ParseObjectPropertyTag(SqlDialect dialect, EntityMap entMap, StatementInputParam inputParam, string text) { CompiledStatement statement = new CompiledStatement(); var values = ExtractTags("prop", text); foreach (var m in values) { if (inputParam != null) { var inPar = new StatementInputParam() { Type = entMap.FullName, Value = m.Value }; inPar.QueryParamName = m.Value.Replace('.', '_'); inPar.ClrType = inputParam.ClrType; inPar.IsMapped = inputParam.IsMapped; inPar.Name = inputParam.Name; inPar.Map = inputParam.Map; inPar.Property = new VarPropNameInfo() { PropName = m.Value, VarName = inputParam.Name }; statement.ParamPropertyMap.Add(m.Key, inPar); } text = text.Replace(m.Key, dialect.CreateParameterName(m.Value.Replace('.', '_'))); } statement.Body = text; return(statement); } CompiledStatement ParseObjectPropertyTag(SqlDialect dialect, MapConfig config, IDictionary <string, StatementInputParam> inputParams, string text) { CompiledStatement statement = new CompiledStatement(); var values = ExtractTags("prop", text); if (values.Count > 0) { foreach (var m in values) { var info = ExtractVariables(m.Value); StatementInputParam inputVariable; if (inputParams.TryGetValue(info.VarName, out inputVariable)) { var inPar = new StatementInputParam(); inPar.QueryParamName = m.Value.Replace('.', '_'); inPar.ClrType = inputVariable.ClrType; inPar.IsMapped = inputVariable.IsMapped; inPar.Name = inputVariable.Name; inPar.Map = inputVariable.Map; inPar.Property = info; statement.ParamPropertyMap.Add(m.Key, inPar); text = text.Replace(m.Key, dialect.CreateParameterName(inPar.QueryParamName)); } } } statement.Body = text; return(statement); } VarPropNameInfo ExtractVariables(string item) { VarPropNameInfo info = new VarPropNameInfo(); string[] split = item.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); if (split.Length < 2) { throw new GoliathDataException("cannot parse statement name.property missing"); } info.VarName = split[0]; info.PropName = split[1]; return(info); } Dictionary <string, string> ExtractTags(string tagName, string text) { return(ExtractTags(tagName, tagName.Length, text)); } Dictionary <string, string> ExtractTags(string tagName, int tagLength, string text) { //int tagLength; if (!string.IsNullOrEmpty(tagName)) { tagName = tagName + @"\:"; tagLength = tagLength + 3; } else { tagLength = tagLength + 2; } string tagPattern = @"(@\{" + tagName + @"(.*?)\})"; var matches = Regex.Matches(text, tagPattern); Dictionary <string, string> values = new Dictionary <string, string>(); foreach (Match m in matches) { string matchValue = m.Value; if (!values.ContainsKey(matchValue)) { string propName = matchValue.Substring(tagLength, matchValue.Length - (tagLength + 1)); values.Add(matchValue, propName); } } return(values); } }
/// <summary> /// Parses the specified text. /// </summary> /// <param name="dialect">The mapper.</param> /// <param name="entMap">The ent map.</param> /// <param name="text">The text.</param> /// <param name="inputParam">The input param.</param> /// <param name="dbParameters">The db parameters.</param> /// <returns></returns> public CompiledStatement Parse(SqlDialect dialect, EntityMap entMap, string text, StatementInputParam inputParam, params QueryParam[] dbParameters) { text = ParseColumnTag(dialect, entMap, text); var statement = ParseObjectPropertyTag(dialect, entMap, inputParam, text); ParseDbParameters(dialect, statement, dbParameters); statement.Body = ParseEntityMapAllowedProperties(entMap, statement.Body); return(statement); }