Is there any Builder class to construct KeyConditionExpression string for DynamoDB query expression? - amazon-dynamodb

From the DDB documentation, KeyConditionExpression is a string to be passed when performing a query on a DDB table/ index.
This expression has a specific structure, so wanted to know if there is a Builder class to get this string?
From what I have searched, it looks like there is no such builder class and simple string concatenations like this are to be used.
String keyConditionExpression = "#" + "id" + " = " + ":" + "idValue"; // "#id = :idValues";
While this is simple, I feel this doesn't look clean.
Note: I am using DynamoDbMapper client (from aws-java-sdk) to integrate with DDB.

This ultimately depends on which client you are using. But there a numerous ways to build an expression without using a String. For example:
QuerySpec spec = new QuerySpec()
.withHashKey("id", "my-id");
ItemCollection<QueryOutcome> items = table.query(spec);
I suggest reading over the API Reference Docs for the client you are using to find the most appropriate way for you.

Related

What do I need to learn for accessing data from mssql database?

I am learning asp.net core mvc and API. I can simply work on it for CRUD operation. But, I get confused for accessing data from multiple tables like listing all categories with showing number of items each categories contains. What I need to learn for example Lina, entity framework code first, ado.net? I am currently using entity framework code first.
Thanks
Learn Dapper a simple object mapper for .NET.
What I Understood from your problem is that you have multiple tables and you want to query them and map the query result in your c# or vb code.Here I will show simple mapping of query result to c# objects.
Suppose you have three tables category_1,category_2 and category_3.
Lets say each table have two columns named itemName and ItemValue.
Lets create c# class corresponding to each table.
class category_1{
string ItemName {get;set};
int ItemValue {get;set;};
}
class category_2{
string ItemName {get;set};
int ItemValue {get;set;};
}
class category_3{
string ItemName {get;set};
int ItemValue {get;set;};
}
Suppose your querying three tables and map the result of query to respective object in c#.
let our sql query be as follows:
string sql = #"select * from category_1;select * from category_2;select * from category_3;"
Here we have three select statements and each select statement will give you result of respective table.Lets query the above sql to database using dapper and map them to c# object as follows.
List<category_1> lstCotegory1 = new List<category_1>();
List<category_2> lstCotegory2 = new List<category_2>();
List<category_3> lstCotegory3 = new List<category_3>();
using (var multi = connection.QueryMultiple(sql))
{
lstCotegory1 = multi.Read<category_1>().ToList(); // map first select statement
lstCotegory2 = multi.Read<category_2>().ToList(); // map second select statement
lstCotegory3 = multi.Read<category_3>().ToList(); // map third select statement.
}
This is how you can return results of multiple queries and map them to appropriate object. I know you can do better than this but to understand we have to go with simple example.Hope this will help.

Difficulty searching Kentico smart search index on integer field using API

I have a Pages smart search index which uses the Standard analyzer. When I examine the generated index in Luke I can see that integer fields have a specific format. For example, all pages created by global administrator have the documentcreatedbyuserid field set to 10000000053.
Reading the documentation I see that integer fields like this need to be searched using a particular syntax:
+DocumentCreatedByUserID;(int)53;Administrator
However, when I pass this string to the following code as the searchQuery variable I get no results.
// Get search results
var parameters = new SearchParameters()
{
AttachmentOrderBy = "",
AttachmentWhere = "",
CheckPermissions = false,
ClassNames = null,
CombineWithDefaultCulture = false,
CurrentCulture = this.Context.CultureCode,
DefaultCulture = CultureHelper.GetDefaultCultureCode(this.Context.SiteName),
DisplayResults = resultsPerPage,
NumberOfProcessedResults = 100,
Path = startPath,
SearchFor = searchQuery,
SearchInAttachments = false,
SearchIndexes = index,
SearchSort = sort,
StartingPosition = (page - 1) * resultsPerPage,
User = this.Context.User.UserInfo
};
ds = CMS.Search.SearchHelper.Search(parameters);
This same code works fine for text field search queries. Can anyone explain:
Is there anything obvious I'm doing wrong?
What is the purpose of the final part of the +DocumentCreatedByUserID;(int)53;Administrator query. Why should I need to pass a text value here?
The field I actually want to search is a custom page type field called newstypeid, which I can see is storing its value in the same way in the index (e.g. a value of 34 is stored as 10000000034).
In Luke if I query +newstypeid:10000000034 I get results. So maybe an easier solution is to find a way to translate an integer to this Lucene format? (i.e. 34 to 10000000034)
UPDATE WITH SOLUTION
Thanks to #richard-Šůstek for pointing me in the right direction. The following method will return a search clause in the required format:
protected string GetIntegerIdClause(string field, int id)
{
var condition = string.Format("{0}:(int){1}", field, id).ToLower();
return SearchSyntaxHelper.CombineSearchCondition(null, new SearchCondition(condition, SearchModeEnum.ExactPhrase, SearchOptionsEnum.NoneSearch));
}
I think you should use SearchValueConverter class from the namespace CMS.Search. This class has static methods to convert specific data type values (int,datetime,etc.) to it's string representation for search terms construction.
Can you try using something like this to transform the searchQuery?:
var condition = new SearchCondition(null, searchModeEnum, SearchOptionsEnum.FullSearch);
searchQuery = SearchSyntaxHelper.CombineSearchCondition(searchText, condition);
I noticed that Kentico is internally calling this method when passing the value from search text box to SearchParameters. I haven't had a chance to test this though. Maybe some other method in SearchSyntaxHelper would be useful too.

