How to search in an array with npgsql? - npgsql

I have an array column i would like to search.
The search term is like :
WHERE ARRAY['tag1','tag2'] <# tags
If i search like this (where donnee is the string of the text to search):
string variable1 = string.Empty;
string[] tags = donnee.Split(',');
if (tags.Length > 1)
{
foreach (string item in tags)
{
variable1 = variable1 + "'" + item + "',";
}
variable1 = variable1.Remove(variable1.Length - 1);
}
else
{
variable1 = variable1 + "'" + tags[0] + "'";
}
NpgsqlCommand cmd = new NpgsqlCommand("SELECT id,name FROM wincorrespondants WHERE (name ILIKE #donnee) OR (ARRAY[#var] <# tags) LIMIT 100", conn);
cmd.Parameters.AddWithValue("donnee", "%" + donnee + "%");
cmd.Parameters.AddWithValue("var", variable1);
the search don't work on the tag array but the program does not crash if there is a ' in the search string
If i search like this:
string variable1 = string.Empty;
string[] tags = donnee.Split(',');
if (tags.Length > 1)
{
foreach (string item in tags)
{
variable1 = variable1 + "'" + item + "',";
}
variable1 = variable1.Remove(variable1.Length - 1);
}
else
{
variable1 = variable1 + "'" + tags[0] + "'";
}
NpgsqlCommand cmd = new NpgsqlCommand("SELECT id,name FROM wincorrespondants WHERE (name ILIKE #donnee) OR (ARRAY["+variable1+"] <# tags) LIMIT 100", conn);
cmd.Parameters.AddWithValue("donnee", "%" + donnee + "%");
the program crash if there is a ' in the search string but work in other case (the program find the name the user is looking for or the user with the tags)
How do i format my search ?

Rather than trying to pass elements of the array, you should be sending the array itself as a parameter from Npgsql. For example:
var cmd = new NpgsqlCommand("SELECT id,name FROM wincorrespondants WHERE (name ILIKE #donnee) OR (#arr <# tags) LIMIT 100", conn);
cmd.Parameters.AddWithValue("arr", new[] {"tag1", "tag2" });

Related

Build a dynamic string to filter a rest call

I'm trying to build a dynamic string but I'm facing a problem, so I kindly ask help to the community.
A have a string to build a rest call filter, but I'm lost with the and's
This query only works if only one filter condition is provided, but I have to provide as AND
var query;
var queryDefault = "IsLastForLevelAndParticipant eq 1";
this.state.participantFirstName
? query += "substringof('" + this.state.participantFirstName + "',Participant/FirstName)"
: queryDefault
this.state.participantLastName
? query += "substringof('" + this.state.participantLastName + "',Participant/LastName)"
: queryDefault
So let´s see.
If I start building this and only one filter is provided I'll have a plus and
var query;
var queryDefault = "IsLastForLevelAndParticipant eq 1";
this.state.participantFirstName
? query += "substringof('" + this.state.participantFirstName + "',Participant/FirstName) and "
: queryDefault
this.state.participantLastName
? query += "substringof('" + this.state.participantLastName + "',Participant/LastName)"
: queryDefault
query += " and " + queryDefault
I have 12 filters and I must know how many have values in order to provide the and clause
This is my state
//Filters Certificates
startEmission: string;
endEmission: string;
startValidity: string;
endValidity: string;
participantFirstName: string;
participantLastName: string;
paticipantCertNumber: string;
selectYesNo: string;
selectLevel: string;
Any help is a bonus.
Add all possible filters to an array, filter the falsy values and finally join all items with " and ".
var query = [
queryDefault,
this.state.participantFirstName && "substringof('" + this.state.participantFirstName + "',Participant/FirstName)"
this.state.participantLastName && "substringof('" + this.state.participantLastName + "',Participant/LastName)"
]
.filter(item => !!item)
.join(" and ");
BTW. are you using OData? the structure of the filter looks familiar. If you do, I would recommend you to use this library: https://github.com/techniq/odata-query#readme
Since I'm using datetime also, here it is the final solution
var queryDefault = "IsLastForLevelAndParticipant eq 1";
var query = [
queryDefault,
this.state.startEmission && "(Date1 ge datetime'" + moment.utc(this.state.startEmission).toISOString() + "') and (Date1 le datetime'"
+ moment.utc(this.state.endEmission).toISOString() + "')",
this.state.startValidity && "(Validto ge datetime'" + moment.utc(this.state.startValidity).toISOString() + "') and (Validto le datetime'"
+ moment.utc(this.state.endValidity).toISOString() + "')",
this.state.participantFirstName && "(substringof('" + this.state.participantFirstName + "',Participant/FirstName))",
this.state.participantLastName && "(substringof('" + this.state.participantLastName + "',Participant/LastName))",
this.state.selectYesNo && "IsPrinted eq " + this.state.selectYesNo,
this.state.selectLevel && "Level/Title eq '" + this.state.selectLevel + "'"
]
.filter(filter => !! filter)
.join(" and ");
var q = JSON.stringify(query).substring(1).slice(0, -1);
console.log(JSON.stringify(query));

