diff --git a/package.json b/package.json index 20fe1ea..7353248 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "parcel-plugin-goodie-bag": "^2.0.0", "rimraf": "^3.0.0", "sass": "^1.24.0", + "sequelize-erd": "https://github.com/Alamantus/sequelize-erd.git", "sharp": "^0.23.4" }, "dependencies": { diff --git a/server/sequelize/db-diagram.svg b/server/sequelize/db-diagram.svg new file mode 100644 index 0000000..5c06a97 --- /dev/null +++ b/server/sequelize/db-diagram.svg @@ -0,0 +1,341 @@ + + + + + + +models_diagram + + + +PermissionLevel + + +PermissionLevel + +id: NUMBER + +name: STRING + +description: STRING + + + +User + + +User + +id: NUMBER + +email: STRING + +username: STRING + +displayName: STRING + +permissionLevel: NUMBER + +passwordHash: STRING + +passwordSalt: STRING + +accountConfirm: STRING + +createdAt: DATE + +updatedAt: DATE + + + +User->PermissionLevel + + + + + + +Follow + + +Follow + +id: NUMBER + +follower: NUMBER + +followerDomain: TEXT + +following: NUMBER + +followingDomain: TEXT + +createdAt: DATE + +updatedAt: DATE + + + +User->Follow + + + + + + +BookReference + + +BookReference + +id: NUMBER + +name: STRING + +description: STRING + +sources: JSON + +covers: JSON + + + +Shelf + + +Shelf + +id: NUMBER + +userId: NUMBER + +name: STRING + +permissionLevel: NUMBER + +isDeletable: BOOLEAN + +createdAt: DATE + +updatedAt: DATE + + + +Shelf->PermissionLevel + + + + + + +Shelf->User + + + + + + +ShelfItem + + +ShelfItem + +id: NUMBER + +shelfId: NUMBER + +bookId: NUMBER + +bookEdition: JSON + +order: NUMBER + +createdAt: DATE + +updatedAt: DATE + + + +ShelfItem->BookReference + + + + + + +ShelfItem->Shelf + + + + + + +Status + + +Status + +id: NUMBER + +userId: NUMBER + +permissionLevel: NUMBER + +text: TEXT + +shelfItemId: NUMBER + +progress: NUMBER + +createdAt: DATE + +updatedAt: DATE + + + +Status->PermissionLevel + + + + + + +Status->User + + + + + + +Status->ShelfItem + + + + + + +Reaction + + +Reaction + +id: NUMBER + +userId: NUMBER + +targetType: ENUM + +targetId: NUMBER + +reactionType: ENUM + +reaction: TEXT + +createdAt: DATE + +updatedAt: DATE + + + +Status->Reaction + + + + + + +Review + + +Review + +id: NUMBER + +userId: NUMBER + +permissionLevel: NUMBER + +text: TEXT + +bookReferenceId: NUMBER + +bookEdition: JSON + +rating: NUMBER + +createdAt: DATE + +updatedAt: DATE + + + +Review->PermissionLevel + + + + + + +Review->User + + + + + + +Review->BookReference + + + + + + +Review->Reaction + + + + + + +Recommendation + + +Recommendation + +id: NUMBER + +fromUser: NUMBER + +toUser: NUMBER + +text: TEXT + +bookId: NUMBER + +data: JSON + +createdAt: DATE + +updatedAt: DATE + +deletedAt: DATE + + + +Recommendation->User + + + + + + +Recommendation->BookReference + + + + + + diff --git a/server/sequelize/generate-db-diagram.js b/server/sequelize/generate-db-diagram.js new file mode 100644 index 0000000..29cc24d --- /dev/null +++ b/server/sequelize/generate-db-diagram.js @@ -0,0 +1,59 @@ +// Run with `node ./path/to/server/sequelize/generate-db-diagram.js` +(async function(){ + const path = require('path'); + const {writeFileSync} = require('fs'); + const Sequelize = require('sequelize'); + const sequelizeErd = require('sequelize-erd'); + + let siteConfig; + try { + siteConfig = require('../config.json'); + } catch (ex) { + console.error('Please copy `config.example.json` to `config.json` and fill it with your server\'s data.'); + process.exit(1); + } + + const sequelizeConfig = { + dialect: siteConfig.db_engine, + }; + switch (siteConfig.db_engine) { + case 'sqlite': { + sequelizeConfig.storage = typeof siteConfig.sqlite_location !== 'undefined' + ? ( + siteConfig.sqlite_location.substr(0, 1) === '.' // If relative path, make relative to ./server + ? path.resolve('../server/', siteConfig.sqlite_location) + : path.resolve(siteConfig.sqlite_location) + ) + : path.resolve(__dirname, '../server/database.sqlite'); + break; + } + default: { + sequelizeConfig.host = siteConfig.db_host; + sequelizeConfig.port = siteConfig.db_port; + sequelizeConfig.database = siteConfig.db_database; + sequelizeConfig.username = siteConfig.db_username; + sequelizeConfig.password = siteConfig.db_password; + } + } + + const sequelize = new Sequelize(sequelizeConfig); + require('./models')(sequelize); + + try { + const svg = await sequelizeErd({ + source: sequelize, + engine: 'dot', + arrowShapes: { + BelongsToMany: ['crow', 'crow'], + BelongsTo: ['crow', 'dot'], + HasMany: ['normal', 'crow'], + HasOne: ['dot', 'dot'], + }, + arrowSize: 1, + lineWidth: 1, + }); + writeFileSync(path.resolve(__dirname, './db-diagram.svg'), svg); + } catch (err) { console.error(err) } + + // Writes erd.svg to local path with SVG file from your Sequelize models + })() \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 2a1ebe0..0b7bc85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1684,7 +1684,7 @@ command-exists@^1.2.6: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== -commander@^2.11.0, commander@^2.19.0, commander@^2.20.0: +commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@^2.9.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -6295,6 +6295,12 @@ seq-queue@^0.0.5: resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" integrity sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4= +"sequelize-erd@https://github.com/Alamantus/sequelize-erd.git": + version "1.3.0" + resolved "https://github.com/Alamantus/sequelize-erd.git#c2def788e60e5976a96779ceb033da1c99ed97fa" + dependencies: + commander "^2.9.0" + sequelize-pool@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-2.3.0.tgz#64f1fe8744228172c474f530604b6133be64993d"