domain-js-将本地领域数据复制到同步领域

2022-02-25 00:00:00 javascript react-native realm
我正在使用realm-js将用户的数据存储在其具有Reaction Native的设备上,并且在工作流中有一个点,我希望将本地领域中的所有数据复制到同步领域中(以在ROS上持久化)。我遇到了一个问题,在我们的模式中,我们通过将引用一个对象的属性添加到另一个对象(反之亦然)来创建伪关系,并且在这样做的过程中,我们创建了循环数据结构。

这在应用程序中实际上工作得很好,但现在我们尝试将数据从本地领域复制到同步领域,但似乎是因为循环引用而崩溃。

例如,架构如下所示。

class Person extends Realm.Object {}
Person.schema = {
  name: 'Person',
  properties: {
    firstName: {
      type: 'string',
      optional: true,
    },
    staffAccount: {
      type: 'StaffAccount'
    },
  },
};

class StaffAccount extends Realm.Object {}
StaffAccount.schema = {
  name: 'StaffAccount',
  properties: {
    id: {
      type: 'string',
    },
    people: {
      type: 'list',
      objectType: 'Person',
    },
  },
};

在此示例中,在创建人员时,您将定义Staff Account属性,该人员帐户属性将具有一个People属性,其中包含拥有该人员帐户的人员列表,并且在该列表中将有Person架构中的人员初始人员。

将数据从一个领域复制到另一个领域时,是否有解决此问题的方法?


解决方案

查看此代码,该代码获取本地.realm文件并将其复制到远程同步领域。代码可以简化,因为看起来您已经知道该模式-此代码动态加载该模式。希望能有所帮助

// Copy local realm to ROS

const Realm = require('realm');


// UPDATE THESE
const realm_server = 'localhost:9080';

const source_realm_path = './localRealm.realm'; // path on disk
const target_realm_path = '/syncRealm'; // path on server


function copyObject(obj, objSchema, targetRealm) {
    const copy = {};
    for (var key in objSchema.properties) {
        const prop = objSchema.properties[key];
        if (prop.type == 'list') {
            const propObjSchema = targetRealm.schema.find((s) => s.name == prop.objectType)
            copy[key] = obj[key].map((obj) => copyObject(obj, propObjSchema, targetRealm))
        }
        else if (prop.type == 'object') {
            const propObjSchema = targetRealm.schema.find((s) => s.name == prop.objectType)
            copy[key] = obj[key] ? copyObject(obj[key], propObjSchema, targetRealm) : obj[key];
        }
        else {
            copy[key] = obj[key];
        }
    }
    return copy;
}

function getMatchingObjectInOtherRealm(sourceObj, source_realm, target_realm, class_name) {
    const allObjects = source_realm.objects(class_name);
    const ndx = allObjects.indexOf(sourceObj);

    // Get object on same position in target realm
    return target_realm.objects(class_name)[ndx];
}

function addLinksToObject(sourceObj, targetObj, objSchema, source_realm, target_realm) {
    for (var key in objSchema.properties) {
        const prop = objSchema.properties[key];
        if (prop.hasOwnProperty('objectType')) {
            if (prop['type'] == "list") {
                var targetList = targetObj[key];
                sourceObj[key].forEach((linkedObj) => {
                    const obj = getMatchingObjectInOtherRealm(linkedObj, source_realm, target_realm, prop.objectType);
                    targetList.push(obj);
                });
            }
            else {
                // Find the position of the linked object
                const linkedObj = sourceObj[key];
                if (linkedObj === null) {
                    continue;
                }

                // Set link to object on same position in target realm
                targetObj[key] = getMatchingObjectInOtherRealm(linkedObj, source_realm, target_realm, prop.objectType);
            }
        }
    }
}

function copyRealm(user, local_realm_path, remote_realm_url) {
    // Open the local realm
    const source_realm =  new Realm({path: local_realm_path});

    // Create the new realm (with same schema as the source)
    const target_realm = new Realm({
        sync: {
            user: user,
            url:  remote_realm_url,
        },
        schema: require('./realmmodels')
    });

    // Copy all objects but ignore links for now
    target_realm.schema.forEach((objSchema) => {
        console.log("copying objects:", objSchema['name']);
        const allObjects = source_realm.objects(objSchema['name']);
        target_realm.write(() => 
          allObjects.forEach((obj) => {
              // Add this object to the target realm
                  target_realm.create(objSchema.name, copyObject(obj, objSchema, target_realm), true)
        }));
    });
}

const remote_realm_url = "realm://" + realm_server + target_realm_path;
copyRealm(Realm.Sync.User.adminUser("ADMIN_TOKEN"), 
    source_realm_path, remote_realm_url);
console.log("done");

相关文章