fremail / sequelize-nested-set

Library to store and manage nested set trees using Sequelize
MIT License
39 stars 10 forks source link

Add example with full working code that creates some Nested Set structure #31

Open MurzNN opened 2 years ago

MurzNN commented 2 years ago

Now we have a lof of examples for exact functions, but not the main "quick start" example that shows the code, that works out-of-the-box.

So I suggest to add a "Quick start" one-file example with full index.js file, that requires sequelize library, creates a connection, creates Tag nested set, adds some elements to it, then moves some to other branch, etc.

MurzNN commented 2 years ago

For example, I'm trying to do a quickstart using this code from https://github.com/fremail/sequelize-nested-set#getting-started

const ns = require('sequelize-nested-set');

module.exports = (sequelize, DataTypes) => {
    const Tag = ns(sequelize, DataTypes, 'Tag', {
        label: DataTypes.STRING,
    }, {
        tableName: 'tag',
        timestamps: false,
        hasManyRoots: true,
    });

    // add additional methods, associations to the model

    return Tag;
};

But got the error on line label: DataTypes.STRING:

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'STRING' of undefined
MurzNN commented 2 years ago

What do you think about adding this code as quick start example?

const { Sequelize, DataTypes, queryInterface } = require("sequelize");
const ns = require('sequelize-nested-set');

(async () => {

  const sequelize = new Sequelize({
    dialect: 'sqlite',
    storage: 'database.sqlite'
  });

  await sequelize.authenticate();

  await sequelize.getQueryInterface().dropAllTables();

  const Tag = ns(sequelize, DataTypes, 'Tag', {
    label: DataTypes.STRING,
  }, {
    tableName: 'tag',
    levelColumnName: 'depth',
    // timestamps: false,
    hasManyRoots: true,
    // hasManyRoots: false,
  });

  Tag.sync();

  const printTree = async function (ns) {
    const items = await ns.fetchTree(10);
    let strings = [];
    for (let item of items) {
      // console.log(item)
      let parent = await item.getParent();
      strings.push(("- ".repeat(item.level) + `${item.label} [id ${item.id}, parentId ` + (parent.id || '-') + `]`));
    }
    console.log(strings.join("\n"));
  }

  let tagElectronics = new Tag(); tagElectronics.label = 'Electronics';
  tagElectronics = await Tag.createRoot(tagElectronics);

  let tagPhones = new Tag(); tagPhones.label = 'Phones';
  await tagElectronics.reload();
  await tagElectronics.addChild(tagPhones);

  let tagTVs = new Tag(); tagTVs.label = 'TVs';
  await tagElectronics.reload();
  await tagElectronics.addChild(tagTVs);

  let tagSamsung = new Tag(); tagSamsung.label = 'Samsung';
  await tagTVs.reload();
  await tagTVs.addChild(tagSamsung);

  let tagApple = new Tag(); tagApple.label = 'Apple';
  await tagTVs.reload();
  await tagTVs.addChild(tagApple);

  let tagXiaomi = new Tag(); tagXiaomi.label = 'Xiaomi';
  await tagPhones.reload();
  await tagPhones.addChild(tagXiaomi);

  let tagAppleIphones = new Tag(); tagAppleIphones.label = 'IPhones';
  await tagApple.reload();
  await tagApple.addChild(tagAppleIphones);

  await printTree(Tag);

  console.log('Moving tag Apple (id ' + tagApple.id + ') from TVs (id ' + tagTVs.id + ') to Phones (id ' + tagPhones.id + ').');
  await tagApple.reload();
  await tagApple.moveAsFirstChildOf(tagPhones);

  await printTree(Tag);
})();

It should return this output:

Electronics [id 1, parentId -]
- Phones [id 2, parentId 1]
- - Xiaomi [id 6, parentId 2]
- TVs [id 3, parentId 1]
- - Apple [id 5, parentId 3]
- - - IPhones [id 7, parentId 5]
- - Samsung [id 4, parentId 3]

Moving tag Apple (id 5) from TVs (id 3) to Phones (id 2).
Electronics [id 1, parentId -]
- Phones [id 2, parentId 1]
- - Apple [id 5, parentId 2]
- - - IPhones [id 7, parentId 5]
- - Xiaomi [id 6, parentId 2]
- TVs [id 3, parentId 1]
- - Samsung [id 4, parentId 3]
xuanngo2001 commented 2 years ago

@MurzNN there are error with your example. When ran, I got the following error:

