how to set value which contains blank space in Redis using hiredis - redis

Well ,I am using hiredis client in centos6 to connect redis server and using it's redisAppendCommand() to send command to the server.
redisContext *redisConnect(ip,port);
std::string value = "E 1";
std::string field_name = "field";
std::string id_code = "id";
std::string key = "HSET type:info:"+ id_code + " " + field_name + " " +value;
redisAppendCommand(_contxt, key.c_str());
It could not set value to E 1 as I wanted. Then I change code like this,
redisContext *redisConnect(ip,port);
std::string value = "E 1";
std::string field_name = "field";
std::string id_code = "id";
std::string key = "HSET type:info:"+ id_code + " " + field_name + " \"" +value + "\"";
redisAppendCommand(_contxt, key.c_str());
But the value would contain \" as it's content ,so value becomes \"E 1\", I just want to know if there any way to set value just E 1 with hiredis?
Thank you.

You can use the format string to specify the command arguments:
string key_name = "type:info:" + id_code;
redisAppendCommand(redisContext,
"%s %b %b %b",
"HSET",
key_name.data(), key_name.size(),
field_name.data(), field_name.size(),
value.data(), value.size());
%b, in the format string, means binary string. With this flag, you can specify any characters for key name, field name and value. Since it's binary string, you have to specify the length of the string.

Related

How to create a dynamic query using collection-valued named parameters?

