Comparing version 0.1.18-alpha.1 to 0.1.19-alpha.0
@@ -5,2 +5,7 @@ let currentConfig = { | ||
name: 'djorm', | ||
storages: { | ||
default: { | ||
driver: 'djorm/storage/FileSystemStorage' | ||
} | ||
}, | ||
logger: { | ||
@@ -30,2 +35,5 @@ level: 'info', | ||
await require('./init/logger').init(settings) | ||
if (settings.storages) { | ||
require('./init/storages').init(settings.storages) | ||
} | ||
if (settings.databases) { | ||
@@ -40,3 +48,4 @@ await require('./init/databases').init(settings.databases) | ||
require('./init/logger').shutdown() | ||
await require('./init/databases').shutdown() | ||
require('./init/storages').shutdown() | ||
require('./init/databases').shutdown() | ||
} | ||
@@ -43,0 +52,0 @@ |
@@ -1,7 +0,9 @@ | ||
const { DatabaseHub, instance } = require('../DatabaseHub') | ||
const hub = require('../DatabaseHub') | ||
const { ConnectionHub } = require('../../models/ConnectionHub') | ||
describe('DatabaseHub', () => { | ||
it('getPool returns pool instance', () => { | ||
expect(instance).toBeInstanceOf(DatabaseHub) | ||
expect(hub).toBeInstanceOf(ConnectionHub) | ||
}) | ||
}) |
const { DatabaseMapper } = require('./DatabaseMapper') | ||
const { NotImplemented } = require('../errors') | ||
const { PropModel } = require('./props') | ||
const { DriverModel } = require('../models/DriverModel') | ||
const { debug, trace } = require('../logger') | ||
class Database extends PropModel { | ||
class Database extends DriverModel { | ||
connected = false | ||
@@ -19,7 +19,2 @@ connecting = false | ||
static resolveDriver (dbConfig) { | ||
const Model = require(dbConfig.driver) | ||
return new Model(dbConfig) | ||
} | ||
getSchema () { | ||
@@ -26,0 +21,0 @@ return this.props.schema |
const { Database } = require('./Database') | ||
const { DatabaseError } = require('./errors') | ||
const { ConnectionHub } = require('../models/ConnectionHub') | ||
class DatabaseHub { | ||
databases = {} | ||
configDb (db, dbName = 'default') { | ||
if (db instanceof Database) { | ||
const existing = this.databases[dbName] | ||
if (existing) { | ||
existing.disconnect() | ||
} | ||
this.databases[dbName] = db | ||
} else { | ||
throw new DatabaseError( | ||
`Database "${dbName}" must be instance of Database` | ||
) | ||
} | ||
} | ||
async connectDb (db, dbName = 'default') { | ||
this.configDb(db, dbName) | ||
await this.connectDbInstance(dbName) | ||
} | ||
async connectDbInstance (dbName) { | ||
await this.databases[dbName].connect() | ||
} | ||
async disconnect () { | ||
await Promise.all(Object.values(this.databases).map(db => db.disconnect())) | ||
this.databases = {} | ||
} | ||
getDb (dbName) { | ||
const db = this.databases[dbName] | ||
if (!db) { | ||
throw new DatabaseError(`Database "${dbName}" is not available`) | ||
} | ||
return db | ||
} | ||
class DatabaseHub extends ConnectionHub { | ||
ErrorClass = DatabaseError | ||
ItemClass = Database | ||
} | ||
let hubSingleton = new DatabaseHub() | ||
module.exports = { | ||
DatabaseHub, | ||
connect: async (...args) => await hubSingleton.connectDb(...args), | ||
disconnect: async () => await hubSingleton.disconnect(), | ||
getDb: name => hubSingleton.getDb(name), | ||
configDb: (db, dbName) => hubSingleton.configDb(db, dbName), | ||
get instance () { | ||
return hubSingleton | ||
}, | ||
set instance (hub) { | ||
hubSingleton = hub | ||
} | ||
} | ||
module.exports = new DatabaseHub() |
const { And } = require('./And') | ||
const { DatabaseModelBase } = require('../models/DatabaseModelBase') | ||
const { filterUnique } = require('../filters') | ||
const { ImmutablePropModel } = require('./props') | ||
const { ImmutablePropModel } = require('../models/PropModel') | ||
const { parseFieldObjects } = require('../models/AttrModel') | ||
@@ -6,0 +6,0 @@ const { Q } = require('./QueryCondition') |
@@ -1,2 +0,2 @@ | ||
const { ImmutablePropModel } = require('./props') | ||
const { ImmutablePropModel } = require('../models/PropModel') | ||
const { LogicOperator } = require('./LogicOperator') | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
const { ImmutablePropModel } = require('./props') | ||
const { ImmutablePropModel } = require('../models/PropModel') | ||
@@ -3,0 +3,0 @@ class QueryIdentifier extends ImmutablePropModel { |
@@ -1,2 +0,2 @@ | ||
const { ImmutablePropModel } = require('./props') | ||
const { ImmutablePropModel } = require('../models/PropModel') | ||
@@ -3,0 +3,0 @@ class QueryShortcut extends ImmutablePropModel {} |
@@ -21,2 +21,4 @@ function formatObject (obj) { | ||
class ModelError extends DjormError {} | ||
class ConnectionError extends DjormError {} | ||
class StorageError extends DjormError {} | ||
@@ -92,2 +94,3 @@ class FieldError extends ModelError {} | ||
ConfigError, | ||
ConnectionError, | ||
DjormError, | ||
@@ -102,2 +105,3 @@ FieldError, | ||
serializeError, | ||
StorageError, | ||
UnknownField, | ||
@@ -104,0 +108,0 @@ ValidationError, |
@@ -0,38 +1,16 @@ | ||
const storageHub = require('../storage/StorageHub') | ||
const { v4 } = require('uuid') | ||
const { basename } = require('path') | ||
const { AttrModel, Field } = require('../models/AttrModel') | ||
const { createReadStream } = require('fs') | ||
const { CharField } = require('./CharField') | ||
const { ObjectField } = require('./ObjectField') | ||
const { ConfigError } = require('../errors') | ||
const { pipeline } = require('stream') | ||
let systemDefaultStorage = null | ||
function getSystemDefaultStorage () { | ||
if (!systemDefaultStorage) { | ||
throw new ConfigError( | ||
'Default system storage needs to be configured to use FileField' | ||
) | ||
} | ||
return systemDefaultStorage | ||
} | ||
function setSystemDefaultStorage (storage) { | ||
systemDefaultStorage = storage | ||
} | ||
function getFieldValue (inst, fieldName) { | ||
return fieldName && inst.get(fieldName) | ||
} | ||
class FileStorage extends AttrModel { | ||
getReadStream (filePath) {} | ||
getWriteStream (filePath) {} | ||
async exists (filePath) {} | ||
async read (filePath) {} | ||
async readMeta (filePath) {} | ||
async write (filePath, data) {} | ||
} | ||
class File extends AttrModel { | ||
static storage = new ObjectField({ model: FileStorage }) | ||
static storageName = new CharField({ default: 'default' }) | ||
static basePath = new CharField() | ||
static name = new CharField() | ||
static src = new Field() | ||
@@ -51,2 +29,6 @@ static meta = { | ||
get storage () { | ||
return storageHub.get(this.storageName) | ||
} | ||
get writeStream () { | ||
@@ -56,33 +38,66 @@ return this.storage.getWriteStream(this.filePath) | ||
async exists () { | ||
return await this.storage.exists(this.filePath) | ||
exists = () => this.storage.exists(this.filePath) | ||
read = () => this.storage.read(this.filePath) | ||
readMeta = () => this.storage.readMeta(this.filePath) | ||
write = data => this.storage.write(this.filePath, data) | ||
save = async () => { | ||
if (this.src) { | ||
const src = | ||
this.src.pipe instanceof Function | ||
? this.src | ||
: createReadStream(this.src) | ||
await new Promise((resolve, reject) => | ||
pipeline(src, this.writeStream, e => { | ||
if (e) { | ||
console.log('REJECT HERE') | ||
reject(e) | ||
} else { | ||
resolve() | ||
} | ||
}) | ||
) | ||
} | ||
} | ||
} | ||
async read () { | ||
return await this.storage.read(this.filePath) | ||
class FileField extends Field { | ||
static fileField = true | ||
static basePath = new CharField() | ||
static model = new ObjectField({ default: () => File, model: Object }) | ||
static storageName = new CharField({ default: 'default' }) | ||
db = true | ||
get storage () { | ||
return storageHub.get(this.storageName) | ||
} | ||
async readMeta () { | ||
return await this.storage.readMeta(this.filePath) | ||
parse (value, inst) { | ||
if (value) { | ||
return this.get('model').from({ | ||
storageName: this.get('storageName'), | ||
basePath: this.get('basePath'), | ||
name: | ||
(typeof value === 'string' ? basename(value) : value.name) || v4(), | ||
src: typeof value === 'string' ? value : value.src | ||
}) | ||
} | ||
} | ||
async write (data) { | ||
return await this.storage.write(this.filePath, data) | ||
toDb (value) { | ||
if (value) { | ||
console.log('toDb', value, value.name) | ||
return value.name | ||
} | ||
return super.toDb(value) | ||
} | ||
} | ||
class FileField extends Field { | ||
static basePath = new CharField() | ||
static model = new ObjectField({ default: () => File, model: Object }) | ||
static storage = new ObjectField({ model: FileStorage, null: true }) | ||
static defaultStorage = new ObjectField({ | ||
default: getSystemDefaultStorage, | ||
model: FileStorage | ||
}) | ||
resolveStorage () { | ||
return this.get('storage') || this.get('defaultStorage') | ||
async saveFileValue (inst, fieldName, value) { | ||
if (value) { | ||
await value.save() | ||
} | ||
} | ||
} | ||
const getFieldValue = (inst, fieldName) => fieldName && inst.get(fieldName) | ||
class NamedFileField extends FileField { | ||
@@ -94,7 +109,10 @@ static nameField = new Field() | ||
parse (value, inst) { | ||
return this.get('model').from({ | ||
storage: this.resolveStorage(this), | ||
basePath: getFieldValue(inst, this.basePathField) || this.get('basePath'), | ||
name: getFieldValue(inst, this.nameField) | ||
}) | ||
if (value) { | ||
return this.get('model').from({ | ||
storageName: this.storageName, | ||
basePath: | ||
getFieldValue(inst, this.basePathField) || this.get('basePath'), | ||
name: getFieldValue(inst, this.nameField) || v4() | ||
}) | ||
} | ||
} | ||
@@ -108,8 +126,5 @@ | ||
module.exports = { | ||
getSystemDefaultStorage, | ||
setSystemDefaultStorage, | ||
File, | ||
FileStorage, | ||
FileField, | ||
NamedFileField | ||
} |
@@ -1,13 +0,4 @@ | ||
const init = async databases => { | ||
const { Database } = require('../db/Database') | ||
const { configDb } = require('../db/DatabaseHub') | ||
Object.entries(databases).map(([dbName, dbConfig]) => | ||
configDb(Database.resolveDriver(dbConfig), dbName) | ||
) | ||
} | ||
const init = databases => require('../db/DatabaseHub').addInstances(databases) | ||
const shutdown = () => require('../db/DatabaseHub').destroy() | ||
const shutdown = async () => { | ||
await require('../db/DatabaseHub').disconnect() | ||
} | ||
module.exports = { init, shutdown } |
const { DatabaseModelBase } = require('./DatabaseModelBase') | ||
const { Delete } = require('../db/Delete') | ||
const { ForeignKey } = require('../fields/ForeignKey') | ||
const { getDb } = require('../db/DatabaseHub') | ||
const { Insert } = require('../db/Insert') | ||
@@ -18,2 +17,3 @@ const { ObjectManager } = require('./ObjectManager') | ||
const databaseHub = require('../db/DatabaseHub') | ||
const nonEmpty = item => Boolean(item) | ||
@@ -42,3 +42,3 @@ | ||
static get db () { | ||
return getDb(this.dbName) | ||
return databaseHub.get(this.dbName) | ||
} | ||
@@ -169,4 +169,13 @@ | ||
async saveFiles () { | ||
await Promise.all( | ||
this.constructor.fieldObjects | ||
.filter(([name, field]) => field.saveFileValue) | ||
.map(([name, field]) => field.saveFileValue(this, name, this.get(name))) | ||
) | ||
} | ||
async create () { | ||
await this.saveForeignKeys() | ||
await this.saveFiles() | ||
const cascade = this.serializeDbValues() | ||
@@ -190,2 +199,3 @@ let inject = {} | ||
await this.saveForeignKeys() | ||
await this.saveFiles() | ||
const cascade = this.serializeDbValues() | ||
@@ -192,0 +202,0 @@ for (const row of cascade) { |
{ | ||
"name": "djorm", | ||
"version": "0.1.18-alpha.1", | ||
"version": "0.1.19-alpha.0", | ||
"description": "Django like ORM framework", | ||
"author": "Pavel Žák <pavel@zak.global>", | ||
"homepage": "https://github.com/just-paja/djorm#readme", | ||
"homepage": "https://just-paja.github.io/djorm", | ||
"license": "ISC", | ||
@@ -40,5 +40,6 @@ "main": "index.js", | ||
"pino": "^6.11.3", | ||
"pino-pretty": "^5.0.2" | ||
"pino-pretty": "^5.0.2", | ||
"uuid": "^9.0.0" | ||
}, | ||
"gitHead": "f3a01cf12213650617ae9a2c554776d9cb6a38d5" | ||
"gitHead": "96cea85017466c1f3099c236f2e0a38623225629" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
89893
83
3103
6
4
+ Addeduuid@^9.0.0
+ Addeduuid@9.0.1(transitive)