Possible to download JPA repository in Vaadin as CSV file?

Assume that we have defined a entity and it's connected to a database. Now we can access the database by using a repository.
#Autowired
private DataLoggRepository dataLoggRepository;
If I want to get all the rows from the database and download it. Then I can write this code:
List<DataLogg> dataLoggers = dataLoggRepository.findAll();
Now, how can I donwload the object dataLoggers as a CSV file in Vaadin in a proper way?
Here you can see how to create a link to download a file:
Anchor csvLink = new Anchor(new StreamResource("file.csv",
() -> {
String csvString = ...// create the csv
return new ByteArrayInputStream(csvString.getBytes());
}), "Download CSV");
csvLink.getElement().setAttribute("download", true);
To create the CSV you have various options like OpenCSV or directly create the CSV from the SQL query.
Here is a working example
// Download all data
Anchor download = new Anchor(); // Add this to the layout
loggerId.addValueChangeListener(e-> {
String fileName = String.valueOf(loggerId.getValue()) + ".csv";
List<DataLogg> selectedLogger = dataLoggRepository.findByLoggerId(loggerId.getValue());
download.setHref(getStreamResource(fileName, selectedLogger));
});
download.getElement().setAttribute("download",true);
download.add(new Button("Download", new Icon(VaadinIcon.DOWNLOAD_ALT)));
Function
public StreamResource getStreamResource(String filename, List<DataLogg> selectedLogger) {
// Create a large CSV file in a form of StringBuilder and then convert it all to bytes
StringWriter stringWriter = new StringWriter();
stringWriter.write("id, dateTime, DO0, DO1, DO2, DO3, AI0, AI1, AI2, AI3, loggerId, samplingTime\n");
for (int i = 0; i < selectedLogger.size(); ++ i) {
DataLogg dataLogg = selectedLogger.get(i);
String row = dataLogg.getId() + "," +
dataLogg.getDateTime() + "," +
dataLogg.getDO0() + "," +
dataLogg.getDO1() + "," +
dataLogg.getDO2() + "," +
dataLogg.getDO3() + "," +
dataLogg.getAI0() + "," +
dataLogg.getAI1() + "," +
dataLogg.getAI2() + "," +
dataLogg.getAI3() + "," +
dataLogg.getLoggerId() + "," +
dataLogg.getSamplingTime() + "\n";
stringWriter.write(row);
}
// Try to download
try {
byte[] buffer = stringWriter.toString().getBytes("UTF-8");
return new StreamResource(filename, () -> new ByteArrayInputStream(buffer));
} catch (UnsupportedEncodingException e) {
byte[] buffer = new byte[] {0};
return new StreamResource(filename, () -> new ByteArrayInputStream(buffer));
}
}

loop through sheet for unmarked value to update Google contacts

