realm.h 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831
  1. /*
  2. FIXME: License, since this header may be distributed independently from
  3. other headers.
  4. */
  5. #ifndef REALM_H
  6. #define REALM_H
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include <stdbool.h>
  10. #if defined(_WIN32) || defined(__CYGWIN__)
  11. #if defined(Realm_EXPORTS)
  12. // Exporting Win32 symbols
  13. #define RLM_EXPORT __declspec(dllexport)
  14. #else
  15. // Importing Win32 symbols. Note: Clients linking statically should define
  16. // RLM_NO_DLLIMPORT.
  17. #if !defined(RLM_NO_DLLIMPORT)
  18. #define RLM_EXPORT __declspec(dllimport)
  19. #else
  20. #define RLM_EXPORT
  21. #endif // RLM_NO_DLLIMPORT
  22. #endif // Realm_EXPORTS
  23. #else
  24. // Not Win32
  25. #define RLM_EXPORT __attribute__((visibility("default")))
  26. #endif
  27. #ifdef __cplusplus
  28. #define RLM_API extern "C" RLM_EXPORT
  29. #else
  30. #define RLM_API RLM_EXPORT
  31. #endif // __cplusplus
  32. typedef struct shared_realm realm_t;
  33. typedef struct realm_schema realm_schema_t;
  34. typedef struct realm_scheduler realm_scheduler_t;
  35. typedef struct realm_thread_safe_reference realm_thread_safe_reference_t;
  36. typedef void (*realm_free_userdata_func_t)(void*);
  37. typedef void* (*realm_clone_userdata_func_t)(const void*);
  38. /* Accessor types */
  39. typedef struct realm_object realm_object_t;
  40. typedef struct realm_list realm_list_t;
  41. typedef struct realm_set realm_set_t;
  42. typedef struct realm_dictionary realm_dictionary_t;
  43. /* Query types */
  44. typedef struct realm_query realm_query_t;
  45. typedef struct realm_results realm_results_t;
  46. /* Config types */
  47. typedef struct realm_config realm_config_t;
  48. typedef struct realm_sync_config realm_sync_config_t;
  49. typedef bool (*realm_migration_func_t)(void* userdata, realm_t* old_realm, realm_t* new_realm,
  50. const realm_schema_t* schema);
  51. typedef bool (*realm_data_initialization_func_t)(void* userdata, realm_t* realm);
  52. typedef bool (*realm_should_compact_on_launch_func_t)(void* userdata, uint64_t total_bytes, uint64_t used_bytes);
  53. typedef enum realm_schema_mode {
  54. RLM_SCHEMA_MODE_AUTOMATIC,
  55. RLM_SCHEMA_MODE_IMMUTABLE,
  56. RLM_SCHEMA_MODE_READ_ONLY_ALTERNATIVE,
  57. RLM_SCHEMA_MODE_RESET_FILE,
  58. RLM_SCHEMA_MODE_ADDITIVE_DISCOVERED,
  59. RLM_SCHEMA_MODE_ADDITIVE_EXPLICIT,
  60. RLM_SCHEMA_MODE_MANUAL,
  61. } realm_schema_mode_e;
  62. /* Key types */
  63. typedef uint32_t realm_class_key_t;
  64. typedef int64_t realm_property_key_t;
  65. typedef int64_t realm_object_key_t;
  66. typedef uint64_t realm_version_t;
  67. static const realm_class_key_t RLM_INVALID_CLASS_KEY = ((uint32_t)-1) >> 1;
  68. static const realm_property_key_t RLM_INVALID_PROPERTY_KEY = -1;
  69. static const realm_object_key_t RLM_INVALID_OBJECT_KEY = -1;
  70. /* Value types */
  71. typedef enum realm_value_type {
  72. RLM_TYPE_NULL,
  73. RLM_TYPE_INT,
  74. RLM_TYPE_BOOL,
  75. RLM_TYPE_STRING,
  76. RLM_TYPE_BINARY,
  77. RLM_TYPE_TIMESTAMP,
  78. RLM_TYPE_FLOAT,
  79. RLM_TYPE_DOUBLE,
  80. RLM_TYPE_DECIMAL128,
  81. RLM_TYPE_OBJECT_ID,
  82. RLM_TYPE_LINK,
  83. RLM_TYPE_UUID,
  84. } realm_value_type_e;
  85. typedef enum realm_schema_validation_mode {
  86. RLM_SCHEMA_VALIDATION_BASIC = 0,
  87. RLM_SCHEMA_VALIDATION_SYNC = 1,
  88. RLM_SCHEMA_VALIDATION_REJECT_EMBEDDED_ORPHANS = 2
  89. } realm_schema_validation_mode_e;
  90. typedef struct realm_string {
  91. const char* data;
  92. size_t size;
  93. } realm_string_t;
  94. typedef struct realm_binary {
  95. const uint8_t* data;
  96. size_t size;
  97. } realm_binary_t;
  98. typedef struct realm_timestamp {
  99. int64_t seconds;
  100. int32_t nanoseconds;
  101. } realm_timestamp_t;
  102. typedef struct realm_decimal128 {
  103. uint64_t w[2];
  104. } realm_decimal128_t;
  105. typedef struct realm_link {
  106. realm_class_key_t target_table;
  107. realm_object_key_t target;
  108. } realm_link_t;
  109. typedef struct realm_object_id {
  110. uint8_t bytes[12];
  111. } realm_object_id_t;
  112. typedef struct realm_uuid {
  113. uint8_t bytes[16];
  114. } realm_uuid_t;
  115. typedef struct realm_value {
  116. union {
  117. int64_t integer;
  118. bool boolean;
  119. realm_string_t string;
  120. realm_binary_t binary;
  121. realm_timestamp_t timestamp;
  122. float fnum;
  123. double dnum;
  124. realm_decimal128_t decimal128;
  125. realm_object_id_t object_id;
  126. realm_uuid_t uuid;
  127. realm_link_t link;
  128. char data[16];
  129. };
  130. realm_value_type_e type;
  131. } realm_value_t;
  132. typedef struct realm_version_id {
  133. uint64_t version;
  134. uint64_t index;
  135. } realm_version_id_t;
  136. /* Error types */
  137. typedef struct realm_async_error realm_async_error_t;
  138. typedef enum realm_errno {
  139. RLM_ERR_NONE = 0,
  140. RLM_ERR_UNKNOWN,
  141. RLM_ERR_OTHER_EXCEPTION,
  142. RLM_ERR_OUT_OF_MEMORY,
  143. RLM_ERR_NOT_CLONABLE,
  144. RLM_ERR_NOT_IN_A_TRANSACTION,
  145. RLM_ERR_WRONG_THREAD,
  146. RLM_ERR_INVALIDATED_OBJECT,
  147. RLM_ERR_INVALID_PROPERTY,
  148. RLM_ERR_MISSING_PROPERTY_VALUE,
  149. RLM_ERR_PROPERTY_TYPE_MISMATCH,
  150. RLM_ERR_MISSING_PRIMARY_KEY,
  151. RLM_ERR_UNEXPECTED_PRIMARY_KEY,
  152. RLM_ERR_WRONG_PRIMARY_KEY_TYPE,
  153. RLM_ERR_MODIFY_PRIMARY_KEY,
  154. RLM_ERR_READ_ONLY_PROPERTY,
  155. RLM_ERR_PROPERTY_NOT_NULLABLE,
  156. RLM_ERR_INVALID_ARGUMENT,
  157. RLM_ERR_LOGIC,
  158. RLM_ERR_NO_SUCH_TABLE,
  159. RLM_ERR_NO_SUCH_OBJECT,
  160. RLM_ERR_CROSS_TABLE_LINK_TARGET,
  161. RLM_ERR_UNSUPPORTED_FILE_FORMAT_VERSION,
  162. RLM_ERR_MULTIPLE_SYNC_AGENTS,
  163. RLM_ERR_ADDRESS_SPACE_EXHAUSTED,
  164. RLM_ERR_MAXIMUM_FILE_SIZE_EXCEEDED,
  165. RLM_ERR_OUT_OF_DISK_SPACE,
  166. RLM_ERR_KEY_NOT_FOUND,
  167. RLM_ERR_COLUMN_NOT_FOUND,
  168. RLM_ERR_COLUMN_ALREADY_EXISTS,
  169. RLM_ERR_KEY_ALREADY_USED,
  170. RLM_ERR_SERIALIZATION_ERROR,
  171. RLM_ERR_INVALID_PATH_ERROR,
  172. RLM_ERR_DUPLICATE_PRIMARY_KEY_VALUE,
  173. RLM_ERR_INDEX_OUT_OF_BOUNDS,
  174. RLM_ERR_INVALID_QUERY_STRING,
  175. RLM_ERR_INVALID_QUERY,
  176. RLM_ERR_CALLBACK = 1000000, /**< A user-provided callback failed. */
  177. } realm_errno_e;
  178. typedef enum realm_logic_error_kind {
  179. RLM_LOGIC_ERR_NONE = 0,
  180. RLM_LOGIC_ERR_STRING_TOO_BIG,
  181. // ...
  182. } realm_logic_error_kind_e;
  183. typedef struct realm_error {
  184. realm_errno_e error;
  185. const char* message;
  186. union {
  187. int code;
  188. realm_logic_error_kind_e logic_error_kind;
  189. } kind;
  190. } realm_error_t;
  191. /* Schema types */
  192. typedef enum realm_column_attr {
  193. // Values matching `realm::ColumnAttr`.
  194. RLM_COLUMN_ATTR_NONE = 0,
  195. RLM_COLUMN_ATTR_INDEXED = 1,
  196. RLM_COLUMN_ATTR_UNIQUE = 2,
  197. RLM_COLUMN_ATTR_RESERVED = 4,
  198. RLM_COLUMN_ATTR_STRONG_LINKS = 8,
  199. RLM_COLUMN_ATTR_NULLABLE = 16,
  200. RLM_COLUMN_ATTR_LIST = 32,
  201. RLM_COLUMN_ATTR_DICTIONARY = 64,
  202. RLM_COLUMN_ATTR_COLLECTION = 64 + 32,
  203. } realm_column_attr_e;
  204. typedef enum realm_property_type {
  205. // Values matching `realm::ColumnType`.
  206. RLM_PROPERTY_TYPE_INT = 0,
  207. RLM_PROPERTY_TYPE_BOOL = 1,
  208. RLM_PROPERTY_TYPE_STRING = 2,
  209. RLM_PROPERTY_TYPE_BINARY = 4,
  210. RLM_PROPERTY_TYPE_MIXED = 6,
  211. RLM_PROPERTY_TYPE_TIMESTAMP = 8,
  212. RLM_PROPERTY_TYPE_FLOAT = 9,
  213. RLM_PROPERTY_TYPE_DOUBLE = 10,
  214. RLM_PROPERTY_TYPE_DECIMAL128 = 11,
  215. RLM_PROPERTY_TYPE_OBJECT = 12,
  216. RLM_PROPERTY_TYPE_LINKING_OBJECTS = 14,
  217. RLM_PROPERTY_TYPE_OBJECT_ID = 15,
  218. RLM_PROPERTY_TYPE_UUID = 17,
  219. } realm_property_type_e;
  220. typedef enum realm_collection_type {
  221. RLM_COLLECTION_TYPE_NONE = 0,
  222. RLM_COLLECTION_TYPE_LIST = 1,
  223. RLM_COLLECTION_TYPE_SET = 2,
  224. RLM_COLLECTION_TYPE_DICTIONARY = 4,
  225. } realm_collection_type_e;
  226. typedef struct realm_property_info {
  227. const char* name;
  228. const char* public_name;
  229. realm_property_type_e type;
  230. realm_collection_type_e collection_type;
  231. const char* link_target;
  232. const char* link_origin_property_name;
  233. realm_property_key_t key;
  234. int flags;
  235. } realm_property_info_t;
  236. typedef struct realm_class_info {
  237. const char* name;
  238. const char* primary_key;
  239. size_t num_properties;
  240. size_t num_computed_properties;
  241. realm_class_key_t key;
  242. int flags;
  243. } realm_class_info_t;
  244. typedef enum realm_class_flags {
  245. RLM_CLASS_NORMAL = 0,
  246. RLM_CLASS_EMBEDDED = 1,
  247. } realm_class_flags_e;
  248. typedef enum realm_property_flags {
  249. RLM_PROPERTY_NORMAL = 0,
  250. RLM_PROPERTY_NULLABLE = 1,
  251. RLM_PROPERTY_PRIMARY_KEY = 2,
  252. RLM_PROPERTY_INDEXED = 4,
  253. } realm_property_flags_e;
  254. /* Notification types */
  255. typedef struct realm_notification_token realm_notification_token_t;
  256. typedef struct realm_object_changes realm_object_changes_t;
  257. typedef struct realm_collection_changes realm_collection_changes_t;
  258. typedef void (*realm_on_object_change_func_t)(void* userdata, const realm_object_changes_t*);
  259. typedef void (*realm_on_collection_change_func_t)(void* userdata, const realm_collection_changes_t*);
  260. typedef void (*realm_callback_error_func_t)(void* userdata, const realm_async_error_t*);
  261. /* Scheduler types */
  262. typedef void (*realm_scheduler_notify_func_t)(void* userdata);
  263. typedef bool (*realm_scheduler_is_on_thread_func_t)(void* userdata);
  264. typedef bool (*realm_scheduler_is_same_as_func_t)(const void* userdata1, const void* userdata2);
  265. typedef bool (*realm_scheduler_can_deliver_notifications_func_t)(void* userdata);
  266. typedef void (*realm_scheduler_set_notify_callback_func_t)(void* userdata, void* callback_userdata,
  267. realm_free_userdata_func_t, realm_scheduler_notify_func_t);
  268. typedef realm_scheduler_t* (*realm_scheduler_default_factory_func_t)(void* userdata);
  269. /* Sync types */
  270. typedef void (*realm_sync_upload_completion_func_t)(void* userdata, realm_async_error_t*);
  271. typedef void (*realm_sync_download_completion_func_t)(void* userdata, realm_async_error_t*);
  272. typedef void (*realm_sync_connection_state_changed_func_t)(void* userdata, int, int);
  273. typedef void (*realm_sync_session_state_changed_func_t)(void* userdata, int, int);
  274. typedef void (*realm_sync_progress_func_t)(void* userdata, size_t transferred, size_t total);
  275. /**
  276. * Get the VersionID of the current transaction.
  277. *
  278. * @param out_found True if version information is available. This requires an available Read or Write transaction.
  279. * @param out_version The version of the current transaction. If `out_found` returns False, this returns (0,0).
  280. * @return True if no exception occurred.
  281. */
  282. RLM_API bool realm_get_version_id(const realm_t*, bool* out_found, realm_version_id_t* out_version);
  283. /**
  284. * Get a string representing the version number of the Realm library.
  285. *
  286. * @return A null-terminated string.
  287. */
  288. RLM_API const char* realm_get_library_version(void);
  289. /**
  290. * Get individual components of the version number of the Realm library.
  291. *
  292. * @param out_major The major version number (X.0.0).
  293. * @param out_minor The minor version number (0.X.0).
  294. * @param out_patch The patch version number (0.0.X).
  295. * @param out_extra The extra version string (0.0.0-X).
  296. */
  297. RLM_API void realm_get_library_version_numbers(int* out_major, int* out_minor, int* out_patch,
  298. const char** out_extra);
  299. /**
  300. * Get the last error that happened on this thread.
  301. *
  302. * Errors are thread-local. Getting the error must happen on the same thread as
  303. * the call that caused the error to occur. The error is specific to the current
  304. * thread, and not the Realm instance for which the error occurred.
  305. *
  306. * Note: The error message in @a err will only be safe to use until the next API
  307. * call is made on the current thread.
  308. *
  309. * Note: The error is not cleared by subsequent successful calls to this
  310. * function, but it will be overwritten by subsequent failing calls to
  311. * other library functions.
  312. *
  313. * Note: Calling this function does not clear the current last error.
  314. *
  315. * This function does not allocate any memory.
  316. *
  317. * @param err A pointer to a `realm_error_t` struct that will be populated with
  318. * information about the last error, if there is one. May be NULL.
  319. * @return True if an error occurred.
  320. */
  321. RLM_API bool realm_get_last_error(realm_error_t* err);
  322. /**
  323. * Get information about an async error, potentially coming from another thread.
  324. *
  325. * This function does not allocate any memory.
  326. *
  327. * @param err A pointer to a `realm_error_t` struct that will be populated with
  328. * information about the error. May not be NULL.
  329. * @see realm_get_last_error()
  330. */
  331. RLM_API void realm_get_async_error(const realm_async_error_t* err, realm_error_t* out_err);
  332. /**
  333. * Convert the last error to `realm_async_error_t`, which can safely be passed
  334. * between threads.
  335. *
  336. * Note: This function does not clear the last error.
  337. *
  338. * @return A non-null pointer if there was an error on this thread.
  339. * @see realm_get_last_error()
  340. * @see realm_get_async_error()
  341. * @see realm_clear_last_error()
  342. */
  343. RLM_API realm_async_error_t* realm_get_last_error_as_async_error(void);
  344. #if defined(__cplusplus)
  345. /**
  346. * Rethrow the last exception.
  347. *
  348. * Note: This function does not have C linkage, because throwing across language
  349. * boundaries is undefined behavior. When called from C code, this should result
  350. * in a linker error. When called from C++, `std::rethrow_exception` will be
  351. * called to propagate the exception unchanged.
  352. */
  353. RLM_EXPORT void realm_rethrow_last_error(void);
  354. /**
  355. * Invoke a function that may throw an exception, and report that exception as
  356. * part of the C API error handling mechanism.
  357. *
  358. * This is used to test translation of exceptions to error codes.
  359. *
  360. * @return True if no exception was thrown.
  361. */
  362. RLM_EXPORT bool realm_wrap_exceptions(void (*)()) noexcept;
  363. #endif // __cplusplus
  364. /**
  365. * Clear the last error on the calling thread.
  366. *
  367. * Use this if the system has recovered from an error, e.g. by closing the
  368. * offending Realm and reopening it, freeing up resources, or similar.
  369. *
  370. * @return True if an error was cleared.
  371. */
  372. RLM_API bool realm_clear_last_error(void);
  373. /**
  374. * Free any Realm C Wrapper object.
  375. *
  376. * Note: Any pointer returned from a library function is owned by the caller.
  377. * The caller is responsible for calling `realm_release()`. The only
  378. * exception from this is C++ bridge functions that return `void*`, with
  379. * the prefix `_realm`.
  380. *
  381. * Note: C++ destructors are typically `noexcept`, so it is likely that an
  382. * exception will crash the process.
  383. *
  384. * @param ptr A pointer to a Realm C Wrapper object. May be NULL.
  385. */
  386. RLM_API void realm_release(void* ptr);
  387. /**
  388. * Clone a Realm C Wrapper object.
  389. *
  390. * If the object is not clonable, this function fails with RLM_ERR_NOT_CLONABLE.
  391. *
  392. * @return A pointer to an object of the same type as the input, or NULL if
  393. * cloning failed.
  394. */
  395. RLM_API void* realm_clone(const void*);
  396. /**
  397. * Return true if two API objects refer to the same underlying data. Objects
  398. * with different types are never equal.
  399. *
  400. * Note: This function cannot be used with types that have value semantics, only
  401. * opaque types that have object semantics.
  402. *
  403. * - `realm_t` objects are identical if they represent the same instance (not
  404. * just if they represent the same file).
  405. * - `realm_schema_t` objects are equal if the represented schemas are equal.
  406. * - `realm_config_t` objects are equal if the configurations are equal.
  407. * - `realm_object_t` objects are identical if they belong to the same realm
  408. * and class, and have the same object key.
  409. * - `realm_list_t` and other collection objects are identical if they come
  410. * from the same object and property.
  411. * - `realm_query_t` objects are never equal.
  412. * - `realm_scheduler_t` objects are equal if they represent the same
  413. * scheduler.
  414. * - Query descriptor objects are equal if they represent equivalent
  415. * descriptors.
  416. * - `realm_async_error_t` objects are equal if they represent the same
  417. * exception instance.
  418. *
  419. * This function cannot fail.
  420. */
  421. RLM_API bool realm_equals(const void*, const void*);
  422. /**
  423. * True if a Realm C Wrapper object is "frozen" (immutable).
  424. *
  425. * Objects, collections, and results can be frozen. For all other types, this
  426. * function always returns false.
  427. */
  428. RLM_API bool realm_is_frozen(const void*);
  429. /**
  430. * Get a thread-safe reference representing the same underlying object as some
  431. * API object.
  432. *
  433. * The thread safe reference can be passed to a different thread and resolved
  434. * against a different `realm_t` instance, which succeeds if the underlying
  435. * object still exists.
  436. *
  437. * The following types can produce thread safe references:
  438. *
  439. * - `realm_object_t`
  440. * - `realm_results_t`
  441. * - `realm_list_t`
  442. * - `realm_t`
  443. *
  444. * This does not assume ownership of the object, except for `realm_t`, where the
  445. * instance is transferred by value, and must be transferred back to the current
  446. * thread to be used. Note that the `realm_thread_safe_reference_t` object must
  447. * still be destroyed after having been converted into a `realm_t` object.
  448. *
  449. * @return A non-null pointer if no exception occurred.
  450. */
  451. RLM_API realm_thread_safe_reference_t* realm_create_thread_safe_reference(const void*);
  452. /**
  453. * Allocate a new configuration with default options.
  454. */
  455. RLM_API realm_config_t* realm_config_new(void);
  456. /**
  457. * Get the path of the realm being opened.
  458. *
  459. * This function cannot fail.
  460. */
  461. RLM_API const char* realm_config_get_path(const realm_config_t*);
  462. /**
  463. * Set the path of the realm being opened.
  464. *
  465. * This function aborts when out of memory, but otherwise cannot fail.
  466. */
  467. RLM_API void realm_config_set_path(realm_config_t*, const char* path);
  468. /**
  469. * Get the encryption key for the realm.
  470. *
  471. * The output buffer must be at least 64 bytes.
  472. *
  473. * @returns The length of the encryption key (0 or 64)
  474. */
  475. RLM_API size_t realm_config_get_encryption_key(const realm_config_t*, uint8_t* out_key);
  476. /**
  477. * Set the encryption key for the realm.
  478. *
  479. * The key must be either 64 bytes long or have length zero (in which case
  480. * encryption is disabled).
  481. *
  482. * This function may fail if the encryption key has the wrong length.
  483. */
  484. RLM_API bool realm_config_set_encryption_key(realm_config_t*, const uint8_t* key, size_t key_size);
  485. /**
  486. * Get the schema for this realm.
  487. *
  488. * Note: The caller obtains ownership of the returned value, and must manually
  489. * free it by calling `realm_release()`.
  490. *
  491. * @return A schema object, or NULL if the schema is not set (empty).
  492. */
  493. RLM_API realm_schema_t* realm_config_get_schema(const realm_config_t*);
  494. /**
  495. * Set the schema object for this realm.
  496. *
  497. * This does not take ownership of the schema object, and it should be released
  498. * afterwards.
  499. *
  500. * This function aborts when out of memory, but otherwise cannot fail.
  501. *
  502. * @param schema The schema object. May be NULL, which means an empty schema.
  503. */
  504. RLM_API void realm_config_set_schema(realm_config_t*, const realm_schema_t* schema);
  505. /**
  506. * Get the schema version of the schema.
  507. *
  508. * This function cannot fail.
  509. */
  510. RLM_API uint64_t realm_config_get_schema_version(const realm_config_t*);
  511. /**
  512. * Set the schema version of the schema.
  513. *
  514. * This function cannot fail.
  515. */
  516. RLM_API void realm_config_set_schema_version(realm_config_t*, uint64_t version);
  517. /**
  518. * Get the schema mode.
  519. *
  520. * This function cannot fail.
  521. */
  522. RLM_API realm_schema_mode_e realm_config_get_schema_mode(const realm_config_t*);
  523. /**
  524. * Set the schema mode.
  525. *
  526. * This function cannot fail.
  527. */
  528. RLM_API void realm_config_set_schema_mode(realm_config_t*, realm_schema_mode_e);
  529. /**
  530. * Set the migration callback.
  531. *
  532. * The migration function is called during a migration for schema modes
  533. * `RLM_SCHEMA_MODE_AUTOMATIC` and `RLM_SCHEMA_MODE_MANUAL`. The callback is
  534. * invoked with a realm instance before the migration and the realm instance
  535. * that is currently performing the migration.
  536. *
  537. * This function cannot fail.
  538. */
  539. RLM_API void realm_config_set_migration_function(realm_config_t*, realm_migration_func_t, void* userdata);
  540. /**
  541. * Set the data initialization function.
  542. *
  543. * The callback is invoked the first time the schema is created, such that the
  544. * user can perform one-time initialization of the data in the realm.
  545. *
  546. * The realm instance passed to the callback is in a write transaction.
  547. *
  548. * This function cannot fail.
  549. */
  550. RLM_API void realm_config_set_data_initialization_function(realm_config_t*, realm_data_initialization_func_t,
  551. void* userdata);
  552. /**
  553. * Set the should-compact-on-launch callback.
  554. *
  555. * The callback is invoked the first time a realm file is opened in this process
  556. * to decide whether the realm file should be compacted.
  557. *
  558. * Note: If another process has the realm file open, it will not be compacted.
  559. *
  560. * This function cannot fail.
  561. */
  562. RLM_API void realm_config_set_should_compact_on_launch_function(realm_config_t*,
  563. realm_should_compact_on_launch_func_t,
  564. void* userdata);
  565. /**
  566. * True if file format upgrades on open are disabled.
  567. *
  568. * This function cannot fail.
  569. */
  570. RLM_API bool realm_config_get_disable_format_upgrade(const realm_config_t*);
  571. /**
  572. * Disable file format upgrade on open (default: false).
  573. *
  574. * If a migration is needed to open the realm file with the provided schema, an
  575. * error is thrown rather than automatically performing the migration.
  576. *
  577. * This function cannot fail.
  578. */
  579. RLM_API void realm_config_set_disable_format_upgrade(realm_config_t*, bool);
  580. /**
  581. * True if automatic change notifications should be generated.
  582. *
  583. * This function cannot fail.
  584. */
  585. RLM_API bool realm_config_get_automatic_change_notifications(const realm_config_t*);
  586. /**
  587. * Automatically generated change notifications (default: true).
  588. *
  589. * This function cannot fail.
  590. */
  591. RLM_API void realm_config_set_automatic_change_notifications(realm_config_t*, bool);
  592. /**
  593. * The scheduler which this realm should be bound to (default: NULL).
  594. *
  595. * If NULL, the realm will be bound to the default scheduler for the current thread.
  596. *
  597. * This function aborts when out of memory, but otherwise cannot fail.
  598. */
  599. RLM_API void realm_config_set_scheduler(realm_config_t*, const realm_scheduler_t*);
  600. /**
  601. * Sync configuration for this realm (default: NULL).
  602. *
  603. * This function aborts when out of memory, but otherwise cannot fail.
  604. */
  605. RLM_API void realm_config_set_sync_config(realm_config_t*, realm_sync_config_t*);
  606. /**
  607. * Get whether the realm file should be forcibly initialized as a synchronized.
  608. *
  609. * This function cannot fail.
  610. */
  611. RLM_API bool realm_config_get_force_sync_history(const realm_config_t*);
  612. /**
  613. * Force the realm file to be initialized as a synchronized realm, even if no
  614. * sync config is provided (default: false).
  615. *
  616. * This function cannot fail.
  617. */
  618. RLM_API void realm_config_set_force_sync_history(realm_config_t*, bool);
  619. /**
  620. * Set the audit interface for the realm (unimplemented).
  621. */
  622. RLM_API bool realm_config_set_audit_factory(realm_config_t*, void*);
  623. /**
  624. * Get maximum number of active versions in the realm file allowed before an
  625. * exception is thrown.
  626. *
  627. * This function cannot fail.
  628. */
  629. RLM_API uint64_t realm_config_get_max_number_of_active_versions(const realm_config_t*);
  630. /**
  631. * Set maximum number of active versions in the realm file allowed before an
  632. * exception is thrown (default: UINT64_MAX).
  633. *
  634. * This function cannot fail.
  635. */
  636. RLM_API void realm_config_set_max_number_of_active_versions(realm_config_t*, uint64_t);
  637. /**
  638. * Create a custom scheduler object from callback functions.
  639. *
  640. * @param userdata Pointer passed to all callbacks.
  641. * @param notify Function to trigger a call to the registered callback on the
  642. * scheduler's event loop. This function must be thread-safe, or
  643. * NULL, in which case the scheduler is considered unable to
  644. * deliver notifications.
  645. * @param is_on_thread Function to return true if called from the same thread as
  646. * the scheduler. This function must be thread-safe.
  647. * @param can_deliver_notifications Function to return true if the scheduler can
  648. * support `notify()`. This function does not
  649. * need to be thread-safe.
  650. * @param set_notify_callback Function to accept a callback that will be invoked
  651. * by `notify()` on the scheduler's event loop. This
  652. * function does not need to be thread-safe.
  653. */
  654. RLM_API realm_scheduler_t*
  655. realm_scheduler_new(void* userdata, realm_free_userdata_func_t, realm_scheduler_notify_func_t notify,
  656. realm_scheduler_is_on_thread_func_t is_on_thread, realm_scheduler_is_same_as_func_t is_same_as,
  657. realm_scheduler_can_deliver_notifications_func_t can_deliver_notifications,
  658. realm_scheduler_set_notify_callback_func_t set_notify_callback);
  659. /**
  660. * Create an instance of the default scheduler for the current platform,
  661. * normally confined to the calling thread.
  662. */
  663. RLM_API realm_scheduler_t* realm_scheduler_make_default(void);
  664. /**
  665. * Get the scheduler used by frozen realms. This scheduler does not support
  666. * notifications, and does not perform any thread checking.
  667. *
  668. * This function is thread-safe, and cannot fail.
  669. */
  670. RLM_API const realm_scheduler_t* realm_scheduler_get_frozen(void);
  671. /**
  672. * Returns true if there is a default scheduler implementation for the current
  673. * platform, or one has been set with `realm_scheduler_set_default_factory()`.
  674. *
  675. * If there is no default factory, and no scheduler is provided in the config,
  676. * `realm_open()` will fail. Note that `realm_scheduler_get_frozen()` always
  677. * returns a valid scheduler.
  678. *
  679. * This function is thread-safe, and cannot fail.
  680. */
  681. RLM_API bool realm_scheduler_has_default_factory(void);
  682. /**
  683. * For platforms with no default scheduler implementation, register a factory
  684. * function which can produce custom schedulers. If there is a platform-specific
  685. * scheduler, this function will fail. If a custom scheduler is desired for
  686. * platforms that already have a default scheduler implementation, the caller
  687. * must call `realm_open()` with a config that indicates the desired scheduler.
  688. *
  689. * The provided callback may produce a scheduler by calling
  690. * `realm_scheduler_new()`.
  691. *
  692. * This function is thread-safe, but should generally only be called once.
  693. */
  694. RLM_API bool realm_scheduler_set_default_factory(void* userdata, realm_free_userdata_func_t,
  695. realm_scheduler_default_factory_func_t);
  696. /**
  697. * Trigger a call to the registered notifier callback on the scheduler's event loop.
  698. *
  699. * This function is thread-safe.
  700. */
  701. RLM_API void realm_scheduler_notify(realm_scheduler_t*);
  702. /**
  703. * Returns true if the caller is currently running on the scheduler's thread.
  704. *
  705. * This function is thread-safe.
  706. */
  707. RLM_API bool realm_scheduler_is_on_thread(const realm_scheduler_t*);
  708. /**
  709. * Returns true if the scheduler is able to deliver notifications.
  710. *
  711. * A false return value may indicate that notifications are not applicable for
  712. * the scheduler, not implementable, or a temporary inability to deliver
  713. * notifications.
  714. *
  715. * This function is not thread-safe.
  716. */
  717. RLM_API bool realm_scheduler_can_deliver_notifications(const realm_scheduler_t*);
  718. /**
  719. * Set the callback that will be invoked by `realm_scheduler_notify()`.
  720. *
  721. * This function is not thread-safe.
  722. */
  723. RLM_API bool realm_scheduler_set_notify_callback(realm_scheduler_t*, void* userdata, realm_free_userdata_func_t,
  724. realm_scheduler_notify_func_t);
  725. /**
  726. * Open a Realm file.
  727. *
  728. * @param config Realm configuration. If the Realm is already opened on another
  729. * thread, validate that the given configuration is compatible
  730. * with the existing one.
  731. * @return If successful, the Realm object. Otherwise, NULL.
  732. */
  733. RLM_API realm_t* realm_open(const realm_config_t* config);
  734. /**
  735. * Create a `realm_t` object from a thread-safe reference to the same realm.
  736. *
  737. * @param tsr Thread-safe reference object created by calling
  738. * `realm_get_thread_safe_reference()` with a `realm_t` instance.
  739. * @param scheduler The scheduler to use for the new `realm_t` instance. May be
  740. * NULL, in which case the default scheduler for the current
  741. * thread is used.
  742. * @return A non-null pointer if no error occurred.
  743. */
  744. RLM_API realm_t* realm_from_thread_safe_reference(realm_thread_safe_reference_t* tsr, realm_scheduler_t* scheduler);
  745. /**
  746. * Create a `realm_t*` from a `std::shared_ptr<Realm>*`.
  747. *
  748. * This is intended as a migration path for users of the C++ Object Store API.
  749. *
  750. * Call `realm_release()` on the returned `realm_t*` to decrement the refcount
  751. * on the inner `std::shared_ptr<Realm>`.
  752. *
  753. * @param pshared_ptr A pointer to an instance of `std::shared_ptr<Realm>`.
  754. * @param n Must be equal to `sizeof(std::shared_ptr<Realm>)`.
  755. * @return A `realm_t*` representing the same Realm object as the passed
  756. * `std::shared_ptr<Realm>`.
  757. */
  758. RLM_API realm_t* _realm_from_native_ptr(const void* pshared_ptr, size_t n);
  759. /**
  760. * Get a `std::shared_ptr<Realm>` from a `realm_t*`.
  761. *
  762. * This is intended as a migration path for users of the C++ Object Store API.
  763. *
  764. * @param pshared_ptr A pointer to an instance of `std::shared_ptr<Realm>`.
  765. * @param n Must be equal to `sizeof(std::shared_ptr<Realm>)`.
  766. */
  767. RLM_API void _realm_get_native_ptr(const realm_t*, void* pshared_ptr, size_t n);
  768. /**
  769. * Forcibly close a Realm file.
  770. *
  771. * Note that this invalidates all Realm instances for the same path.
  772. *
  773. * The Realm will be automatically closed when the last reference is released,
  774. * including references to objects within the Realm.
  775. *
  776. * @return True if no exception occurred.
  777. */
  778. RLM_API bool realm_close(realm_t*);
  779. /**
  780. * True if the Realm file is closed.
  781. *
  782. * This function cannot fail.
  783. */
  784. RLM_API bool realm_is_closed(realm_t*);
  785. /**
  786. * Begin a read transaction for the Realm file.
  787. *
  788. * @return True if no exception occurred.
  789. */
  790. RLM_API bool realm_begin_read(realm_t*);
  791. /**
  792. * Begin a write transaction for the Realm file.
  793. *
  794. * @return True if no exception occurred.
  795. */
  796. RLM_API bool realm_begin_write(realm_t*);
  797. /**
  798. * Return true if the realm is in a write transaction.
  799. *
  800. * This function cannot fail.
  801. */
  802. RLM_API bool realm_is_writable(const realm_t*);
  803. /**
  804. * Commit a write transaction.
  805. *
  806. * @return True if the commit succeeded and no exceptions were thrown.
  807. */
  808. RLM_API bool realm_commit(realm_t*);
  809. /**
  810. * Roll back a write transaction.
  811. *
  812. * @return True if the rollback succeeded and no exceptions were thrown.
  813. */
  814. RLM_API bool realm_rollback(realm_t*);
  815. /**
  816. * Refresh the view of the realm file.
  817. *
  818. * If another process or thread has made changes to the realm file, this causes
  819. * those changes to become visible in this realm instance.
  820. *
  821. * This calls `advance_read()` at the Core layer.
  822. *
  823. * @return True if the realm was successfully refreshed and no exceptions were
  824. * thrown.
  825. */
  826. RLM_API bool realm_refresh(realm_t*);
  827. /**
  828. * Produce a frozen view of this realm.
  829. *
  830. * @return A non-NULL realm instance representing the frozen state.
  831. */
  832. RLM_API realm_t* realm_freeze(realm_t*);
  833. /**
  834. * Vacuum the free space from the realm file, reducing its file size.
  835. *
  836. * @return True if compaction was successful and no exceptions were thrown.
  837. */
  838. RLM_API bool realm_compact(realm_t*, bool* did_compact);
  839. /**
  840. * Create a new schema from classes and their properties.
  841. *
  842. * Note: This function does not validate the schema.
  843. *
  844. * Note: `realm_class_key_t` and `realm_property_key_t` values inside
  845. * `realm_class_info_t` and `realm_property_info_t` are unused when
  846. * defining the schema. Call `realm_get_schema()` to obtain the values for
  847. * these fields in an open realm.
  848. *
  849. * @return True if allocation of the schema structure succeeded.
  850. */
  851. RLM_API realm_schema_t* realm_schema_new(const realm_class_info_t* classes, size_t num_classes,
  852. const realm_property_info_t** class_properties);
  853. /**
  854. * Get the schema for this realm.
  855. *
  856. * Note: The returned value is allocated by this function, so `realm_release()`
  857. * must be called on it.
  858. */
  859. RLM_API realm_schema_t* realm_get_schema(const realm_t*);
  860. /**
  861. * Update the schema of an open realm.
  862. *
  863. * This is equivalent to calling `realm_update_schema_advanced(realm, schema, 0,
  864. * NULL, NULL, NULL, NULL, false)`.
  865. */
  866. RLM_API bool realm_update_schema(realm_t* realm, const realm_schema_t* schema);
  867. /**
  868. * Update the schema of an open realm, with options to customize certain steps
  869. * of the process.
  870. *
  871. * @param realm The realm for which the schema should be updated.
  872. * @param schema The new schema for the realm. If the schema is the same the
  873. * existing schema, this function does nothing.
  874. * @param version The version of the new schema.
  875. * @param migration_func Callback to perform the migration. Has no effect if the
  876. * Realm is opened with `RLM_SCHEMA_MODE_ADDITIVE`.
  877. * @param migration_func_userdata Userdata pointer to pass to `migration_func`.
  878. * @param data_init_func Callback to perform initialization of the data in the
  879. * Realm if it is opened for the first time (i.e., it has
  880. * no previous schema version).
  881. * @param data_init_func_userdata Userdata pointer to pass to `data_init_func`.
  882. * @param is_in_transaction Pass true if the realm is already in a write
  883. * transaction. Otherwise, if the migration requires a
  884. * write transaction, this function will perform the
  885. * migration in its own write transaction.
  886. */
  887. RLM_API bool realm_update_schema_advanced(realm_t* realm, const realm_schema_t* schema, uint64_t version,
  888. realm_migration_func_t migration_func, void* migration_func_userdata,
  889. realm_data_initialization_func_t data_init_func,
  890. void* data_init_func_userdata, bool is_in_transaction);
  891. /**
  892. * Get the `realm::Schema*` pointer for this realm.
  893. *
  894. * This is intended as a migration path for users of the C++ Object Store API.
  895. *
  896. * The returned value is owned by the `realm_t` instance, and must not be freed.
  897. */
  898. RLM_API const void* _realm_get_schema_native(const realm_t*);
  899. /**
  900. * Validate the schema.
  901. *
  902. * @param validation_mode A bitwise combination of values from the
  903. * enum realm_schema_validation_mode.
  904. *
  905. * @return True if the schema passed validation. If validation failed,
  906. * `realm_get_last_error()` will produce an error describing the
  907. * validation failure.
  908. */
  909. RLM_API bool realm_schema_validate(const realm_schema_t*, uint64_t validation_mode);
  910. /**
  911. * Return the number of classes in the Realm's schema.
  912. *
  913. * This cannot fail.
  914. */
  915. RLM_API size_t realm_get_num_classes(const realm_t*);
  916. /**
  917. * Get the table keys for classes in the schema.
  918. *
  919. * @param out_keys An array that will contain the keys of each class in the
  920. * schema. May be NULL, in which case `out_n` can be used to
  921. * determine the number of classes in the schema.
  922. * @param max The maximum number of keys to write to `out_keys`.
  923. * @param out_n The actual number of classes. May be NULL.
  924. * @return True if no exception occurred.
  925. */
  926. RLM_API bool realm_get_class_keys(const realm_t*, realm_class_key_t* out_keys, size_t max, size_t* out_n);
  927. /**
  928. * Find a by the name of @a name.
  929. *
  930. * @param name The name of the class.
  931. * @param out_found Set to true if the class was found and no error occurred.
  932. * Otherwise, false. May not be NULL.
  933. * @param out_class_info A pointer to a `realm_class_info_t` that will be
  934. * populated with information about the class. May be
  935. * NULL.
  936. * @return True if no exception occurred.
  937. */
  938. RLM_API bool realm_find_class(const realm_t*, const char* name, bool* out_found, realm_class_info_t* out_class_info);
  939. /**
  940. * Get the class with @a key from the schema.
  941. *
  942. * Passing an invalid @a key for this schema is considered an error.
  943. *
  944. * @param key The key of the class, as discovered by `realm_get_class_keys()`.
  945. * @param out_class_info A pointer to a `realm_class_info_t` that will be
  946. * populated with the information of the class. May be
  947. * NULL, though that's kind of pointless.
  948. * @return True if no exception occurred.
  949. */
  950. RLM_API bool realm_get_class(const realm_t*, realm_class_key_t key, realm_class_info_t* out_class_info);
  951. /**
  952. * Get the list of properties for the class with this @a key.
  953. *
  954. * @param out_properties A pointer to an array of `realm_property_info_t`, which
  955. * will be populated with the information about the
  956. * properties. To see all properties, the length of the
  957. * array should be at least the number of properties in
  958. * the class, as reported in the sum of persisted and
  959. * computed properties for the class. May be NULL, in
  960. * which case this function can be used to discover the
  961. * number of properties in the class.
  962. * @param max The maximum number of entries to write to `out_properties`.
  963. * @param out_n The actual number of properties written to `out_properties`.
  964. * @return True if no exception occurred.
  965. */
  966. RLM_API bool realm_get_class_properties(const realm_t*, realm_class_key_t key, realm_property_info_t* out_properties,
  967. size_t max, size_t* out_n);
  968. /**
  969. * Get the property keys for the class with this @a key.
  970. *
  971. * @param key The class key.
  972. * @param out_col_keys An array of property keys. May be NULL, in which case
  973. * this function can be used to discover the number of
  974. * properties for this class.
  975. * @param max The maximum number of keys to write to `out_col_keys`. Ignored if
  976. * `out_col_keys == NULL`.
  977. * @param out_n The actual number of properties written to `out_col_keys` (if
  978. * non-NULL), or number of properties in the class.
  979. **/
  980. RLM_API bool realm_get_property_keys(const realm_t*, realm_class_key_t key, realm_property_key_t* out_col_keys,
  981. size_t max, size_t* out_n);
  982. /**
  983. * Find a property by its column key.
  984. *
  985. * It is an error to pass a property @a key that is not present in this class.
  986. *
  987. * @param class_key The key of the class.
  988. * @param key The column key for the property.
  989. * @param out_property_info A pointer to a `realm_property_info_t` that will be
  990. * populated with information about the property.
  991. * @return True if no exception occurred.
  992. */
  993. RLM_API bool realm_get_property(const realm_t*, realm_class_key_t class_key, realm_property_key_t key,
  994. realm_property_info_t* out_property_info);
  995. /**
  996. * Find a property by the internal (non-public) name of @a name.
  997. *
  998. * @param class_key The table key for the class.
  999. * @param name The name of the property.
  1000. * @param out_found Will be set to true if the property was found. May not be
  1001. * NULL.
  1002. * @param out_property_info A pointer to a `realm_property_info_t` that will be
  1003. * populated with information about the property. May
  1004. * be NULL.
  1005. * @return True if no exception occurred.
  1006. */
  1007. RLM_API bool realm_find_property(const realm_t*, realm_class_key_t class_key, const char* name, bool* out_found,
  1008. realm_property_info_t* out_property_info);
  1009. /**
  1010. * Find a property with the public name of @a name.
  1011. *
  1012. * @param class_key The table key for the class.
  1013. * @param public_name The public name of the property.
  1014. * @param out_found Will be set to true if the property was found. May not be
  1015. * NULL.
  1016. * @param out_property_info A pointer to a `realm_property_info_t` that will be
  1017. * populated with information about the property. May
  1018. * be NULL.
  1019. * @return True if no exception occurred.
  1020. */
  1021. RLM_API bool realm_find_property_by_public_name(const realm_t*, realm_class_key_t class_key, const char* public_name,
  1022. bool* out_found, realm_property_info_t* out_property_info);
  1023. /**
  1024. * Find the primary key property for a class, if it has one.
  1025. *
  1026. * @param class_key The table key for this class.
  1027. * @param out_found Will be set to true if the property was found. May not be
  1028. * NULL.
  1029. * @param out_property_info A property to a `realm_property_info_t` that will be
  1030. * populated with information about the property, if it
  1031. * was found. May be NULL.
  1032. * @return True if no exception occurred.
  1033. */
  1034. RLM_API bool realm_find_primary_key_property(const realm_t*, realm_class_key_t class_key, bool* out_found,
  1035. realm_property_info_t* out_property_info);
  1036. /**
  1037. * Get the number of objects in a table (class).
  1038. *
  1039. * @param out_count A pointer to a `size_t` that will contain the number of
  1040. * objects, if successful.
  1041. * @return True if the table key was valid for this realm.
  1042. */
  1043. RLM_API bool realm_get_num_objects(const realm_t*, realm_class_key_t, size_t* out_count);
  1044. /**
  1045. * Get the number of versions found in the Realm file.
  1046. *
  1047. * @param out_versions_count A pointer to a `size_t` that will contain the number of
  1048. * versions, if successful.
  1049. * @return True if no exception occurred.
  1050. */
  1051. RLM_API bool realm_get_num_versions(const realm_t*, uint64_t* out_versions_count);
  1052. /**
  1053. * Get an object with a particular object key.
  1054. *
  1055. * @param class_key The class key.
  1056. * @param obj_key The key to the object. Passing a non-existent key is
  1057. * considered an error.
  1058. * @return A non-NULL pointer if no exception occurred.
  1059. */
  1060. RLM_API realm_object_t* realm_get_object(const realm_t*, realm_class_key_t class_key, realm_object_key_t obj_key);
  1061. /**
  1062. * Find an object with a particular primary key value.
  1063. *
  1064. * @param out_found A pointer to a boolean that will be set to true or false if
  1065. * no error occurred.
  1066. * @return A non-NULL pointer if the object was found and no exception occurred.
  1067. */
  1068. RLM_API realm_object_t* realm_object_find_with_primary_key(const realm_t*, realm_class_key_t, realm_value_t pk,
  1069. bool* out_found);
  1070. /**
  1071. * Find all objects in class.
  1072. *
  1073. * Note: This is faster than running a query matching all objects (such as
  1074. * "TRUEPREDICATE").
  1075. *
  1076. * @return A non-NULL pointer if no exception was thrown.
  1077. */
  1078. RLM_API realm_results_t* realm_object_find_all(const realm_t*, realm_class_key_t);
  1079. /**
  1080. * Create an object in a class without a primary key.
  1081. *
  1082. * @return A non-NULL pointer if the object was created successfully.
  1083. */
  1084. RLM_API realm_object_t* realm_object_create(realm_t*, realm_class_key_t);
  1085. /**
  1086. * Create an object in a class with a primary key.
  1087. *
  1088. * @return A non-NULL pointer if the object was created successfully.
  1089. */
  1090. RLM_API realm_object_t* realm_object_create_with_primary_key(realm_t*, realm_class_key_t, realm_value_t pk);
  1091. /**
  1092. * Delete a realm object.
  1093. *
  1094. * Note: This does not call `realm_release()` on the `realm_object_t` instance.
  1095. *
  1096. * @return True if no exception occurred.
  1097. */
  1098. RLM_API bool realm_object_delete(realm_object_t*);
  1099. RLM_API realm_object_t* _realm_object_from_native_copy(const void* pobj, size_t n);
  1100. RLM_API realm_object_t* _realm_object_from_native_move(void* pobj, size_t n);
  1101. RLM_API const void* _realm_object_get_native_ptr(realm_object_t*);
  1102. /**
  1103. * True if this object still exists in the realm.
  1104. *
  1105. * This function cannot fail.
  1106. */
  1107. RLM_API bool realm_object_is_valid(const realm_object_t*);
  1108. /**
  1109. * Get the key for this object.
  1110. *
  1111. * This function cannot fail.
  1112. */
  1113. RLM_API realm_object_key_t realm_object_get_key(const realm_object_t* object);
  1114. /**
  1115. * Get the table for this object.
  1116. *
  1117. * This function cannot fail.
  1118. */
  1119. RLM_API realm_class_key_t realm_object_get_table(const realm_object_t* object);
  1120. /**
  1121. * Get a `realm_link_t` representing a link to @a object.
  1122. *
  1123. * This function cannot fail.
  1124. */
  1125. RLM_API realm_link_t realm_object_as_link(const realm_object_t* object);
  1126. /**
  1127. * Subscribe to notifications for this object.
  1128. *
  1129. * @return A non-null pointer if no exception occurred.
  1130. */
  1131. RLM_API realm_notification_token_t* realm_object_add_notification_callback(realm_object_t*, void* userdata,
  1132. realm_free_userdata_func_t free,
  1133. realm_on_object_change_func_t on_change,
  1134. realm_callback_error_func_t on_error,
  1135. realm_scheduler_t*);
  1136. /**
  1137. * Get an object from a thread-safe reference, potentially originating in a
  1138. * different `realm_t` instance
  1139. */
  1140. RLM_API realm_object_t* realm_object_from_thread_safe_reference(const realm_t*, realm_thread_safe_reference_t*);
  1141. /**
  1142. * Get the value for a property.
  1143. *
  1144. * @return True if no exception occurred.
  1145. */
  1146. RLM_API bool realm_get_value(const realm_object_t*, realm_property_key_t, realm_value_t* out_value);
  1147. /**
  1148. * Get the values for several properties.
  1149. *
  1150. * This is provided as an alternative to calling `realm_get_value()` multiple
  1151. * times in a row, which is particularly useful for language runtimes where
  1152. * crossing the native bridge is comparatively expensive. In addition, it
  1153. * eliminates some parameter validation that would otherwise be repeated for
  1154. * each call.
  1155. *
  1156. * Example use cases:
  1157. *
  1158. * - Extracting all properties of an object for serialization.
  1159. * - Converting an object to some in-memory representation.
  1160. *
  1161. * @param num_values The number of elements in @a properties and @a out_values.
  1162. * @param properties The keys for the properties to fetch. May not be NULL.
  1163. * @param out_values Where to write the property values. If an error occurs,
  1164. * this array may only be partially initialized. May not be
  1165. * NULL.
  1166. * @return True if no exception occurs.
  1167. */
  1168. RLM_API bool realm_get_values(const realm_object_t*, size_t num_values, const realm_property_key_t* properties,
  1169. realm_value_t* out_values);
  1170. /**
  1171. * Set the value for a property.
  1172. *
  1173. * @param new_value The new value for the property.
  1174. * @param is_default True if this property is being set as part of setting the
  1175. * default values for a new object. This has no effect in
  1176. * non-sync'ed realms.
  1177. * @return True if no exception occurred.
  1178. */
  1179. RLM_API bool realm_set_value(realm_object_t*, realm_property_key_t, realm_value_t new_value, bool is_default);
  1180. /**
  1181. * Set the values for several properties.
  1182. *
  1183. * This is provided as an alternative to calling `realm_get_value()` multiple
  1184. * times in a row, which is particularly useful for language runtimes where
  1185. * crossing the native bridge is comparatively expensive. In addition, it
  1186. * eliminates some parameter validation that would otherwise be repeated for
  1187. * each call.
  1188. *
  1189. * Example use cases:
  1190. *
  1191. * - Initializing a new object with default values.
  1192. * - Deserializing some in-memory structure into a realm object.
  1193. *
  1194. * This operation is "atomic"; if an exception occurs due to invalid input (such
  1195. * as type mismatch, nullability mismatch, etc.), the object will remain
  1196. * unmodified.
  1197. *
  1198. * @param num_values The number of elements in @a properties and @a values.
  1199. * @param properties The keys of the properties to set. May not be NULL.
  1200. * @param values The values to assign to the properties. May not be NULL.
  1201. * @param is_default True if the properties are being set as part of setting
  1202. * default values for a new object. This has no effect in
  1203. * non-sync'ed realms.
  1204. * @return True if no exception occurred.
  1205. */
  1206. RLM_API bool realm_set_values(realm_object_t*, size_t num_values, const realm_property_key_t* properties,
  1207. const realm_value_t* values, bool is_default);
  1208. /**
  1209. * Get a list instance for the property of an object.
  1210. *
  1211. * Note: It is up to the caller to call `realm_release()` on the returned list.
  1212. *
  1213. * @return A non-null pointer if no exception occurred.
  1214. */
  1215. RLM_API realm_list_t* realm_get_list(realm_object_t*, realm_property_key_t);
  1216. /**
  1217. * Create a `realm_list_t` from a pointer to a `realm::List`, copy-constructing
  1218. * the internal representation.
  1219. *
  1220. * @param plist A pointer to an instance of `realm::List`.
  1221. * @param n Must be equal to `sizeof(realm::List)`.
  1222. * @return A non-null pointer if no exception occurred.
  1223. */
  1224. RLM_API realm_list_t* _realm_list_from_native_copy(const void* plist, size_t n);
  1225. /**
  1226. * Create a `realm_list_t` from a pointer to a `realm::List`, move-constructing
  1227. * the internal representation.
  1228. *
  1229. * @param plist A pointer to an instance of `realm::List`.
  1230. * @param n Must be equal to `sizeof(realm::List)`.
  1231. * @return A non-null pointer if no exception occurred.
  1232. */
  1233. RLM_API realm_list_t* _realm_list_from_native_move(void* plist, size_t n);
  1234. /**
  1235. * Get the size of a list, in number of elements.
  1236. *
  1237. * This function may fail if the object owning the list has been deleted.
  1238. *
  1239. * @param out_size Where to put the list size. May be NULL.
  1240. * @return True if no exception occurred.
  1241. */
  1242. RLM_API bool realm_list_size(const realm_list_t*, size_t* out_size);
  1243. /**
  1244. * Get the property that this list came from.
  1245. *
  1246. * @return True if no exception occurred.
  1247. */
  1248. RLM_API bool realm_list_get_property(const realm_list_t*, realm_property_info_t* out_property_info);
  1249. /**
  1250. * Get the value at @a index.
  1251. *
  1252. * @param out_value The resulting value, if no error occurred. May be NULL,
  1253. * though nonsensical.
  1254. * @return True if no exception occurred.
  1255. */
  1256. RLM_API bool realm_list_get(const realm_list_t*, size_t index, realm_value_t* out_value);
  1257. /**
  1258. * Set the value at @a index.
  1259. *
  1260. * @param value The value to set.
  1261. * @return True if no exception occurred.
  1262. */
  1263. RLM_API bool realm_list_set(realm_list_t*, size_t index, realm_value_t value);
  1264. /**
  1265. * Insert @a value at @a index.
  1266. *
  1267. * @param value The value to insert.
  1268. * @return True if no exception occurred.
  1269. */
  1270. RLM_API bool realm_list_insert(realm_list_t*, size_t index, realm_value_t value);
  1271. /**
  1272. * Erase the element at @a index.
  1273. *
  1274. * @return True if no exception occurred.
  1275. */
  1276. RLM_API bool realm_list_erase(realm_list_t*, size_t index);
  1277. /**
  1278. * Clear a list, removing all elements in the list. In a list of links, this
  1279. * does *NOT* delete the target objects.
  1280. *
  1281. * @return True if no exception occurred.
  1282. */
  1283. RLM_API bool realm_list_clear(realm_list_t*);
  1284. /**
  1285. * In a list of objects, delete all objects in the list and clear the list. In a
  1286. * list of values, clear the list.
  1287. *
  1288. * @return True if no exception occurred.
  1289. */
  1290. RLM_API bool realm_list_remove_all(realm_list_t*);
  1291. /**
  1292. * Replace the contents of a list with values.
  1293. *
  1294. * This is equivalent to calling `realm_list_clear()`, and then
  1295. * `realm_list_insert()` repeatedly.
  1296. *
  1297. * @return True if no exception occurred.
  1298. */
  1299. RLM_API bool realm_list_assign(realm_list_t*, const realm_value_t* values, size_t num_values);
  1300. /**
  1301. * Subscribe to notifications for this object.
  1302. *
  1303. * @return A non-null pointer if no exception occurred.
  1304. */
  1305. RLM_API realm_notification_token_t* realm_list_add_notification_callback(realm_list_t*, void* userdata,
  1306. realm_free_userdata_func_t free,
  1307. realm_on_collection_change_func_t on_change,
  1308. realm_callback_error_func_t on_error,
  1309. realm_scheduler_t*);
  1310. /**
  1311. * Get an list from a thread-safe reference, potentially originating in a
  1312. * different `realm_t` instance
  1313. */
  1314. RLM_API realm_list_t* realm_list_from_thread_safe_reference(const realm_t*, realm_thread_safe_reference_t*);
  1315. /**
  1316. * True if an object notification indicates that the object was deleted.
  1317. *
  1318. * This function cannot fail.
  1319. */
  1320. RLM_API bool realm_object_changes_is_deleted(const realm_object_changes_t*);
  1321. /**
  1322. * Get the number of properties that were modified in an object notification.
  1323. *
  1324. * This function cannot fail.
  1325. */
  1326. RLM_API size_t realm_object_changes_get_num_modified_properties(const realm_object_changes_t*);
  1327. /**
  1328. * Get the column keys for the properties that were modified in an object
  1329. * notification.
  1330. *
  1331. * This function cannot fail.
  1332. *
  1333. * @param out_modified Where the column keys should be written. May be NULL.
  1334. * @param max The maximum number of column keys to write.
  1335. * @return The number of column keys written to @a out_modified, or the number
  1336. * of modified properties if @a out_modified is NULL.
  1337. */
  1338. RLM_API size_t realm_object_changes_get_modified_properties(const realm_object_changes_t*,
  1339. realm_property_key_t* out_modified, size_t max);
  1340. /**
  1341. * Get the number of various types of changes in a collection notification.
  1342. *
  1343. * @param out_num_deletions The number of deletions. May be NULL.
  1344. * @param out_num_insertions The number of insertions. May be NULL.
  1345. * @param out_num_modifications The number of modifications. May be NULL.
  1346. * @param out_num_moves The number of moved elements. May be NULL.
  1347. */
  1348. RLM_API void realm_collection_changes_get_num_changes(const realm_collection_changes_t*, size_t* out_num_deletions,
  1349. size_t* out_num_insertions, size_t* out_num_modifications,
  1350. size_t* out_num_moves);
  1351. /**
  1352. * Get the number of various types of changes in a collection notification,
  1353. * suitable for acquiring the change indices as ranges, which is much more
  1354. * compact in memory than getting the individual indices when multiple adjacent
  1355. * elements have been modified.
  1356. *
  1357. * @param out_num_deletion_ranges The number of deleted ranges. May be NULL.
  1358. * @param out_num_insertion_ranges The number of inserted ranges. May be NULL.
  1359. * @param out_num_modification_ranges The number of modified ranges. May be
  1360. * NULL.
  1361. * @param out_num_moves The number of moved elements. May be NULL.
  1362. */
  1363. RLM_API void realm_collection_changes_get_num_ranges(const realm_collection_changes_t*,
  1364. size_t* out_num_deletion_ranges,
  1365. size_t* out_num_insertion_ranges,
  1366. size_t* out_num_modification_ranges, size_t* out_num_moves);
  1367. typedef struct realm_collection_move {
  1368. size_t from;
  1369. size_t to;
  1370. } realm_collection_move_t;
  1371. typedef struct realm_index_range {
  1372. size_t from;
  1373. size_t to;
  1374. } realm_index_range_t;
  1375. /**
  1376. * Get the indices of changes in a collection notification.
  1377. *
  1378. * Note: For moves, every `from` index will also be present among deletions, and
  1379. * every `to` index will also be present among insertions.
  1380. *
  1381. * This function cannot fail.
  1382. *
  1383. * @param out_deletion_indices Where to put the indices of deleted elements
  1384. * (*before* the deletion happened). May be NULL.
  1385. * @param max_deletion_indices The max number of indices to write to @a
  1386. * out_deletion_indices.
  1387. * @param out_insertion_indices Where the put the indices of inserted elements
  1388. * (*after* the insertion happened). May be NULL.
  1389. * @param max_insertion_indices The max number of indices to write to @a
  1390. * out_insertion_indices.
  1391. * @param out_modification_indices Where to put the indices of modified elements
  1392. * (*before* any insertions or deletions of
  1393. * other elements). May be NULL.
  1394. * @param max_modification_indices The max number of indices to write to @a
  1395. * out_modification_indices.
  1396. * @param out_modification_indices_after Where to put the indices of modified
  1397. * elements (*after* any insertions or
  1398. * deletions of other elements). May be
  1399. * NULL.
  1400. * @param max_modification_indices_after The max number of indices to write to
  1401. * @a out_modification_indices_after.
  1402. * @param out_moves Where to put the pairs of indices of moved elements. May be
  1403. * NULL.
  1404. * @param max_moves The max number of pairs to write to @a out_moves.
  1405. */
  1406. RLM_API void realm_collection_changes_get_changes(const realm_collection_changes_t*, size_t* out_deletion_indices,
  1407. size_t max_deletion_indices, size_t* out_insertion_indices,
  1408. size_t max_insertion_indices, size_t* out_modification_indices,
  1409. size_t max_modification_indices,
  1410. size_t* out_modification_indices_after,
  1411. size_t max_modification_indices_after,
  1412. realm_collection_move_t* out_moves, size_t max_moves);
  1413. RLM_API void realm_collection_changes_get_ranges(
  1414. const realm_collection_changes_t*, realm_index_range_t* out_deletion_ranges, size_t max_deletion_ranges,
  1415. realm_index_range_t* out_insertion_ranges, size_t max_insertion_ranges,
  1416. realm_index_range_t* out_modification_ranges, size_t max_modification_ranges,
  1417. realm_index_range_t* out_modification_ranges_after, size_t max_modification_ranges_after,
  1418. realm_collection_move_t* out_moves, size_t max_moves);
  1419. RLM_API realm_set_t* _realm_set_from_native_copy(const void* pset, size_t n);
  1420. RLM_API realm_set_t* _realm_set_from_native_move(void* pset, size_t n);
  1421. RLM_API realm_set_t* realm_get_set(const realm_object_t*, realm_property_key_t);
  1422. RLM_API size_t realm_set_size(const realm_set_t*);
  1423. RLM_API bool realm_set_get(const realm_set_t*, size_t index, realm_value_t* out_value);
  1424. RLM_API bool realm_set_find(const realm_set_t*, realm_value_t value, size_t* out_index);
  1425. RLM_API bool realm_set_insert(realm_set_t*, realm_value_t value, size_t out_index);
  1426. RLM_API bool realm_set_erase(realm_set_t*, realm_value_t value, bool* out_erased);
  1427. RLM_API bool realm_set_clear(realm_set_t*);
  1428. RLM_API bool realm_set_assign(realm_set_t*, realm_value_t values, size_t num_values);
  1429. RLM_API realm_notification_token_t* realm_set_add_notification_callback(realm_object_t*, void* userdata,
  1430. realm_free_userdata_func_t free,
  1431. realm_on_collection_change_func_t on_change,
  1432. realm_callback_error_func_t on_error,
  1433. realm_scheduler_t*);
  1434. RLM_API realm_dictionary_t* _realm_dictionary_from_native_copy(const void* pdict, size_t n);
  1435. RLM_API realm_dictionary_t* _realm_dictionary_from_native_move(void* pdict, size_t n);
  1436. RLM_API realm_dictionary_t* realm_get_dictionary(const realm_object_t*, realm_property_key_t);
  1437. RLM_API size_t realm_dictionary_size(const realm_dictionary_t*);
  1438. RLM_API bool realm_dictionary_get(const realm_dictionary_t*, realm_value_t key, realm_value_t* out_value,
  1439. bool* out_found);
  1440. RLM_API bool realm_dictionary_insert(realm_dictionary_t*, realm_value_t key, realm_value_t value, bool* out_inserted,
  1441. size_t* out_index);
  1442. RLM_API bool realm_dictionary_erase(realm_dictionary_t*, realm_value_t key, bool* out_erased);
  1443. RLM_API bool realm_dictionary_clear(realm_dictionary_t*);
  1444. typedef realm_value_t realm_key_value_pair_t[2];
  1445. RLM_API bool realm_dictionary_assign(realm_dictionary_t*, const realm_key_value_pair_t* pairs, size_t num_pairs);
  1446. RLM_API realm_notification_token_t*
  1447. realm_dictionary_add_notification_callback(realm_object_t*, void* userdata, realm_free_userdata_func_t free,
  1448. realm_on_collection_change_func_t on_change,
  1449. realm_callback_error_func_t on_error, realm_scheduler_t*);
  1450. /**
  1451. * Parse a query string and bind it to a table.
  1452. *
  1453. * If the query failed to parse, the parser error is available from
  1454. * `realm_get_last_error()`.
  1455. *
  1456. * @param target_table The table on which to run this query.
  1457. * @param query_string A zero-terminated string in the Realm Query Language,
  1458. * optionally containing argument placeholders (`$0`, `$1`,
  1459. * etc.).
  1460. * @param num_args The number of arguments for this query.
  1461. * @param args A pointer to a list of argument values.
  1462. * @return A non-null pointer if the query was successfully parsed and no
  1463. * exception occurred.
  1464. */
  1465. RLM_API realm_query_t* realm_query_parse(const realm_t*, realm_class_key_t target_table, const char* query_string,
  1466. size_t num_args, const realm_value_t* args);
  1467. /**
  1468. * Parse a query string and bind it to a list.
  1469. *
  1470. * If the query failed to parse, the parser error is available from
  1471. * `realm_get_last_error()`.
  1472. *
  1473. * @param target_list The list on which to run this query.
  1474. * @param query_string A string in the Realm Query Language, optionally
  1475. * containing argument placeholders (`$0`, `$1`, etc.).
  1476. * @param num_args The number of arguments for this query.
  1477. * @param args A pointer to a list of argument values.
  1478. * @return A non-null pointer if the query was successfully parsed and no
  1479. * exception occurred.
  1480. */
  1481. RLM_API realm_query_t* realm_query_parse_for_list(const realm_list_t* target_list, const char* query_string,
  1482. size_t num_args, const realm_value_t* args);
  1483. /**
  1484. * Parse a query string and bind it to another query result.
  1485. *
  1486. * If the query failed to parse, the parser error is available from
  1487. * `realm_get_last_error()`.
  1488. *
  1489. * @param target_results The results on which to run this query.
  1490. * @param query_string A zero-terminated string in the Realm Query Language,
  1491. * optionally containing argument placeholders (`$0`, `$1`,
  1492. * etc.).
  1493. * @param num_args The number of arguments for this query.
  1494. * @param args A pointer to a list of argument values.
  1495. * @return A non-null pointer if the query was successfully parsed and no
  1496. * exception occurred.
  1497. */
  1498. RLM_API realm_query_t* realm_query_parse_for_results(const realm_results_t* target_results, const char* query_string,
  1499. size_t num_args, const realm_value_t* args);
  1500. /**
  1501. * Count the number of objects found by this query.
  1502. */
  1503. RLM_API bool realm_query_count(const realm_query_t*, size_t* out_count);
  1504. /**
  1505. * Return the first object matched by this query.
  1506. *
  1507. * Note: This function can only produce objects, not values. Use the
  1508. * `realm_results_t` returned by `realm_query_find_all()` to retrieve
  1509. * values from a list of primitive values.
  1510. *
  1511. * @param out_value Where to write the result, if any object matched the query.
  1512. * May be NULL.
  1513. * @param out_found Where to write whether the object was found. May be NULL.
  1514. * @return True if no exception occurred.
  1515. */
  1516. RLM_API bool realm_query_find_first(realm_query_t*, realm_value_t* out_value, bool* out_found);
  1517. /**
  1518. * Produce a results object for this query.
  1519. *
  1520. * Note: This does not actually run the query until the results are accessed in
  1521. * some way.
  1522. *
  1523. * @return A non-null pointer if no exception occurred.
  1524. */
  1525. RLM_API realm_results_t* realm_query_find_all(realm_query_t*);
  1526. /**
  1527. * Delete all objects matched by a query.
  1528. */
  1529. RLM_API bool realm_query_delete_all(const realm_query_t*);
  1530. /**
  1531. * Count the number of results.
  1532. *
  1533. * If the result is "live" (not a snapshot), this may rerun the query if things
  1534. * have changed.
  1535. *
  1536. * @return True if no exception occurred.
  1537. */
  1538. RLM_API bool realm_results_count(realm_results_t*, size_t* out_count);
  1539. /**
  1540. * Get the matching element at @a index in the results.
  1541. *
  1542. * If the result is "live" (not a snapshot), this may rerun the query if things
  1543. * have changed.
  1544. *
  1545. * Note: The bound returned by `realm_results_count()` for a non-snapshot result
  1546. * is not a reliable way to iterate over elements in the result, because
  1547. * the result will be live-updated if changes are made in each iteration
  1548. * that may change the number of query results or even change the
  1549. * ordering. In other words, this method should probably only be used with
  1550. * snapshot results.
  1551. *
  1552. * @return True if no exception occurred (including out-of-bounds).
  1553. */
  1554. RLM_API bool realm_results_get(realm_results_t*, size_t index, realm_value_t* out_value);
  1555. /**
  1556. * Get the matching object at @a index in the results.
  1557. *
  1558. * If the result is "live" (not a snapshot), this may rerun the query if things
  1559. * have changed.
  1560. *
  1561. * Note: The bound returned by `realm_results_count()` for a non-snapshot result
  1562. * is not a reliable way to iterate over elements in the result, because
  1563. * the result will be live-updated if changes are made in each iteration
  1564. * that may change the number of query results or even change the
  1565. * ordering. In other words, this method should probably only be used with
  1566. * snapshot results.
  1567. *
  1568. * @return An instance of `realm_object_t` if no exception occurred.
  1569. */
  1570. RLM_API realm_object_t* realm_results_get_object(realm_results_t*, size_t index);
  1571. /**
  1572. * Delete all objects in the result.
  1573. *
  1574. * If the result if "live" (not a snapshot), this may rerun the query if things
  1575. * have changed.
  1576. *
  1577. * @return True if no exception occurred.
  1578. */
  1579. RLM_API bool realm_results_delete_all(realm_results_t*);
  1580. /**
  1581. * Return a snapshot of the results that never automatically updates.
  1582. *
  1583. * The returned result is suitable for use with `realm_results_count()` +
  1584. * `realm_results_get()`.
  1585. */
  1586. RLM_API realm_results_t* realm_results_snapshot(const realm_results_t*);
  1587. /**
  1588. * Map the results into a frozen realm instance.
  1589. */
  1590. RLM_API realm_results_t* realm_results_freeze(const realm_results_t*, const realm_t* frozen_realm);
  1591. /**
  1592. * Compute the minimum value of a property in the results.
  1593. *
  1594. * @param out_min Where to write the result, if there were matching rows.
  1595. * @param out_found Set to true if there are matching rows.
  1596. * @return True if no exception occurred.
  1597. */
  1598. RLM_API bool realm_results_min(realm_results_t*, realm_property_key_t, realm_value_t* out_min, bool* out_found);
  1599. /**
  1600. * Compute the maximum value of a property in the results.
  1601. *
  1602. * @param out_max Where to write the result, if there were matching rows.
  1603. * @param out_found Set to true if there are matching rows.
  1604. * @return True if no exception occurred.
  1605. */
  1606. RLM_API bool realm_results_max(realm_results_t*, realm_property_key_t, realm_value_t* out_max, bool* out_found);
  1607. /**
  1608. * Compute the sum value of a property in the results.
  1609. *
  1610. * @param out_sum Where to write the result. Zero if no rows matched.
  1611. * @param out_found Set to true if there are matching rows.
  1612. * @return True if no exception occurred.
  1613. */
  1614. RLM_API bool realm_results_sum(realm_results_t*, realm_property_key_t, realm_value_t* out_sum, bool* out_found);
  1615. /**
  1616. * Compute the average value of a property in the results.
  1617. *
  1618. * Note: For numeric columns, the average is always converted to double.
  1619. *
  1620. * @param out_average Where to write the result.
  1621. * @param out_found Set to true if there are matching rows.
  1622. * @return True if no exception occurred.
  1623. */
  1624. RLM_API bool realm_results_average(realm_results_t*, realm_property_key_t, realm_value_t* out_average,
  1625. bool* out_found);
  1626. RLM_API realm_notification_token_t* realm_results_add_notification_callback(realm_results_t*, void* userdata,
  1627. realm_free_userdata_func_t,
  1628. realm_on_collection_change_func_t,
  1629. realm_callback_error_func_t,
  1630. realm_scheduler_t*);
  1631. /**
  1632. * Get an results object from a thread-safe reference, potentially originating
  1633. * in a different `realm_t` instance
  1634. */
  1635. RLM_API realm_results_t* realm_results_from_thread_safe_reference(const realm_t*, realm_thread_safe_reference_t*);
  1636. #endif // REALM_H