As the title suggests, i'm currently trying to add parts to the JPQL-query using collection-valued named parameters (:queryLst).
Function call:
List<PanelSet> psetLst = setRepository.getMaxZchnrGroupByLeftEight(p.getCustomerNumber(), p.getDrawingNumber(), queryLst);
queryLst:
// Is used to store values from scanned and convert them into parts of a query
ArrayList<String> queryLst = new ArrayList<>();
for (int i = 0; i < size1; i++) {
scanEdvRev = scanned.get(i).toString();
queryLst.set(i, "and left(a.drawingnumber, 8) != left('" + scanEdvRev + "', 8)");
}
SetRepository:
public interface SetRepository extends CrudRepository<PanelSet, Integer> {
#Query("select distinct max(a.drawingNumber) from PanelSet a "
+ "where a.customerNumber = :customerNumber "
+ "and a.drawingNumber != :drawingNumber (:queryLst) "
+ "group by left(a.drawingNumber, 8)")
List<PanelSet> getMaxZchnrGroupByLeftEight(#Param("customerNumber") String customerNumber,
#Param("drawingNumber") String drawingNumber,
#Param("queryLst") ArrayList<String> queryLst);
}
When i run the project i get the following exception:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 159 [select distinct max(a.drawingNumber) from com.asetronics.qis2.model.PanelSet a where a.customerNumber = :customerNumber and a.drawingNumber != :drawingNumber (:queryLst) group by left(a.drawingNumber, 8)]
I'm unsure whether my approach to this problem is the correct way of doing this and whether this exception is caused by a simple syntax error or by my usage of collection-valued named parameters.
I've followed this guide trying to solve the problem.
EDIT: I'm basically trying to add each String from ArrayList<String> queryLst to the parametrized query inside setRepository.
#Query("select distinct max(a.drawingNumber) from PanelSet a "
+ "where a.customerNumber = :customerNumber "
+ "and a.drawingNumber != :drawingNumber (:queryLst) "
+ "group by left(a.drawingNumber, 8)")
If successful, the query behind the function
List<PanelSet> getMaxZchnrGroupByLeftEight(#Param("customerNumber") String customerNumber,
#Param("drawingNumber") String drawingNumber,
#Param("queryLst") ArrayList<String> queryLst);
should look like this:
queryStr = "select distinct max(a.drawingNumber) from PanelSet a "
+ "where a.customerNumber = " + customerNumber + ""
+ "and a.drawingNumber != " + drawingNumber + "";
for (String s : queryLst) {
queryStr = queryStr + s;
}
queryStr = queryStr + " group by left(a.drawingNumber, 8)";
I hope this clarifies what i'm trying to do with queryLst.
It can't be done using your approach of passing in a list of query chunks.
The closest you'll get is by adding every possible condition to the query and provide values for all those conditions in a way that allows conditions to be ignored, typically by providing a null.
You code might look like this:
#Query("select distinct max(a.drawingNumber) from PanelSet a "
+ "where a.customerNumber = :customerNumber "
+ "and a.drawingNumber != :drawingNumber "
+ "and a.myTextColumn = coalesce(:myTextColumn, a.myTextColumn) "
+ "and a.myIntegerColumn = coalesce(:myIntegerColumn, a.myIntegerColumn) "
// etc for all possible runtime conditions
+ "group by left(a.drawingNumber, 8)")
List<PanelSet> getMaxZchnrGroupByLeftEight(
#Param("customerNumber") String customerNumber,
#Param("drawingNumber") String drawingNumber,
#Param("myTextColumn") String myTextColumn,
#Param("myIntegerColumn") Integer myIntegerColumn);
Passing null for myTextColumn or myIntegerColumn will allow that column to be any value (except null).
You'll have to find SQL that works for the type of conditions you have and the data type of the columns involved and whether nulls are allowed.
If passing nulls doesn't work, use a special value, perhaps blank for text columns and some "impossible" date like 2999-01-01 fir date columns etc and code the condition like:
and (a.myCol = :myCol or :myCol = '2999-01-01')

I have schema CSV file with variable types, workbench can't understand it, how to import this CSV format?

"bio({""constraints"":[],""type"":""STRING"",""dataSize"":500})","birthday({""constraints"":[],""type"":""DATETIME""})","chattiness({""constraints"":[],""type"":""INT"",""defaultValue"":""1""})","firstName({""constraints"":[],""type"":""STRING"",""dataSize"":250})","gender({""constraints"":[],""type"":""BOOLEAN"",""dataSize"":500})","image({""constraints"":[],""type"":""FILE_REF"",""dataSize"":500,""defaultValue"":""""})","lastName({""constraints"":[],""type"":""STRING"",""dataSize"":500})","token({""constraints"":[],""type"":""STRING"",""dataSize"":500,""dynamicProps"":{""localData"":{}}})","objectId({""constraints"":[],""type"":""STRING_ID"",""dataSize"":36})","ownerId({""constraints"":[],""type"":""STRING"",""dataSize"":36})","created({""constraints"":[],""type"":""DATETIME""})","updated({""constraints"":[],""type"":""DATETIME""})","countryInformations({""constraints"":[],""type"":""RELATION"",""autoLoad"":false,""relatedTable"":""countryInformation""})","statistics({""constraints"":[""UQ""],""type"":""RELATION"",""autoLoad"":false,""relatedTable"":""userStatistics""})"
I got this CSV as I exported Person table from Backendless.com. I never saw such CSV format. does this structure has a proper name that I can look up on the internet? is there any software that can read it and accordingly import it to a mysql db?
I'm going to withdraw my objection to calling this a CSV file. That's exactly what it is. This doesn't do the whole job, but maybe this will give you a start. This assumes there is only one line in the file; if you have multiple tables in separate files, then you'd need a loop instead of using next() on the cvs.reader.
import json
import csv
row = next(csv.reader(open('x.txt')))
for f in row:
column,_,rest = f.partition('(')
data = json.loads(rest[:-1])
print(column, data)
Now you can print data['type'] and data['dataSize']. There are still some awkward things here. It shows fields with relations to other tables, but it doesn't say what type those fields are.
based on the code provided by Tim Roberts, I wrote a script that converts Backendless CSV schema to MYSQL 8.0 Schema
import json
import csv
from os import listdir
import mysql.connector
host="host"
user="admin"
password="admin"
database="mydb"
# when true all tables with the same names will be dropped before a new ones are created
drop_existing_tables = False
mydb = mysql.connector.connect(
host=host,
user=user,
password=password,
database=database
)
path = "./"
filenames = listdir(path)
files = [ filename for filename in filenames if filename.endswith(".csv") ]
# select table
commands = "USE " + database + ";\n"
#to be able to reference a table before it s even created.
commands += "SET foreign_key_checks = 0;\n"
def constraints_to_string(constraints):
if len(constraints) == 0:
return ""
stringConstraints = ""
addIndex = False
for constraint in constraints:
if constraint == "NN":
constraint = "NOT NULL"
if constraint == "UQ":
constraint = "UNIQUE"
if constraint == "IDX":
addIndex = True
if not addIndex:
stringConstraints += " " + str(constraint)
if addIndex:
stringConstraints += ",\n INDEX (`" + column + "`)"
return stringConstraints
def map_data_type(data, column, constraints):
dataType = data["type"]
if column == "ownerId":
dataType = "BINARY(16) " + constraints + ", " + \
" FOREIGN KEY (`" + column + "`) REFERENCES `users`(`objectId`)"
elif dataType == "STRING":
dataSize = data.get("dataSize")
dataType = "VARCHAR(" + str(dataSize) + ") " + constraints
elif dataType == "STRING_ID":
dataType = "BINARY(16) NOT NULL PRIMARY KEY " + constraints
elif dataType == "RELATION":
dataType = "BINARY(16) " + constraints + ", " + \
"FOREIGN KEY (`" + column + "`) REFERENCES `" + data["relatedTable"] + "`(`objectId`)"
elif dataType == "FILE_REF":
dataType = "VARCHAR(256) " + constraints
else:
dataType += " " + constraints
return dataType
# drop tables.
if drop_existing_tables:
for file in files:
tableName = file.rpartition('.')[0]
commands += "DROP TABLE IF EXISTS " + tableName + ";\n"
commands += "\n"
# generate SQL scripts from backendless schema csv file.
for file in files:
row = next(csv.reader(open(file)))
tableName = file.rpartition('.')[0]
variablesString = ""
first=True
for f in row:
column,_,rest = f.partition('(')
data = json.loads(rest[:-1])
constraints = constraints_to_string(data.get("constraints"))
dataType = map_data_type(data, column, constraints)
if not first:
variablesString += ", \n"
variablesString += "`" + column + "`" + " " + dataType
first = False
commands += "CREATE TABLE IF NOT EXISTS " + tableName + " (" + variablesString + ");\n\n"
print(commands)
mycursor = mydb.cursor()
results = mycursor.execute(commands, multi=True)
if input("are you sure you want to execute the SQL script above? (y/n)") != "y":
mydb.commit()

token expression in flat file connection

I have loaded the variables in the format for example:
where produkt = 'Muj zivot2 R' and uraz = 'Uraz'
and I need the output in the file name to be:
Muj zivot2 R_Uraz
token worked for me, but it doesn't work in this case
" + TOKEN(" #[User::where] ","''",2) + "_" + TOKEN(" #[User::where] ","''",4) + "
You can use the following expression:
TOKEN(#[User::where],"'",2) + "_" + TOKEN(#[User::where],"'",4)
Output
Muj zivot2 R_Uraz

SQL to_date function

im modifying an oracle table using the following line of code:
db.execute("INSERT INTO "+dbOwner+"tbl_name VALUES('" + id+ "','" + studID+ "','"+"TO_DATE('"+ dateStr +"','MM/DD/YY)");
dateStr value: 2014-04-25
var now = new Date(),
dateStr = now.getFullYear() + "-",
monthCode = now.getMonth() + 1;
dateStr += ((monthCode < 10) ? ("0" + monthCode) : ("" + monthCode));
dateStr += "-" + ((now.getDate() < 10) ? ("0" + now.getDate()) : ("" + now.getDate()));
use bind variables. your insert statement will be 'visible'. there would be no problem to add quotes for variables (it will be automatic). and bonus: it is safer and faster.
Also, you can pass date as date, without transformation to/from string.
It will not work only for schema name (dbOwner).
according to what you write in the question
dateStr value is: 2014-04-25
so you should modify the date format in your code to be:
yyyy-MM-DD

Pass a SQL condition as a OleDb parameter

I have following code:
Dim executedCmd As OleDb.OleDbCommand = m_dbMgr.GetCommand()
executedCmd.CommandText = "select * from [Parameters] where "
Dim SQLcondition As String = String.Empty
For i As Integer = 0 To ParameterName.Count - 1
executedCmd.CommandText += "ParameterName = #parametername" + i.ToString() + " and ParameterValue #ParamaterCondition" + i.ToString() + " #ParameterValue" + i.ToString()
executedCmd.Parameters.AddWithValue("#parametername" + i.ToString(), ParameterName(i))
executedCmd.Parameters.AddWithValue("#ParameterValue" + i.ToString(), ParameterValue(i))
executedCmd.Parameters.AddWithValue("#ParamaterCondition" + i.ToString(), Condition(i))
Next
ParameterName, ParameterValue, ParameterCondition all are same length ArrayList, but the code does not work properly. I have verified all the variables have values.
When I run the code it reports a syntax error: "missing operations in query expression"
The problem is that ParameterCondition has values like ('>', '<', '=',.... some logical SQL operators).
Edit: How can I include conditions in parameters?
Add 1 = 1 after where to simplify building logical expression. Notice that all conditions added by AND logical operator. You can generate parameter name from columns name.
executedCmd.CommandText = "select * from [Parameters] where 1 = 1"
....
executedCmd.CommandText += " AND " + ParameterName(i) + " " + Condition(i) + " #" + ParameterName(i)
executedCmd.Parameters.AddWithValue("#" + ParameterName(i), ParameterValue(i))
ParameterCondition must all be binary operators.
The database engine would check the syntax of the SQL statement before it replaces the parameters with values. So somethinhg like "WHERE #p1 #p2 #p3" will not be parsed correctly.
Replace your condition with a string-expression e.g.
commandtext = parameterName + condition + " #p1"