Android Studio Room query to get a random row of db and saving the rows 2nd column in variable - android-studio

like the title mentions I want a Query that gets a random row of the existing database. After that I want to save the data which is in a specific column of that row in a variable for further purposes.
The query I have at the moment is as follows:
#Query("SELECT * FROM data_table ORDER BY RANDOM() LIMIT 1")
fun getRandomRow()
For now I am not sure if this query even works, but how would I go about writing my function to pass a specific column of that randomly selected row to a variable?
Ty for your advice, tips and/or solutions!

Your query is almost correct; however, you should specify a return type in the function signature. For example, if the records in the data_table table are mapped using a data class called DataEntry, then the query could read as shown below (note I've also added the suspend modifier so the query must be run using a coroutine):
#Query("SELECT * FROM data_table ORDER BY RANDOM() LIMIT 1")
suspend fun getRandomRow(): DataEntry?
If your application interacts with the database via a repository and view model (as described here: https://developer.android.com/topic/libraries/architecture/livedata) then the relevant methods would be along the lines of:
DataRepository
suspend fun findRandomEntry(): DataEntry? = dataEntryDao.getRandomRow()
DataViewModel
fun getRandomRecord() = viewModelScope.launch(Dispatchers.IO) {
val entry: DataEntry? = dataRepository.findRandomEntry()
entry?.let {
// You could assign a field of the DataEntry record to a variable here
// e.g. val name = entry.name
}
}
The above code uses the view model's coroutine scope to query the database via the repository and retrieve a random DataEntry record. Providing the returning DataEntry record is not null (i.e. your database contains data) then you could assign the fields of the DataEntry object to variables in the let block of the getRandomRecord() method.
As a final point, if it's only one field that you need, you could specify this in the database query. For example, imagine the DataEntry data class has a String field called name. You could retrieve this bit of information only and ignore the other fields by restructuring your query as follows:
#Query("SELECT name FROM data_table ORDER BY RANDOM() LIMIT 1")
suspend fun getRandomRow(): String?
If you go for the above option, remember to refactor your repository and view model to expect a String instead of a DataEntry object.

Related

Where is my error with my join in acumatica?

I want to get all the attributes from my "Actual Item Inventry" (From Stock Items Form) so i have:
PXResultset<CSAnswers> res = PXSelectJoin<CSAnswers,
InnerJoin<InventoryItem,
On<CSAnswers.refNoteID, Equal<Current<InventoryItem.noteID>>>
>
>.Select(new PXGraph());
But, this returns me 0 rows.
Where is my error?
UPDATED:
My loop is like this:
foreach (PXResult<CSAnswers> record in res)
{
CSAnswers answers = (CSAnswers)record;
string refnoteid = answers.RefNoteID.ToString();
string value = answers.Value;
}
... but i can not go inside foreach.
Sorry for the English.
You should use an initialized graph rather than just "new PXGraph()" for the select. This can be as simple as "this" or "Base" depending on where this code is located. There are times that it is ok to initialize a new graph instance, but also times that it is not ok. Not knowing the context of your code sample, let's assume that "this" and "Base" were insufficient, and you need to initialize a new graph. If you need to work within another graph instance, this is how your code would look.
InventoryItemMaint graph = PXGraph<InventoryItemMaint>.CreateInstance<InventoryItemMaint>();
PXResultset<CSAnswers> res = PXSelectJoin<CSAnswers,
InnerJoin<InventoryItem, On<CSAnswers.refNoteID, Equal<Current<InventoryItem.noteID>>>>>
.Select(graph);
foreach (PXResult<CSAnswers> record in res)
{
CSAnswers answers = (CSAnswers)record;
string refnoteid = answers.RefNoteID.ToString();
string value = answers.Value;
}
However, since you should be initializing graph within a graph or graph extension, you should be able to use:
.Select(this) // To use the current graph containing this logic
or
.Select(Base) // To use the base graph that is being extended if in a graph extension
Since you are referring to:
Current<InventoryItem.noteID>
...but are using "new PXGraph()" then there is no "InventoryItem" to be in the current data cache of the generic base object PXGraph. Hence the need to reference a fully defined graph.
Another syntax for specifying exactly what value you want to pass in is to use a parameter like this:
var myNoteIdVariable = ...
InventoryItemMaint graph = PXGraph<InventoryItemMaint>.CreateInstance<InventoryItemMaint>();
PXResultset<CSAnswers> res = PXSelectJoin<CSAnswers,
InnerJoin<InventoryItem, On<CSAnswers.refNoteID, Equal<Required<InventoryItem.noteID>>>>>
.Select(graph, myNoteIdVariable);
foreach (PXResult<CSAnswers> record in res)
{
CSAnswers answers = (CSAnswers)record;
string refnoteid = answers.RefNoteID.ToString();
string value = answers.Value;
}
Notice the "Required" and the extra value in the Select() section. A quick and easy way to check if you have a value for your parameter is to use PXTrace to write to the Trace that you can check after refreshing the screen and performing whatever action would execute your code:
PXTrace.WriteInformation(myNoteIdVariable.ToString());
...to see if there is a value in myNoteIdVariable to retrieve a result set. Place that outside of the foreach block or you will only get a value in the trace when you actually get records... which is not happening in your case.
If you want to get deep into what SQL statements are being generated and executed, look for Request Profiler in the menus and enable SQL logging while you run a test. Then come back to check the results. (Remember to disable the SQL logging when done or you can generate a lot of unnecessary data.)

Getting the values and column names of an INSERT object in the Java Cassandra Driver

I have a Insert object created as follows:
Insert insert = QueryBuilder.insertInto("demo", "users");
insert.value("name", name);
insert.value("sport", "test");
insert.value("years", 2);
insert.value("vegetarian", true);
Somewhere else in my code, I need to get the list of names and values associated with this INSERT object. When I debug the code I can see two "values" and "names" ArrayLists that contain the information I need, however they are private and I cannot access them.
While insert.getObject(0); gets the object from the values ArrayList, I can't map the value to a column name. Furthermore insert.getValues(ProtocolVersion.V4, CodecRegistry.DEFAULT_INSTANCE); seems to serialize the objects and put them into a ByteBuffer which is not desirable.
I recommend to use the PreparedStatement & BoundStatement instead of simple Insert. First, you can get better performance if you're inserting a lot of data. And second - you'll be able to get a list of variables defined in prepared statement, together with associated values

How to change the value of a certain core data across VCs/ How to know the index of a created CoreData?

I start from a TableView to create and store user information. This is how I create a core data entity called "Trials" in CreateTrialViewController. And I can successfully fetch it in the tableViewController after I come back to it.
let trial : Trials = NSEntityDescription.insertNewObjectForEntityForName("Trials", inManagedObjectContext: self.managedObjectContext!) as? Trials
{
trial.project = theProject.text
trial.record = theRecord.text
trial.notes = theNotes.text
trial.percentile = ""
managedObjectContext?.save(nil)
}
'
But after I create the Trial, I will get some calculated results from the accelerometer in the next measureViewController, and I want to save the result into 'trial.percentile'.
I have already converted the results into a string, so I can write it directly into the core data attribute. But how can I know the index of this core data that I just created? Should I try to use 'segue' to transmit?
In the tableView it fetches in a ascending sequence of date, so the index is clear. But here in the following VC how to know the index? I still couldn't figure this out by myself... The sequence of my VCs is: TableViewController -> CreateTrialViewController -> MeasureViewController -> TableViewController (start again)
Your table view controller can keep a reference to the newly created object. Insert the object (trial) in the original view controller and pass it on to the next controller in prepareForSegue. So the CreateTrialViewController starts out with a blank object to which the table view controller has a reference.
You configure the object, go to the measure controller, modify the object. When done, you pop these two controllers from the navigation stack and are back in your original table view controller.
Because your table view controller has the NSFetchedResultsControllerDelegate enabled, it will update itself to reflect the data of your new object. Remember, you still have a reference to this object, so you can just use indexPathForObject to retrieve its index path.

Pass table name a parameter to the Data Context method using LINQ to SQL in C#

I have created a method which delete data from the database by joining a db column with a csv file, I have a list of tables in a Data Context which I need to iterate, i means that I need to change the table name by passing it as parameter to the method.
Basically I need to use this method for all the table present in the Data Context
Current hard coded Table name in a GetTable method: dw_Job
DataContext Object: job
Here is my code
var query = from line in File.ReadAllLines(file, Encoding.GetEncoding(1252))
//let jobrecord = line.Split(',')
join j in job.GetTable<dw_Job>() on
Convert.ToInt32(line.Split(',').GetValue(factColPos))
equals j.JobID
select j;
foreach (var deletejob in query)
{
Console.WriteLine(deletejob);
job.dw_Jobs.DeleteOnSubmit(deletejob);
}
job.SubmitChanges();
I can able to provide if you need any further details of my code. Please correct me on this
Thanks in advance

Subsonic 3: Strongly typed return value for stored procedures that return mixed results from different tables

Say I have a stored procedure that returns dataSet from 2 different tables. Example:
SELECT Customers.FirstName, Customers.LastName, SUM(Sales.SaleAmount) AS SalesPerCustomer
FROM Customers LEFT JOIN Sales
ON Customers.CustomerID = Sales.CustomerID
GROUP BY Customers.FirstName, Customers.LastName
Is there any way to get a strongly typed list as a result from this stored procedure ? Something like this:
StoredProcedure sp = myDevDB.GetCustomerSales();
List<MyCustomType> resultSet = sp.ExecuteTypedList<MyCustomType>();
How and where do I define the MyCustomType class ? How do I map its properties to the actual table columns ?
thanks,mehul
I solved it by creating a class (in the same place as all my other classes, but I didn't extend IActiveRecord, it's just a vanilla class).
Make sure the property names have exactly the same name and data type as the ones in the procedure, then call db.sproc(params).ExecuteTypedList().AsQueryable(); and it populated fine.

Resources