Как бы я смоделировать файловую систему в dexie.js? - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь создать виртуальную файловую систему, используя dexie.js. Каждый файл и каталог будет иметь как минимум 2 свойства, идентификатор и имя. Кроме того, файлы будут иметь свойство blob с содержимым файла. Однако я не знаю, следует ли хранить дочерние элементы каталога как многозначный индекс каталога или ссылаться на родительский элемент как индекс файла. Какой лучший выбор?

Мой предыдущий опыт работы с SQL говорит мне, что я должен идти с последним, но я не знаю, в каком случае IndexedDB справится лучше.

1 Ответ

0 голосов
/ 11 января 2019

Я бы порекомендовал иерархическую структуру, примерно такую:

const db = new Dexie('filesystem');
db.version(1).stores({
  files: `
    [parentDir+name],
    parentDir`
});

Используя составной индекс [parentDir + name], БД гарантирует, что никакие два элемента не будут иметь одинаковый путь.

Индексируя parentDir, вы можете перечислять как прямых, так и рекурсивных детей только с помощью индекса.

Некоторые примеры:

function createDir(parentDir, name) {
  // The following transaction will fail if
  // the combination parentDir+name already exists or
  // represents a file.
  return db.files.add({parentDir, name, type: "dir"});
}

function createFile(parentDir, filename, blob) {
  return db.transaction('rw', db.files, async ()=>{
    // Verify parentDir exists and is a directory:
    const dir = await db.files.get({
      parentDir: parentDir
    });
    if (!dir) throw new Error("Parent dir not found");
    if (dir.type !== 'dir') throw new Error("Parent is not a dir");
    await db.files.add({
      type: 'file',
      name: filename,
      parentDir,
      blob
    });
  });
}

/** List all files and folders within given diretory */
function listDirectory(dirPath) {
  return db.files
    .where({parentDir: dirPath})
    .toArray();
}

/** List all files and folders recursively within given diretory */
function listDirectoryRecursively(dirPath) {
  return db.files
    .where('parentDir')
    .startsWith(dirPath)
    .toArray();
}

Перемещение файла или каталога будет быстрым, поскольку вы можете получить доступ ко всему поддереву за один запрос.

function moveDirectory (oldParentDir, name, newParentDir) {
  return db.transaction('rw', db.files, async ()=>{

    // Move the directory itself:
    await db.files
      .where({parentDir: oldParentDir, name: name})
      .modify(item => item.parentDir = newDir);

    // Move all descendants:
    await db.files
      .where('parentDir')
      .startsWith(oldParentDir + "/" + name)
      .modify(item =>
        item.parentDir = newParentDir +
          item.parentDir.substr(oldParentDir.length) + // strip start
          "/" + item.name);
  });
}
...