Executing (default): SELECT 1+1 AS result
Executing (default): SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';
Executing (default): PRAGMA foreign_keys = OFF
Executing (default): DROP TABLE IF EXISTS `tag`;
Executing (default): PRAGMA foreign_keys = ON
Executing (default): SELECT name FROM sqlite_master WHERE type='table' AND name='tag';
Executing (default): INSERT INTO `tag` (`id`,`lft`,`rgt`,`depth`,`root_id`,`label`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4,$5,$6,$7);
Executing (default): CREATE TABLE IF NOT EXISTS `tag` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `lft` INTEGER NOT NULL DEFAULT 1, `rgt` INTEGER NOT NULL DEFAULT 2, `depth` INTEGER NOT NULL, `root_id` INTEGER NOT NULL, `label` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT 
NULL);
node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

Error
    at C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\dialects\sqlite\query.js:177:50
    at new Promise (<anonymous>)
    at Query.run (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\dialects\sqlite\query.js:177:12)
    at C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\sequelize.js:311:28
    at async SQLiteQueryInterface.insert (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\dialects\abstract\query-interface.js:308:21)
    at async model.save (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\model.js:2432:35)
    at async Function.Model.createRoot (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize-nested-set\index.js:78:9)
    at async C:\xuan\vbox-shared\github-projects\treeorg\nested-sets-8.js:39:20 {
  name: 'SequelizeDatabaseError',
  parent: [Error: SQLITE_ERROR: no such table: tag] {
    errno: 1,
    code: 'SQLITE_ERROR',
    sql: 'INSERT INTO `tag` (`id`,`lft`,`rgt`,`depth`,`root_id`,`label`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4,$5,$6,$7);'
  },
  original: [Error: SQLITE_ERROR: no such table: tag] {
    errno: 1,
    code: 'SQLITE_ERROR',
    sql: 'INSERT INTO `tag` (`id`,`lft`,`rgt`,`depth`,`root_id`,`label`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4,$5,$6,$7);'
  },
  sql: 'INSERT INTO `tag` (`id`,`lft`,`rgt`,`depth`,`root_id`,`label`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4,$5,$6,$7);',
  parameters: {}
}
Error: near line 1: in prepare, no such table: Trees (1)
PS C:\xuan\vbox-shared\github-projects\treeorg> rm treeorg.sqlite -force; node .\nested-sets-8.js; 'Select * from Trees' | sqlite3 -column -header treeorg.sqlite
Executing (default): SELECT 1+1 AS result
Executing (default): SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';
Executing (default): PRAGMA foreign_keys = OFF
Executing (default): PRAGMA foreign_keys = ON
Executing (default): SELECT name FROM sqlite_master WHERE type='table' AND name='tag';
Executing (default): INSERT INTO `tag` (`id`,`lft`,`rgt`,`depth`,`root_id`,`label`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4,$5,$6,$7);
Executing (default): CREATE TABLE IF NOT EXISTS `tag` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `lft` INTEGER NOT NULL DEFAULT 1, `rgt` INTEGER NOT NULL DEFAULT 2, `depth` INTEGER NOT NULL, `root_id` INTEGER NOT NULL, `label` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT 
NULL);
node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

Error
    at Database.<anonymous> (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\dialects\sqlite\query.js:179:27)
    at C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\dialects\sqlite\query.js:177:50
    at new Promise (<anonymous>)
    at Query.run (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\dialects\sqlite\query.js:177:12)
    at C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\sequelize.js:311:28
    at async SQLiteQueryInterface.insert (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\dialects\abstract\query-interface.js:308:21)
    at async model.save (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize\lib\model.js:2432:35)
    at async Function.Model.createRoot (C:\xuan\vbox-shared\github-projects\treeorg\node_modules\sequelize-nested-set\index.js:78:9)
    at async C:\xuan\vbox-shared\github-projects\treeorg\nested-sets-8.js:39:20 {
  name: 'SequelizeDatabaseError',
  parent: [Error: SQLITE_ERROR: no such table: tag] {
    errno: 1,
    code: 'SQLITE_ERROR',
    sql: 'INSERT INTO `tag` (`id`,`lft`,`rgt`,`depth`,`root_id`,`label`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4,$5,$6,$7);'
  },
  original: [Error: SQLITE_ERROR: no such table: tag] {
    errno: 1,
    code: 'SQLITE_ERROR',
    sql: 'INSERT INTO `tag` (`id`,`lft`,`rgt`,`depth`,`root_id`,`label`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4,$5,$6,$7);'
  },
  sql: 'INSERT INTO `tag` (`id`,`lft`,`rgt`,`depth`,`root_id`,`label`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4,$5,$6,$7);',
  parameters: {}
}