I've got a working script that grabs the last row of a Google sheet and pushes the info into Google contacts.
var ss = SpreadsheetApp.getActiveSheet(); //var emailRow = ss.getRange('F2:F').getValues();
var emailRowNum = ss.getLastRow(); //var emailRowNum = emailRow.filter(String).length + 1;
function email() {
var emailNew = ss.getRange(emailRowNum,6).getValue(); //var emailNew = ss.getRange("F"+emailRowNum).getValues();
return emailNew;}
function givenName() {
var fname = ss.getRange(emailRowNum,4).getValue();
return fname;}
function lastName() {
var lname = ss.getRange(emailRowNum,5).getValue();
return lname;}
function loc() {
var street = ss.getRange(emailRowNum,8).getValue();
var city = ss.getRange(emailRowNum,9).getValue();
return street + " " + city;}
function phone() {
var phone = ss.getRange(emailRowNum,7).getValue();
return phone;}
function notes() {
var date = ss.getRange(emailRowNum,1).getValue();
var work = ss.getRange(emailRowNum,2).getValue();
var photo = ss.getRange(emailRowNum,3).getValue();
var site = ss.getRange(emailRowNum,12).getValue();
var find = ss.getRange(emailRowNum,10).getValue();
var referrer = ss.getRange(emailRowNum,11).getValue();
return (date + "\n\n" + work + "\n\n" + photo + "\n\n" + site + "\n\n" + find + " " + referrer + "\n\n-- eom --\n\n");}
function create() {
var fname = givenName();
var lname = lastName();
var contact = ContactsApp.createContact(fname, lname, email());
var group = ContactsApp.getContactGroup('emf');
group.addContact(contact);
var contacts = ContactsApp.getContactsByName(fname + ' ' + lname);
var setaddress = contacts[0].addAddress(ContactsApp.Field.HOME_ADDRESS,loc());
var setphone = contacts[0].addPhone(ContactsApp.Field.MAIN_PHONE,phone());
for (var i in contacts) {
contacts[i].setNotes(notes());
}
}
I'd like to modify it so that instead of grabbing the last row, it checks a column for a (not) value. If value is not found, then update Google contacts with that row's information.
Currently, I'm getting a 'Range not found' error ...
function info(){
var ss = SpreadsheetApp.getActiveSheet();
var data = ss.getRange("N1:N").getValues();
for(var n=0;n<data.length;n++){
if(data[n-1] != 'done'){
var email = ss.getRange("F"+n).getValue(); // Range not found error
var fname = ss.getRange("D"+n).getValue();
var lname = ss.getRange("E"+n).getValue();
var city = ss.getRange("I"+n).getValue();
var street = ss.getRange("H"+n).getValue();
var phone = ss.getRange("G"+n).getValue();
var date = ss.getRange("A"+n).getValue();
var work = ss.getRange("B"+n).getValue();
var photo = ss.getRange("C"+n).getValue();
var site = ss.getRange("L"+n).getValue();
var find = ss.getRange("J"+n).getValue();
var referrer = ss.getRange("K"+n).getValue();
var contact = ContactsApp.createContact(fname, lname, email);
var group = ContactsApp.getContactGroup('emf');
group.addContact(contact);
var contacts = ContactsApp.getContactsByName(fname + ' ' + lname);
var setaddress = contacts[0].addAddress(ContactsApp.Field.HOME_ADDRESS,street + " " + city);
var setphone = contacts[0].addPhone(ContactsApp.Field.MAIN_PHONE,phone);
for (var i in contacts) {
contacts[i].setNotes(date + "\n\n" + work + "\n\n" + photo + "\n\n" + site + "\n\n" + find + " " + referrer + "\n\n-- eom --\n\n");}
}
}
}
1 is the first row using A1Notation with getRange(). The first iteration is trying to getValue() of F0. Changing the n to start at 1 and n <= data.length should get the ranges you are looking for.
...
for(var n=1;n<=data.length;n++){
if(data[n-1] == 'done'){
var email = ss.getRange("F"+n).getValue(); // Range not found error
...
edit: One thing to note the var data = ss.getRange("N1:N").getValues(); range is going to loop over all 1000 default rows. This may not be ideal if your data set is significantly smaller than 1000 rows.

SQLError could not prepare statement

Hi Im trying to dynamically ORDER BY my sqlite in angular. but it always says erro rcould not prepare statement.. and it redirect to my order string.. But when I manually set my ASC or DESC it works pretty well. My question is how can I set my string to my query
This is my js. The order_by_field is equal to the name and the order is equal to the ASC or DESC
//Sort Priority Ascending
$scope.sortAsc = function() {
sort_orderby('name', 'asc');
$scope.orderByPopover.hide();
};
//Sort Priority Descending
$scope.sortDesc = function() {
sort_orderby('name', 'desc');
$scope.orderByPopover.hide();
};
function sort_orderby(order_by_field, order) {
var query = "SELECT * FROM listJobs ORDER BY '" + order_by_field + "' '"+ order +"' ";
$cordovaSQLite.execute(db, query, [])
//If success
.then(function(data) {
offlineGetJobList();
console.log(data.rows)
},
function(err) {
console.error(err);
});
}
line
var query = "SELECT * FROM listJobs ORDER BY '" + order_by_field + "' '"+ order +"' ";
should be
var query = "SELECT * FROM listJobs ORDER BY " + order_by_field + " "+ order +" ";

Reading calendar folder in a date range using JACOB

hi guys is it possible on JACOB on reading only CALENDAR folder with a date range and let me get the subject. If yes please give a sample code for reference. Thanks a lot
This code has two filters
1) first only by date range - start and end date
2) filter by subject = "test"
If you need only date, you can omit second filter.
How to: Filter Recurring Appointments and Search for a String in the Subject
Dispatch namespace = outlokAx.getProperty("Session").toDispatch();
Dispatch calendarFolder = Dispatch.call(namespace, "GetDefaultFolder", new Integer(9)).toDispatch();
Dispatch calItems = Dispatch.get(calendarFolder, "items").toDispatch();
String customFilter = "#SQL=\"urn:schemas:calendar:dtstart\" > '" + DateUtility.dateToUtcString(startDate) + "' and \"urn:schemas:calendar:dtend\" = '" + DateUtility.dateToUtcString(endDate) + "'" ;
String customFindFilter = "#SQL=\"urn:schemas:httpmail:subject\" like '" + "test" + "'" ;
Dispatch restrictedItems = Dispatch.call(calItems, "Restrict", new Variant(customFilter)).toDispatch(); //Works only with dates
Dispatch.call(calItems, "Sort", "[Start]");
Dispatch.put(restrictedItems, "IncludeRecurrences", "False");
int numberOfMatchingItems = 0;
Dispatch lastitemFound = null;
if (restrictedItems != null && restrictedItems.m_pDispatch > 0) {
Dispatch findItem = Dispatch.call(restrictedItems, "Find", customFindFilter).toDispatch(); // Find Works with other attributes
while (findItem != null && findItem.m_pDispatch > 0) {
numberOfMatchingItems++;
lastitemFound = findItem;
findItem = Dispatch.call(restrictedItems, "FindNext").toDispatch();
Variant start = Dispatch.get(findItem, "Start");
Variant end = Dispatch.get(findItem, "End");
Variant subject = Dispatch.get(findItem, "Subject");
System.out.println("# Outlook event fetched: " + subject + " start: '" + start + "' end '" + end + "'");
}
}

Resources