Realm.io - Is it possible to find object by its subobject? - android

Doctor includes object Organization sub object:
#PrimaryKey
private int doctorId;
private FullName fullName;
private Age age;
private Organization organization;
private Position position;
private String category;
private String loyalty;
private List<Specialization> specializations;
private Contacts contacts;
Organization model has following parameters:
#PrimaryKey
private OrganizationId organizationId;
private String organizationName;
private String key;
// private Address address;
private String address;
private String phoneNumber;
Filling values like this:
Organization organization = realm.createObject(Organization.class); // Create a new object
OrganizationId organizationId = realm.createObject(OrganizationId.class);
organizationId.setAggregateId("1");
organization.setOrganizationId(organizationId);
organization.setOrganizationName("1-я Клиника Ташкентской Медицинской Академии");
organization.setAddress("Адрес: г. Ташкент, ул. Фароби, 2");
organization.setPhoneNumber("Тел.: (+99871) 214-51-01, 214-50-86, 214-50-43");
organization.setKey(organization.getOrganizationName().toLowerCase());
Doctor doctor = realm.createObject(Doctor.class);
//FULL NAME
FullName fullName = realm.createObject(FullName.class);
fullName.setFirstName("Joe");
fullName.setLastName("Richard");
fullName.setMiddleName("Brown");
doctor.setFullName(fullName);
//CONTACTS
Contacts contacts = realm.createObject(Contacts.class);
String[] phoneNumbers = {"+998903735173"};
contacts.setPhoneNumbers(phoneNumbers);
doctor.setContacts(contacts);
//ORGANIZATION
doctor.setOrganization(organization);
For example, this code returns all doctors with A category:
RealmQuery<Doctor> query = realm.where(Doctor.class);
RealmResults<Doctor> rDoctors = query.contains("category", "A").findAll();
return rDoctors;
My app logic like this: first of all, I open list of organizations. When User clicks on one organization. This will open list of doctors.
So my question is can I find doctors by its sub object(Organization)? Something like this
RealmQuery<Doctor> query = realm.where(Doctor.class);
RealmResults<Doctor> rDoctors = query.someMagicalMethod("organization", organization1).findAll();
return rDoctors;
PS. Yes, I can get it by going deep into organization. I was wondering does Realm.io makes search by object possible. Anyways I love Realm.io

I think it i possible. You can check it out here: http://realm.io/docs/java/latest/#link-queries
As per your case, you can try my following code:
RealmResults<Doctor> rDoctors = realm.where(Doctor.class)
.equalsTo("organization.organizationId", organizationId)
.findAll();
return rDoctors;
Please let me know if it works for you.

Related

Room: error: Not sure how to convert a Cursor to this method's return type (void)

