Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

CRUD - 作成 - C++ SDK

項目一覧

  • 書込みトランザクション (write transaction)
  • 新しいオブジェクトの作成
  • オブジェクトの作成
  • 埋め込みオブジェクトの作成
  • 対 1 の関係を持つオブジェクトの作成
  • ToMany の関係を持つオブジェクトの作成
  • 逆の関係を持つオブジェクトの作成
  • マップ プロパティを持つオブジェクトの作成
  • セット プロパティを持つオブジェクトの作成
  • 非対称オブジェクトの作成

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 の関係を持つオブジェクトを作成するには、関連オブジェクトの未加工のポインターをメイン オブジェクトの関係プロパティに割り当てます。 書込みトランザクション (write transaction) 内でRealm.add() 関数を使用してオブジェクトを Realm に移動します。

この例では、関連オブジェクト - FavoriteToy * - の未加工のポインターを、メイン オブジェクトの関係 - Dog.favoriteToyに割り当てます。 次に、 dogオブジェクトを Realm に追加すると、 dogfavoriteToyの両方が 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)

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)

戻る

CRUD - C++ SDK