Defining Queries¶
A defining query is a read query that targets the OData service associated with the offline store and retrieves a subset of the endpoint data. You can define multiple defining queries for each endpoint.
Defining queries retrieve data from the OData service that is sent to the client, either during initialization of the offline store or during a download.
Defining queries are set up in both the application source code and in the application configuration files.
In Java, use the addDefiningQuery
method from the OfflineODataProvider
class with a name and a query.
In Swift, use the add()
method from OfflineODataProvider
class with an instance of the OfflineODataDefiningQuery
class constructed with a name, a query, and a flag for whether or not automatically retrieving streams.
The example below demonstrates how the defining queries retrieve all information for one event.
// Expand is needed to create a many-to-many relationship between Event and Feature
// since there is no referential constraint defined on the relationship.
// Data sharing should be enabled as all users see the same information
offlineODataProvider.addDefiningQuery(
new OfflineODataDefiningQuery("Events_10000",
"/Events?$filter=EventID eq 10000L&$expand=Features",
false));
// One-to-many relationship between Event and Session is built via
// referential constraint. Data sharing should be enabled
offlineODataProvider.addDefiningQuery(
new OfflineODataDefiningQuery("Sessions_10000",
"/Sessions?$filter=EventID eq 10000L",
false));
// Data sharing should be enabled
offlineODataProvider.addDefiningQuery(
new OfflineODataDefiningQuery("Tracks_10000",
"/Tracks?$filter=EventID eq 10000L",
false));
// User Specific data; data sharing should be off
offlineODataProvider.addDefiningQuery(
new OfflineODataDefiningQuery("UserSessionAgendas",
"/UserSessionAgendas?$filter=EventID eq 10000L",
false));
// Data sharing should be enabled.
offlineODataProvider.addDefiningQuery(
new OfflineODataDefiningQuery("Features",
"/Features",
false));
/// Expand is needed to create a many-to-many relationship between Event and Feature
/// since there is no referential constraint defined on the relationship.
/// Data sharing should be enabled as all users see the same information
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "Events_10000",
query: "/Events?$filter=EventID eq 10000L&$expand=Features",
automaticallyRetrievesStreams: false))
/// One-to-many relationship between Event and Session is built via referential constraint.
/// Data sharing should be enabled
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "Sessions_10000",
query: "/Sessions?$filter=EventID eq 10000L",
automaticallyRetrievesStreams: false))
/// Data sharing should be enabled
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "Tracks_10000",
query: "/Tracks?$filter=EventID eq 10000L",
automaticallyRetrievesStreams: false))
/// User Specific data; data sharing should be off
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "UserSessionAgendas",
query: "/UserSessionAgendas?$filter=EventID eq 10000L",
automaticallyRetrievesStreams: false))
/// Data sharing should be enabled
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "Features",
query: "/Features",
automaticallyRetrievesStreams: false))
In the application configuration file, reference each query using the same name as the one written in the source code (the first parameter to the OfflineODataDefiningQuery
constructor), as shown in the following example:
[defining_query]
name=Events_10000
is_shared_data=Y
download_interval=10
track_deltas=AUTO
delta_token_lifetime=36000
[defining_query]
name=UserSessionsAgendas
is_shared_data=N
In the example, the defining query Events_10000
is declared as shareable, which means that the event and related features can be accessed by all users.
Usually, you'll specify defining queries before opening the offline store for the first time, but they can also be added or removed afterwards if appropriate. You can use the getDefiningQueries
method from the OfflineODataProvider
class to fetch all existing defining queries.
Keep the following in mind when writing defining queries:
-
Currently, only defining queries where the resource path identifies an entity set or entity type instance (a single entity) are supported.
-
Shared defining query names must be unique, and must be identical on both the client and server. Otherwise, expected settings will not be applied to the correct defining query and the query will be using the default settings instead.
-
If you are using a mix of delta-enabled and non-delta-enabled defining queries, and you are using referential constraints to build relationships, the dependent entity in a relationship cannot be in a delta-enabled defining query if the principal entity is in a non-delta enabled-relationship. For example, say you have two defining queries,
Events
andSessions
(based on the sample metadata). Since there is a referential constraint between them and no expands are specified, the mobile services automatically uses the referential constraints to build relationships. The events are the principal entities and the sessions are the dependent entities. If theEvents
defining query is not delta-enabled, then theSessions
defining query must not be delta-enabled. However, if theEvents
defining query is delta-enabled, theSessions
defining query may or may not be delta-enabled. -
If you are not using deltas, you can use the same entity sets in more than one defining query, but you cannot perform a selective download of one of those defining queries without the others.
-
If you are using a mix of delta-enabled and non-delta enabled defining queries, you cannot use the same entity set in both a delta-enabled and a non-delta enabled defining query, either directly referenced in the resource path or through an
$expand
.
Removing Defining Queries¶
You can always remove a stream-defining query. For non-stream-defining queries, before opening the offline store, if a defining query is specified for the first time, then you can remove it immediately. After opening the offline store, by default configuration, neither existing defining queries, nor new specifying defining queries can be removed. To remove a defining query and its entities in the local store, you need to set allow_defining_query_removal
to Y. This will allow the server and local store to keep track of the mapping between defining queries and entities. If you do not need to remove any general defining queries, leave allow_defining_query_removal
as N for better performance. Turning allow_defining_query_removal
on or off will cause the server to reinitialize the offline store for the client during a download. This will take more time than the normal download, and if the client has any pending changes, they will not take place until pending changes are uploaded or deleted.
Using Defining Queries to Build Entity Relationships¶
To build relationships in your application, you can use $expand
in queries, referential constraints, or a combination of the two.
-
$expand
in queriesUse
$expand
in queries to build relationships between entity sets only if you are not tracking deltas, or if you are tracking deltas using the mobile services. You cannot use$expand
in queries if you are tracking deltas using the OData service. -
Referential constraints
If you are tracking deltas using the OData service and require entity relationships in the offline store, you cannot use
$expand
in queries but instead must have associations with referential constraints. Ensure that each defining query references a single entity set. The mobile services detects the associations with referential constraints and uses referential constraints to build the relationships between the entity sets selected in your defining queries.For example, the sample metadata document has an association between
Event
andSession
, calledEvent_Session_One_Many0
, which defines a referential constraint. If you specify two defining queries,/Events
and/Sessions
, the server uses the referential constraint defined in the associationEvent_Session_One_Many0
to build the relationship between theEvents
andSessions
entity sets in the offline store. -
Combining referential constraints and
$expand
in queriesWhen you use an
$expand
to build relationships between two top-level entity sets, an association set is implicitly referenced. For example,/Events?$expand=Sessions
implicitly references theEvent_Session_One_Many0Set
association set. The mobile services allows you to mix referential constraints and$expand
to build relationships.Consider the following example, which uses entity sets from the sample metadata:
~/Events?$expand=Sessions ~/Tracks
Relationships between events and sessions are computed using $expand
, and relationships between events and track are computed using referential constraints.
However, you cannot mix referential constraints and $expand
for the same implicitly referenced association set. In the example below, relationships between events in Canada and their sessions are built using $expand
, where the Event_Session_One_Many0Set
association set is implicitly referenced. Although there is an Event_Session_One_Many0
association with referential constraint between the Event
and Session
entity type, the referential constraint will not be used by the second and the third defining query to build other relationships, since the referential constraint also implicitly references the same association set. As a result, relationships between events in the US and their sessions are not built. Hence, only for events in Canada can one use the Sessions
navigation property to get associated sessions. For events in the US, one must use the EventID
property in a filter to get the associated sessions.
~/Events?$expand=Sessions&$filter=Country eq 'CAN'
~/Events?$filter=Country eq 'US'
~/Sessions
~/Tracks
Tip
This is not an exhaustive list of ways to build relationships. The choice of defining queries is highly dependent on the needs of the offline application.
The table below lists parameters that can be used to configure defining queries in an application configuration file.
Parameter | Value | Notes |
---|---|---|
name |
Valid String | (Required) Name of the defining query.endpoint data. |
is_shared_data |
N or Y | Whether the data is shared among different clients or users.
The default value is N. |
refresh_interval |
NNN | The interval time, in minutes, between downloads of the shared data. The default is 15 minutes. |
track_deltas |
AUTO or ALWAYS or NEVER | How to track OData deltas.
The default value is AUTO. |
delta_token_lifetime |
NNN | The time, in minutes, until the OData delta token expires. While a token is valid, only changed data is downloaded to the offline store. When the delta token expires, the entire data set is replaced. The default is |