how can i use sqlite rawQuery? - sqlite

when I call select in other function, there is problem in line number 3.
Is it wrong?
public String[] select(int n){
db = helper.getReadableDatabase();
Cursor c = db.rawQuery("SELECT * FROM info WHERE number='" + n + "'", null);
}

The rawQuery() looks good, though usually you wouldn't quote integers as 'string literal'.
However, a non-void method must return a value and your method doesn't return anything. Add return null; to make it compile; implement a loop that builds a string array to return a non-null value.

Related

Correctly returning Int from Hashmap in a function

I have a function in Kotlin which takes in an Int argument and return a value based on a formula. To speed things up I store intermediate results in a HashMap<Int, Int>
private val calculatedResults = HashMap<Int, Int>()
private fun q2(n: Int): Int {
if(calculatedResults.containsKey(n)) {
return calculatedResults[n]
}
val q = ...
calculatedResults[n] = q
return q
}
I'm getting a type mismatch of Int found but Int? required at
return calculatedResults[n]
Im not sure how to correctly write this. I had
return calculatedResults[n]!!
But I'm not sure, if it's a bit hacky.
Should the return type of the function be Int? because while the HashMap might contain the key n the value could be null? Wouldn't that mean the HashMap should be <Int, Int?>?
getOrPut will check if a value exists for n. If the value exists, it will be returned. If the values does not exist the value returned by the lambda will be assigned and afterwards returned by getOrPut.
Take a look at this example:
fun calculate(n: Int) = n * 5 // some calculation
private fun q2(n: Int) = calculatedResults.getOrPut(n) {
calculate(n)
}
Should the return type of the function be Int? because while the
HashMap might contain the key n the value could be null? Wouldn't that
mean the HashMap should be ?
In this case the answer to the question is obviously "no" because if the value is missing you just add it. So, the value returned by q2 can never be null.
The underlying problem is that calculatedResults could have been modified by an other thread between contains (if(calculatedResults.containsKey(n))) and get (return calculatedResults[n]).
Even after checking with containsKey calculatedResults[n] could therefore possibly return a wrong result, including null, and this way of checking should be avoided.
Using !! should generally only be used when absolutely necessary, because it can cause a NPE. It definitely is hacky.
Use the following syntax to overcome the problem:
calculatedResults[n]?.let {
return it
}
Basically this is a nice way of saying
val result = calculatedResults[n]
if(result != null) {
return result
}
see https://kotlinlang.org/docs/reference/null-safety.html#safe-calls
Even better is to use the built-in getOrPut:
private fun q2(n: Int): Int {
return calculatedResults.getOrPut(n) { calcQ() }
}
private fun calcQ(): Int {
val q = ...
return q
}
Should the return type of the function be Int? because while the HashMap might contain the key n the value could be null? Wouldn't that mean the HashMap should be <Int, Int?>?
No, you did exactly the right thing when you defined the method signature. The compiler only complained because what happened within the method did not fit it. If you change the method signature you just move the problem to the function calling q2 without handling it.
You should consider re-writing this to more idiomatic code. It's a rather basic task to compute a value if it is not set in the map already:
fun q2(n: Int): Int {
return calculatedResults.getOrPut(n) {
42 //q
}
}

JSON Lists not removing duplicates with Distinct command