I have this query set up to return all the records from these tables and display the information on a recyclerview in android. the DB is set up using the Room persistence library aka SQLITE.
#Query
("SELECT moodBeforetable.userId,
moodBeforetable.moodBefore,
moodBeforetable.cbtId,
cbtTable.automaticThought,
cbtTable.twistedThinkingPK,
cbtTable.challengeThought,
cbtTable.rationalThought,
cbtTable.date,
moodAfterTable.moodAfter,
twistedThinkingTable.twistedThinkingPK,
twistedThinkingTable.allOrNothing,
twistedThinkingTable.blamingOthers,
twistedThinkingTable.catastrophizing,
twistedThinkingTable.emotionalReasoning,
twistedThinkingTable.fortuneTelling,
twistedThinkingTable.labelling,
twistedThinkingTable.magnifyingTheNegative,
twistedThinkingTable.mindReading,
twistedThinkingTable.minimisingThePositive,
twistedThinkingTable.overGeneralisation,
twistedThinkingTable.selfBlaming,
twistedThinkingTable.shouldStatement
FROM moodBeforetable
JOIN cbtTable ON moodBeforetable.cbtId = cbtTable.cbtId
JOIN twistedThinkingTable ON cbtTable.cbtId = twistedThinkingTable.cbtId
JOIN moodAfterTable ON moodAfterTable.cbtId = cbtTable.cbtId
WHERE moodBeforetable.date >= datetime('now', '-1 year')
AND moodBeforetable.userId = :userId
ORDER BY :date DESC")
LiveData<List<MoodBeforeTable>> moodLogsAll (int userId, String date);
When I try to compile the app I get the following error:
The query returns some columns which are not used by com.example.feelingfit.persistence.tables.MoodBeforeTable.
You can use #ColumnInfo annotation on the fields to specify the mapping.
Could anyone help me debug this and find out why the app wont compile?
Problem is Room cannot map the result from your custom query to existing MoodBeforeTable. It is because your return type is List<MoodBeforeTable> but you have used joins using TwistedThinkingTable and MoodAfterTable and so on.
What you should do is create a new POJO like below:
public class MoodLogPojo() {
private int userId;
private String moodBefore;
zprivate int cbtId;
private String automaticThought;
private int twistedThinkingPK;
private String challengeThought;
private String rationalThought;
private String date;
private String moodAfter;
private int twistedThinkingPK;
private String allOrNothing;
private String blamingOthers;
private String catastrophizing;
private String emotionalReasoning;
private String fortuneTelling;
private String labelling;
private String magnifyingTheNegative;
private String mindReading;
private String minimisingThePositive;
private String overGeneralisation;
private String selfBlaming;
private String shouldStatement;
// generate getters and setters too
public void setSelfBlaming(Stirng selfBlming) {
this.selfBlming = selfBlming
}
public String getSelfBlaming() { return selfBlaming; }
// and so on ...
}
Then use this class as the return type like :
LiveData<List<MoodLogPojo>> moodLogsAll (int userId, String date);.
NOTE: Mind the MoodLogPojo class. Modify it accoring to the corresponding data types from each Entity.

Retrieve Values from a List within an Object

I'm trying to retrieve a value from an Object which sits within an ArrayList
within another Object.
The basic structure is:
+++++
Book Object -> List of Author Objects -> Author Object -> Author first name variable
+++++
And I would like to access the first name of the first Author for a given Book
+++++
I have created a "Book" Class which looks like the following:
public class Book {
private String mTitle;
private List<Author> mAuthors;
public Book(String title, List<Author> authors) {
this.mTitle = title;
this.mAuthors = authors;
}
public String getmTitle() {
return mTitle;
}
public List<Author> getmAuthors() {
return mAuthors;
}
}
This class also contains a list of Author-Objects:
public class Author {
private String mFirstName;
private String mLastName;
public Author(String firstName, String lastName) {
this.mFirstName = firstName;
this.mLastName = lastName;
}
public String getmFirstName() {
return mFirstName;
}
public String getmLastName() {
return mLastName;
}
}
I then create an the list of Author instances in the MainActivity:
ArrayList<Author> authors = new ArrayList<>();
authors.add(new Author("Hans", "Schwabe"));
And use this list when creating the book instance
Book buch = new Book("Säulen der Erde",authors);
When I then try to access the name of the first Author in the list I use the following code:
List<Author> authorArrayList = new ArrayList<Author>();
authorArrayList = buch.getmAuthors();
authorArrayList.get(1).getmFirstName();
And at this point my app keeps crashing.
**
Hence: What would be the right way to retrieve the first name of the
first author from the list?
**
Issue is that you have 1 author and you are trying to retrieve it from index 1. Index should be 0. Indexing in programming is starting from 0.
If you write
authorArrayList.get(0).getmFirstName();
It should work

Problems with ArrayAdapter

When I trying to get item index by below code.
Company company = getDefaultCompany();
companyArrayAdapter.getPosition(company);
I always to get result of -1. I don't understand what's wrong?
Because
companyArrayAdapter also have type Company.
private ArrayAdapter<Company> companyArrayAdapter;
Next you can see Company class declaration.
#DatabaseTable(tableName=Company.TABLE_NAME)
public class Company {
public static final String TABLE_NAME = "company";
#DatabaseField(id = true, columnName = "id")
private UUID id;
#DatabaseField(canBeNull=false)
private String name;
#DatabaseField
private String address;
#DatabaseField
private String phone;
#ForeignCollectionField(eager = false)
private ForeignCollection<Contract> contracts;
public Company(){
}
}
ArrayAdapter uses List.indexOf() method which and it can't compare your custom Company class objects and always returns "Not Found" index (-1).
So you should override getPosition() method int your custom adapter which extends ArrayAdapter:
#Override
public int getPosition(#Nullable Company company) {
/* here write logic of finding your company in companies list and retur index*/
return index;
}
P.S
If you had snippet of your custom adapter I would give you more detailed answer.
you can iterate through the loop of the list
var list=adapter.your_list
var toMatch=yourObject
for((index,elem) in list.withIndex()){
if(elem.someUniqueProperty == toMatch.someUniqueProperty){
var needed_index=index
}
}

Realm query with List

I'm using realm to store my data on Android. Awesome framework! Now the only problem I'm now having is:
I got a array list strings with id's of Countries in my database.
Now I retrieve my Drinks that contains a relationship to countries.
Is there a way that I could to do a query like this:
String [] ids;
realm.where(Drinks.class).equalsTo("country.id", ids);
Something like that?
Or do I really need to do a query to get me all drinks and then filter the list manually?
EDIT:
My classes:
public class Drinks extends RealmObject {
#PrimaryKey
private String id;
private String name;
private Country country;
}
public class Country extends RealmObject {
#PrimaryKey
private String id;
private String name;
}
What you want to do is possible with link queries in theory (searching for "country.id"), however link queries are slow. Also you'd need to concatenate a bunch of or() predicates together, and I would not risk that with a link query.
I would recommend using the following
public class Drinks extends RealmObject {
#PrimaryKey
private String id;
private String name;
private Country country;
#Index
private String countryId;
}
public class Country extends RealmObject {
#PrimaryKey
private String id;
private String name;
}
And when you set the Country in your class, you also set the countryId as country.getId().
Once you do that, you can construct such:
RealmQuery<Drinks> drinkQuery = realm.where(Drinks.class);
int i = 0;
for(String id : ids) {
if(i != 0) {
drinkQuery = drinkQuery.or();
}
drinkQuery = drinkQuery.equalTo("countryId", id);
i++;
}
return drinkQuery.findAll();
Since the Realm database has added RealmQuery.in() with the version 1.2.0
I suggest using something like this.
//Drinks
public class Drinks extends RealmObject {
#PrimaryKey
private String id;
private String name;
private String countryId;
//getter and setter methods
}
//Country
public class Country extends RealmObject {
#PrimaryKey
private String id;
private String name;
//getter and setter methods
}
The code to use inside activity/fragments to retrieve drink list
String[] countryIdArray = new String[] {"1","2","3"} //your string array
RealmQuery<Drinks> realmQuery = realm.where(Drinks.class)
.in("countryId",countryIdArray);
RealmResults<Drinks> drinkList = realmQuery.findAll();
In latest version of Realm 7+, you can use anyOf to match a field against a list of values.
anyOf("name", new String[]{"Jill", "William", "Trillian"})
in older versions, use in instead of anyOf and with kotlin use oneOf instead of in.
see this issue
To match a field against a list of values, use in. For example, to find the names “Jill,” “William,” or “Trillian”, you can use in("name", new String[]{"Jill", "William", "Trillian"}). The in predicate is applicable to strings, binary data, and numeric fields (including dates).
Doc.-> https://realm.io/docs/java/latest#queries

Manually updating a foreign key.

I am pretty much aware of the absence of foreign keys in Realm. But I encountered this issue. I receive data in a normalised way and I have to figure out how to properly persist the relations.
Example:
class User{
private int id;
private Email email;
}
class Email{
private int id;
private String address;
}
And I receive something like:
{user={id:1, emailId:1}}
How can I store this type of data in my existing realm object ?
You will have to parse the JSON yourself to setup the links. From your description it isn't clear if you User and Email is already in Realm, but if that is the case I would do something like this:
class User{
#PrimaryKey
private int id;
private Email email;
}
class Email{
#PrimaryKey
private int id;
private String address;
}
JSONObject json = new JSONObject("{id:1, emailId:1}");
realm.beginTransaction();
User user = realm.where(User.class).equalTo("id", json.getInt("id")).findFirst();
Email email = realm.where(Email.class).equalTo("id", json.getInt("emailId")).findFirst();
user.setEmail(email);
realm.commitTransaction();

Categories

Resources