Change a space to a + in order to complete an api in flex

I'm trying to make a search form to use on an api. However when the user types in the search field more then one name I want it to break the string into pieces and make a new string with a + between every keyword. I have no idea how to do this however.
Try this
var searchString:String = "nameOne nameTwo nameThree";
var whiteSpacePattern:RegExp = /\s+/g;
var replacedString:String = searchString.replace(whiteSpacePattern, "+");
trace(replacedString); // nameOne+nameTwo+nameThree
More information about String.replace : http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f00.html#WS5b3ccc516d4fbf351e63e3d118a9b90204-7ef1

Accessing the query string value using ASP.NET

I have been trying to find the question to my answer but I'm unable to and finally I'm here. What I want to do is access the value passed to a webpage (GET, POST request) using asp.net. To be more clear, for example:
URL: http://www.foobar.com/SaleVoucher.aspx?sr=34
Using asp.net I want to get the sr value i.e 34.
I'm from the background of C# and new to ASP.NET and don't know much about ASP.NET.
Thanx.
Can you refer to this QueryString
Here he says how to access the query string using:
Request.Url.Query
That is not called a Header, but the Query String.
the object document.location.search will contain that and the javascript to get any query string value based on the key would be something like:
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
code from other question: https://stackoverflow.com/a/901144/28004

SQLite Parameters - Not allowing tablename as parameter

I'm developing an application in AIR via Flex, but I'm not seeing where I'm going wrong with SQLite (I'm used to MySQL). Parameters work, but only in certain instances. Is this part of the built-in sanitation system against sql injection? Thanks for any help!
Works:
sqlite
"INSERT :Fields FROM Category", where the parameter is :Fields = "*"
as3
var statement:SQLStatement = new SQLStatement();
statement.connection = connection;
statement.text = "INSERT :Fields FROM Category";
statement.parameters[":Fields"] = "*";
statement.execute;
Doesn't Work (SQL syntax error at ":Table"):
sqlite
"INSERT :Fields FROM :Table", where the parameters are :Fields = "*" and :Table = "Category"
as3
var statement:SQLStatement = new SQLStatement();
statement.connection = connection;
statement.text = "INSERT :Fields FROM :Table";
statement.parameters[":Fields"] = "*";
statement.parameters[":Table"] = "Category";
statement.execute;
Generally one cannot use SQL parameters/placeholders for database identifiers (tables, columns, views, schemas, etc.) or database functions (e.g., CURRENT_DATE), but instead only for binding literal values.
With server-side support for parameterized (a.k.a. prepared) statements, the DB engine parses your query once, remembering out the peculiars of any parameters -- their types, max lengths, precisions, etc. -- that you will bind in subsequent executions of the already-parsed query. But the query cannot be properly parsed into its syntactic elements if critical bits, like database objects, are unknown.
So, one generally has to substitute table names oneself, in a stored procedure or in client code which dynamically concats/interpolates/whatevers the SQL statement to be properly executed. In any case, please remember to use your SQL API's function for quoting database identifiers, since the API won't do it for you.
Not sure if this is the same but I ran across something similar in Java. Basically you can't add a table as a parameter so you must generate the statement like so:
var statement:SQLStatement = new SQLStatement();
statement.connection = connection;
statement.text = stringUtil.substitute("INSERT :Fields FROM {0}", "Category");
statement.parameters[":Fields"] = "*";
statement.execute;
This is mostly likely not the securest solution, so you might want to some custom validation of the data before you add the table name.. so someone doesn't try to send it the table name ";drop tableName..."

Resources