Currently I am querying a web service that returns a JSON string.
url = #"redacted url;
returnValue = new WebClient().DownloadString(url);
I am putting the return results into a list of items defined in a model class. I am then running a second JSON call searching a different field with that same search term.
url2 = #"redacted url2;
returnValue2 = new WebClient().DownloadString(url2);
I then create my lists and combine the lists using AddRange.
List<Order> shipments = JsonConvert.DeserializeObject<List<Order>>(returnValue);
List<Order> shipments2 = JsonConvert.DeserializeObject<List<Order>>(returnValue2);
shipments.AddRange(shipments2);
As a result there are some duplicates. To try and only return unique records I am using the command Distinct when sending to my MVC view from the controller.
return View(shipments.OrderBy(x => x.dtDateReceived).Distinct().ToList());
But for some reason it's still returning duplicates.
Any ideas on what I am doing wrong here?
Thanks in advance for any help!
I ended up correcting it using Shyju's comment above.
I changed the Distinct to the following.
return View(shipments.OrderBy(x => x.dtDateReceived).Distinct(new OrderComparer()).ToList());
Then built the following compare functions
// Custom comparer for the Order class
class OrderComparer : IEqualityComparer<Order>
{
// Orders are equal if their names and order numbers are equal.
public bool Equals(Order x, Order y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//Check whether the order's properties are equal.
return x.sWorkOrderNumber == y.sWorkOrderNumber && x.sCustomerOrderName == y.sCustomerOrderName;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(Order order)
{
//Check whether the object is null
if (Object.ReferenceEquals(order, null)) return 0;
//Get hash code for the sCustomerOrderName field if it is not null.
int hashOrderName = order.sCustomerOrderName == null ? 0 : order.sCustomerOrderName.GetHashCode();
//Get hash code for the sWorkOrderNumber field.
int hashOrderCode = order.sWorkOrderNumber.GetHashCode();
//Calculate the hash code for the order.
return hashOrderName ^ hashOrderCode;
}
}

How to return String from Optional<String>?

I have the following function.
public String getSomething(){
TextInputDialog dialog = new TextInputDialog();
dialog.setHeaderText("X");
dialog.setTitle("Y");
Optional<String> result = dialog.showAndWait();
return result;
}
Obviously, the returned value is not of String type. How could I return a String when result's type is Optional<String>?
Try doing result.get() should return a string.
I would do something like this to make sure you are protecting from null
if(a. isPresent()) {a.get()}
I'd use orElse which provides a default value in case the actual value is absent:
public String getSomething(){
TextInputDialog dialog = new TextInputDialog();
dialog.setHeaderText("X");
dialog.setTitle("Y");
return dialog.showAndWait().orElse("n/a");
}
Use String.valueOf(optionalString);
Optional<String> s1 =Optional.of("Hello");
// s1 will print - Optional["Hello"]
String s1 = String.valueOf(optionalObj.get());
// now s1 will print "Hello"
this would extract the exact string literal from the optional object.

How to get value of a variable in a long delimited string

In a db table I have a string, such as...
Var1=0;CosType=1;DefaultType=US_Pass;DateYear=1;DateRange=1;ReportFormat=0
I want to create a VB.NET function that has 1 input var, the string (above) and the "token" to get the value for. (The return value is the value of the token.) For example, if I call it (LongString is the string above)....
txtValue.text = MyFunction(LongString,"DefaultType")
So, "US_Pass" would be returned.
What is the most efficient way to code MyFunction?
I've tried something like this...
return LongString.Substring(LongString.IndexOf(input_token) + 12)
I feel I'm close, but so far away.
Thanks!
This works as long as you know the key exists in your string:
public string MyFunction(string longString, string key)
{
return
longString
.Split(';')
.Select(x => x.Split('='))
.ToDictionary(x => x[0], x => x[1])[key];
}
With this code:
string longString = "Var1=0;CosType=1;DefaultType=US_Pass;DateYear=1;DateRange=1;ReportFormat=0";
Console.WriteLine(MyFunction(longString, "DefaultType"));
I get:
US_Pass
As VB.NET:
Public Function MyFunction(longString As String, key As String) As String
Return longString.Split(";"c).Select(Function(x) x.Split("="c)).ToDictionary(Function(x) x(0), Function(x) x(1))(key)
End Function
Split the string into parts at the semi-colons.
Dim parts As String() = LongString.Split(";")
Loop over the parts in a ForEach loop.
Find the part that StartsWith the the token value.
Find the equal sign (IndexOf) and take everything to the right of it (Substring).
That should give you enough to figure it out.
It's probably not a great idea to store data like this in your database. Hopefully you won't need to query these attributes from SQL.
In your case I would create a class to encapsulate the attributes. You pass in the string as a constructor parameter and let the class manage it.
Here's an example in C# that shouldn't be too hard to convert to VB:
public class AttributeCollection
{
private readonly Dictionary<string, string> _attrs;
public AttributeCollection(string values)
{
_attrs = (from v in values.Split(new[] {';'})
select v.Split(new[] {'='})).ToDictionary(i => i[0], i => i[1]);
}
public string this[string name]
{
get { return _attrs[name]; }
set { _attrs[name] = value; }
}
public override string ToString()
{
return string.Join(";", (from a in _attrs select a.Key + "=" + a.Value).ToArray());
}
}

Sqlite Row Number

I have problem with my database row number. My table has 3 columns(ROWID,WORD,DEFINITION) and 3 row. I delete second row and then I try to query same row, my app fails. is this an autoincrement problem? what should I do?
Here is my code;
//Get that function
public String getThat(int id) {
String result= "";
String[] columns = new String[]{KEY_ROWID,KEY_WORD,KEY_DEFINITION};
Cursor c = ourDatabase.query(DB_TABLE, columns, KEY_ROWID +
"=" + id, null, null, null, null,null);
if(c!=null){
c.moveToFirst();
}
result = c.getString(c.getColumnIndex(KEY_DEFINITION));
return result;
}
//delete function
public boolean deleteRecords(long rowId){
return ourDatabase.delete(DB_TABLE, KEY_ROWID +"="+rowId,null)>0;
}
When the query doesn't match anything, a non-null Cursor is returned anyway but it doesn't contain any rows. When you try to access data from a non-existing row an exception is thrown.
Change this
if(c!=null){
c.moveToFirst();
}
result = c.getString(c.getColumnIndex(KEY_DEFINITION));
to something like
if(c.moveToFirst()){
result = c.getString(c.getColumnIndex(KEY_DEFINITION));
}
i.e. check the return value of moveTo..() and only access cursor data if the move succeeded and the cursor points to a valid row.

Resources