CRUD - 作成 - C++ SDK
項目一覧
書込みトランザクション (write transaction)
Realm は高効率のストレージ エンジンを使用してオブジェクトを永続化します。 Realm でオブジェクトを作成し、Realm 内のオブジェクトを更新し、最終的に Realm からオブジェクトを削除することができます。 これらの操作は Realm の状態を変更するため、書込み (write) と呼びます。
Realm はトランザクション単位で書込み (write) を処理します。 トランザクションは 、Realm が単一の分割不可の操作として取り扱う読み取り操作と書込み (write) 操作のリストです。 言い換えれば、トランザクションはすべてであるか、または何もなかったようになります。つまり、トランザクション内のすべての操作が成功するか、トランザクション内のどの操作が有効になりません。
すべての書込み (write) はトランザクション内で発生する必要があります。
Realm では一度に 1 つのトランザクションのみを開くことができます。 Realm は、開いているトランザクションが完了するまで、他のスレッドへの他の書込みをブロックします。 その結果、トランザクション内で Realm から値を読み取るときに競合状態は発生しません。
トランザクションが完了すると、Realm はトランザクションをコミットまたはキャンセルします。
Realm がトランザクションをコミットすると、Realm はすべての変更をディスクに書込みます。 同期された Realm の場合、SDK は Atlas Device Sync との同期のために変更をキューに入れます。
Realm が書込みトランザクションをキャンセルするか、トランザクション内の操作によってエラーが発生すると、すべての変更は破棄されます(または「ロールバック」)。
新しいオブジェクトの作成
オブジェクトの作成
オブジェクトを作成するには、 realm
名前空間を使用してインスタンス化する必要があります。 書込みトランザクション内で Realm.add() 関数を使用してオブジェクトを Realm に移動します。
オブジェクトを Realm に移動すると、これによりオブジェクトが r値として消費されます。 データアクセスまたは監視には、 管理対象オブジェクト を使用する必要があります。 この例では、 dog
オブジェクトを Realm にコピーすると、それが r値として消費されます。 管理対象のオブジェクトを返して、引き続き操作を行うことができます。
// Create an object using the `realm` namespace. auto dog = realm::Dog{.name = "Rex", .age = 1}; std::cout << "dog: " << dog.name << "\n"; // Open the database with compile-time schema checking. auto config = realm::db_config(); auto realm = realm::db(std::move(config)); // Persist your data in a write transaction // Optionally return the managed object to work with it immediately auto managedDog = realm.write([&] { return realm.add(std::move(dog)); });
モデル
オブジェクトのモデリングの詳細については、「 新しいオブジェクト タイプの定義 」を参照してください。
namespace realm { struct Dog { std::string name; int64_t age; }; REALM_SCHEMA(Dog, name, age) } // namespace realm
埋め込みオブジェクトの作成
埋め込みオブジェクトを作成するには、埋め込みオブジェクトの未加工ポインターを親オブジェクトの プロパティに割り当てます。 書込みトランザクション (write transaction) 内でRealm.add() 関数を使用して親オブジェクトを Realm に移動します。
この例では、埋め込みオブジェクトの未加工ポインター - ContactDetails *
- を親オブジェクトの埋め込みオブジェクト プロパティ - Business.contactDetails
に割り当てます。
次に、 business
オブジェクトを Realm に追加します。 これにより、business
オブジェクトとcontactDetails
オブジェクトが Realm にコピーされます。
ContactDetails
は埋め込みオブジェクトであるため、メインのBusiness
オブジェクトから独立した独自のライフサイクルはありません。 Business
オブジェクトを削除すると、 ContactDetails
オブジェクトも削除されます。
auto config = realm::db_config(); auto realm = realm::db(std::move(config)); auto contactDetails = realm::ContactDetails{ .emailAddress = "email@example.com", .phoneNumber = "123-456-7890"}; auto business = realm::Business(); business._id = realm::object_id::generate(); business.name = "MongoDB"; business.contactDetails = &contactDetails; realm.write([&] { realm.add(std::move(business)); });
モデル
埋め込みオブジェクトのモデル化の詳細については、「 埋め込みオブジェクトの定義 」を参照してください。
namespace realm { struct ContactDetails { // Because ContactDetails is an embedded object, it cannot have its own _id // It does not have a lifecycle outside of the top-level object std::string emailAddress; std::string phoneNumber; }; REALM_EMBEDDED_SCHEMA(ContactDetails, emailAddress, phoneNumber) struct Business { realm::object_id _id; std::string name; ContactDetails *contactDetails; }; REALM_SCHEMA(Business, _id, name, contactDetails) } // namespace realm
対 1 の関係を持つオブジェクトの作成
別のオブジェクトとの 1 対 1 の関係を持つオブジェクトを作成するには、関連オブジェクトの未加工のポインターをメイン オブジェクトの関係プロパティに割り当てます。 書込みトランザクション (write transaction) 内でRealm.add() 関数を使用してオブジェクトを Realm に移動します。
この例では、関連オブジェクト - FavoriteToy *
- の未加工のポインターを、メイン オブジェクトの関係 - Dog.favoriteToy
に割り当てます。 次に、 dog
オブジェクトを Realm に追加すると、 dog
とfavoriteToy
の両方が Realm にコピーされます。
関連するfavoriteToy
オブジェクトには、メインのdog
オブジェクトとは独立した独自のライフサイクルがあります。 メイン オブジェクトを削除しても、関連するオブジェクトは残ります。
auto config = realm::db_config(); auto realmInstance = realm::db(std::move(config)); auto favoriteToy = realm::FavoriteToy{ ._id = realm::uuid("68b696c9-320b-4402-a412-d9cee10fc6a5"), .name = "Wubba"}; auto dog = realm::Dog{ ._id = realm::uuid("68b696d7-320b-4402-a412-d9cee10fc6a3"), .name = "Lita", .age = 10, .favoriteToy = &favoriteToy}; realmInstance.write([&] { realmInstance.add(std::move(dog)); });
オプションで、関連オブジェクトからメイン オブジェクトを参照する逆の関係を作成することもできます。 詳細については、「 逆の関係を持つオブジェクトの作成 」を参照してください。
モデル
対 1 の関係のモデル化の詳細については、「 対 1 の関係の定義 」を参照してください。
struct FavoriteToy { realm::primary_key<realm::uuid> _id; std::string name; }; REALM_SCHEMA(FavoriteToy, _id, name) struct Dog { realm::primary_key<realm::uuid> _id; std::string name; int64_t age; // Define a relationship as a link to another SDK object FavoriteToy* favoriteToy; }; REALM_SCHEMA(Dog, _id, name, age, favoriteToy)
ToMany の関係を持つオブジェクトの作成
1 つ以上のオブジェクトとの対多の関係を持つオブジェクトを作成するには、
メイン オブジェクトと関連オブジェクトを初期化
Realm オブジェクト リストで使用できるpush_back ノード関数を使用して、関連オブジェクトの未加工のポインターをメインオブジェクトのリストプロパティに追加します
書込みトランザクション (write transaction) 内でRealm.add() 関数を使用してオブジェクトを Realm に移動します。
この例では、関連オブジェクト - Employee *
- の未加工のポインターをメイン オブジェクトの関係プロパティ - Company.employees
に追加します。 これにより、 Company
オブジェクトからEmployee
オブジェクトへの一方向接続が作成されます。
次に、 Company
を Realm に追加します。 これにより、Company
オブジェクトとEmployee
オブジェクトが Realm にコピーされます。
関連するEmployee
オブジェクトには、メインのCompany
オブジェクトとは独立した独自のライフサイクルがあります。 メイン オブジェクトを削除しても、関連するオブジェクトは残ります。
auto config = realm::db_config(); auto realmInstance = realm::db(std::move(config)); auto employee1 = realm::Employee{ ._id = 23456, .firstName = "Pam", .lastName = "Beesly"}; auto employee2 = realm::Employee{ ._id = 34567, .firstName = "Jim", .lastName = "Halpert"}; auto company = realm::Company{._id = 45678, .name = "Dunder Mifflin"}; // Use the `push_back` member function available to the // `ListObjectPersistable<T>` template to append `Employee` objects to // the `Company` `employees` list property. company.employees.push_back(&employee1); company.employees.push_back(&employee2); realmInstance.write([&] { realmInstance.add(std::move(company)); });
オプションで、関連オブジェクトからメイン オブジェクトを参照する逆の関係を作成することもできます。 詳細については、「 逆の関係を持つオブジェクトの作成 」を参照してください。
モデル
Tomany 関係のモデル化の詳細については、「 ToMany 関係の定義 」を参照してください。
namespace realm { struct Employee { realm::primary_key<int64_t> _id; std::string firstName; std::string lastName; // You can use this property as you would any other member // Omitting it from the schema means the SDK ignores it std::string jobTitle_notPersisted; }; // The REALM_SCHEMA omits the `jobTitle_notPersisted` property // The SDK does not store and cannot retrieve a value for this property REALM_SCHEMA(Employee, _id, firstName, lastName) } // namespace realm
struct Company { int64_t _id; std::string name; // To-many relationships are a list, represented here as a // vector container whose value type is the SDK object // type that the list field links to. std::vector<Employee*> employees; }; REALM_SCHEMA(Company, _id, name, employees)
逆の関係を持つオブジェクトの作成
別のオブジェクトと逆の関係を持つオブジェクトを作成するには、関連オブジェクトの未加工のポインターをメインオブジェクトの関係プロパティに割り当てます。 書込みトランザクション (write transaction) 内でRealm.add() 関数を使用してオブジェクトを Realm に移動します。
この例では、それぞれが同じDog
オブジェクトと 1 対 1 の関係を持つ 2 つのPerson
オブジェクトを作成します。 Dog
は各Person
オブジェクトと逆の関係にあります。 リンクされたPerson
オブジェクトがDog
の関係を更新すると、逆関係のバックリンクは自動的に更新されます。
auto config = realm::db_config(); auto realm = realm::db(std::move(config)); auto dog = realm::Dog{.name = "Bowser"}; auto [jack, jill] = realm.write([&realm]() { auto person = realm::Person{.name = "Jack", .age = 27, .dog = nullptr}; realm::Person person2; person2.name = "Jill"; person2.age = 28; person2.dog = nullptr; return realm.insert(std::move(person), std::move(person2)); }); realm.write([&dog, jack = &jack]() { jack->dog = &dog; }); // After assigning `&dog` to jack's `dog` property, // the backlink automatically updates to reflect // the inverse relationship through the dog's `owners` // property CHECK(jack.dog->owners.size() == 1); realm.write([&dog, jill = &jill]() { jill->dog = &dog; }); // After assigning the same `&dog` to jill's `dog` // property, the backlink automatically updates CHECK(jill.dog->owners.size() == 2); CHECK(jack.dog->owners.size() == 2); // Removing the relationship from the parent object // automatically updates the inverse relationship realm.write([jack = &jack]() { jack->dog = nullptr; }); CHECK(jack.dog == nullptr); CHECK(jill.dog->owners.size() == 1);
モデル
逆関係のモデル化の詳細については、「 逆関係の定義 」を参照してください。
struct Dog; struct Person { realm::primary_key<int64_t> _id; std::string name; int64_t age = 0; Dog* dog; }; REALM_SCHEMA(Person, _id, name, age, dog) struct Dog { realm::primary_key<int64_t> _id; std::string name; int64_t age = 0; linking_objects<&Person::dog> owners; }; REALM_SCHEMA(Dog, _id, name, age, owners)
マップ プロパティを持つオブジェクトの作成
マップ プロパティを持つオブジェクトを作成する場合、いくつかの方法でキーの値を設定できます。
オブジェクトにキーと値を設定し、そのオブジェクトを Realm に追加する
書込みトランザクション内でオブジェクトのキーと値を直接設定
auto config = realm::db_config(); auto realm = realm::db(std::move(config)); auto employee = realm::Employee{ ._id = 8675309, .firstName = "Tommy", .lastName = "Tutone"}; employee.locationByDay = { {"Monday", realm::Employee::WorkLocation::HOME}, {"Tuesday", realm::Employee::WorkLocation::OFFICE}, {"Wednesday", realm::Employee::WorkLocation::HOME}, {"Thursday", realm::Employee::WorkLocation::OFFICE}}; realm.write([&] { realm.add(std::move(employee)); employee.locationByDay["Friday"] = realm::Employee::WorkLocation::HOME; });
Realm では、マップキーに.
または$
文字を使用できません。 パーセント エンコーディングとデコーディング を使用して、これらの許可されていない文字の 1 つを含むマップキーを保存できます。
// Percent encode . or $ characters to use them in map keys auto mapKey = "Monday.Morning"; auto encodedMapKey = "Monday%2EMorning";
モデル
サポートされているマップ データ型の詳細については、「マップ/辞書 」を参照してください。
namespace realm { struct Employee { enum class WorkLocation { HOME, OFFICE }; int64_t _id; std::string firstName; std::string lastName; std::map<std::string, WorkLocation> locationByDay; }; REALM_SCHEMA(Employee, _id, firstName, lastName, locationByDay) } // namespace realm
セット プロパティを持つオブジェクトの作成
Realm オブジェクトと同様に、セットプロパティを含むオブジェクトを作成できますが、セット プロパティを変更するには、書込みトランザクション内でのみです。 つまり、書込みトランザクション内でセットプロパティの値のみを設定できます。
auto realm = realm::db(std::move(config)); // Create an object that has a set property auto docsRealmRepo = realm::Repository{.ownerAndName = "mongodb/docs-realm"}; // Add the object to the database and get the managed object auto managedDocsRealm = realm.write([&]() { return realm.add(std::move(docsRealmRepo)); }); // Insert items into the set auto openPullRequestNumbers = {3059, 3062, 3064}; realm.write([&] { for (auto number : openPullRequestNumbers) { // You can only mutate the set in a write transaction. // This means you can't set values at initialization, // but must do it during a write. managedDocsRealm.openPullRequestNumbers.insert(number); } });
モデル
サポートされているセット データ型の詳細については、「セット 」を参照してください。
namespace realm { struct Repository { std::string ownerAndName; std::set<int64_t> openPullRequestNumbers; }; REALM_SCHEMA(Repository, ownerAndName, openPullRequestNumbers) } // namespace realm
非対称オブジェクトの作成
Data Ingestを介して Atlas App Services App にリンクされた Atlas データベースに一方向に同期する非対称オブジェクトを作成できます。 非対称オブジェクトにローカルにアクセスしたり、Realm から削除したり、クエリを実行したりすることはできません。
auto weatherSensorReading = realm::WeatherSensorReading{.deviceId = "WX1278UIT", .temperatureInFahrenheit = 64.7, .windSpeedInMph = 7}; realm.write([&] { realm.add(std::move(weatherSensorReading)); });
非対称オブジェクトの操作の詳細については、「 Atlas へのストリーム データ - C++ SDK 」を参照してください。
モデル
非対称オブジェクトの定義の詳細については、「 非対称オブジェクトの定義 」を参照してください。
struct WeatherSensorReading { realm::primary_key<realm::object_id> _id{realm::object_id::generate()}; std::string deviceId; double temperatureInFahrenheit; int64_t windSpeedInMph; }; REALM_ASYMMETRIC_SCHEMA(WeatherSensorReading, _id, deviceId, temperatureInFahrenheit, windSpeedInMph)