jugglingdb - Setting the primary key field - jugglingdb

Is it possible to set what field should be the "id" field? I'm defining my scheme with:
var Person = app.ormDb.define('person', {
id : { type: String, index: true, default: function () { return uuid.v4(); } },
oAuthID : { type: String, index: true },
name : { type: String },
gender : { type: String },
birth : { type: Date },
email : { type: String },
imageID : { type: String },
favorites : { type: JSON, default: function() { return {cars : [], animals : []}; } },
date : { type: Date, default: function() { return new Date(); } },
updated : { type: Date, default: function() { return new Date(); } }
});
and my defined id field shows up in MongoDB but when I use jugglingdb to lookup a person the returned value for Person.id is the MongoDB _id ObjectId value. so my id is hidden.

_id is reserved in MongoDB as the primary key. This would explain why it can't be changed. You can place any value into this as long as it's unique. Hope that helps.
There is also currently an open issue in the jugglingdb-mongodb adapter. That addresses the reason why id is not returned. Basically if object.id exists when calling create it is removed before insert into the collection.

Related

Can I validate the length of something by middy?

const baseHandler: APIGatewayProxyHandlerV2 = async (event) => {
return service.create(event.body);
}
const inputSchema = {
type: "object",
properties: {
body: {
type: "object",
properties: {
year: { type: "number" },
questionId: { type: "string" },
propSeq: { type: "number" },
questionTitle: { type: "string" },
propContent: { type: "string" },
isTrue: { type: "boolean" },
chapter: { type: "number" }
},
required: ["year", "questionId", "propSeq", "questionTitle", "propContent", "isTrue", "chapter"],
},
},
};
export const handler = middy(baseHandler)
.use(jsonBodyParser())
.use(validator({inputSchema}))
.use(httpErrorHandler())
I'm writing AWS Lambda code on Serverless Framework.
I wanted request body validator like express-validator, so I found middy.
But it looks impossible to validate the length of something.
I want to force the length of year to 4.
for example, 2023(o), 23(x)
properties: {
year: { type: "number", length: 4 }
}
As you guess, length property cannot be understood.
I don't want to add some codes to baseHandler function to validate the length.
Thank you in advance.
Middy uses JSONSchema, so you can use anything that is compatible with JSONSchema there. You could use length, but then you'd need to switch the type to string from number, as length is not supported for number (rightfully so in my opinion). If you want to keep it as number, then probably using range-based validation is your best bet: https://json-schema.org/understanding-json-schema/reference/numeric.html#range

Problem with setting a value in foreign key column

I'm using Sequelize.js with SQLite-database and faced a question with setting a value for foreign key. I have the following code:
const MessageModel = sequelize.define('MessageModel ', {
uuid: DataTypes.STRING,
authorId: DataTypes.STRING,
// ... other props
}, {});
const TodoModel = sequelize.define('TodoModel', {
ownerId: DataTypes.STRING,
status: {
type: DataTypes.STRING,
defaultValue: 'pending'
}
}, {});
TodoModel.belongsTo(MessageModel , {
foreignKey: {
name: 'messageId',
field: 'messageId',
allowNull: false
},
targetKey: 'uuid'
});
MessageModel.create({
uuid: 'testUUIDForExample'
// other props
}).then(message => {
console.log(`Message's created successful`);
TodoModel.create({
ownerId: 'id-string',
status: 'test-status',
messageId: 'testUUIDForExample'
})
})
Sequelize creates MessageModel-row in DB, but it falls when it's trying to generate TodoModel with this err:
DatabaseError: SQLITE_ERROR: foreign key mismatch - "TodoModel" referencing "MessageModel "
at Query.formatError (C:\Users\lrsvo\web-development\projects\platoon-web-electron\node_modules\sequelize\lib\dialects\sqlite\query.js:432:16)
at Query._handleQueryResponse (C:\Users\lrsvo\web-development\projects\platoon-web-electron\node_modules\sequelize\lib\dialects\sqlite\query.js:77:18)
at afterExecute (C:\Users\lrsvo\web-development\projects\platoon-web-electron\node_modules\sequelize\lib\dialects\sqlite\query.js:260:31)
at Statement.errBack (C:\Users\lrsvo\web-development\projects\platoon-web-electron\node_modules\sqlite3\lib\sqlite3.js:16:21)
Err.original.message: "SQLITE_ERROR: foreign key mismatch - "TodoModel" referencing "MessageModel"
Generated SQL:
"INSERT INTO `TodoModel` (`id`,`ownerId`,`status`,`createdAt`,`updatedAt`,`messageId`) VALUES (NULL,$1,$2,$3,$4,$5);"
My TodoModel table looks like:
CREATE TABLE "TodoModel" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"ownerId" VARCHAR(255),
"status" TEXT DEFAULT 'pending',
"createdAt" DATETIME NOT NULL,
"updatedAt" DATETIME NOT NULL,
"messageId" VARCHAR(255) NOT NULL,
FOREIGN KEY("messageId") REFERENCES "MessageModel"("uuid") ON DELETE NO ACTION ON UPDATE CASCADE
);
I can't get why is the err occurs and need help, cause I'm dummy in this ORM.
I'm using "sequelize": "^5.1.0" with SQLite.
MyConfig file:
const Sequelize = require("sequelize");
const electron = require('electron');
const storagePath = electron.app.getPath('userData') + '/plt.db';
module.exports = {
development: {
dialect: "sqlite",
storage: storagePath,
username: null,
password: null,
operatorsAliases: Sequelize.Op,
define: { freezeTableName: true },
query: { raw: true }, // Always get raw result
logging: true,
},
};
There are a copuple of things here. First If you are going to use uuid on MessageModel as primary key, you have to define it, otherwise you'll have a default id field.
const MessageModel = sequelize.define('MessageModel ', {
uuid:{ // if this is your primary key you have to define it
type: DataTypes.STRING, //there is also DataTypes.UUID
allowNull: false,
primaryKey: true,
unique: true
},
authorId: DataTypes.STRING,
// ... other props
}, {});
Then on your TodoModel, you are setting the messageId association as integer. To change it to string, you have to define the field on the model, and on the association use it as a foreign key.
const TodoModel = sequelize.define('TodoModel', {
ownerId: DataTypes.STRING,
status: {
type: DataTypes.STRING,
defaultValue: 'pending'
},
messageId: { //you also have to add the field on your model and set it as STRING, because on the association Sequelize by default is going to use INTEGER
type: DataTypes.STRING,
allowNull: false
}
}, {});
TodoModel.belongsTo(MessageModel , {
as: 'Message',
foreignKey: 'messageId', // and you only set the foreignKey - Same name as your field above
});

Is it possible to atomically add several items to DynamoDB array with checking their occurance in it (to avoid duplication)?

I have email black list stored as one item in DynamoDB
// item example
{
id: "blackList" // PrimaryKey of item
list: [ "email_1#example.com", "email_2#example.com" ]
}
It is possible to add new email to the list and the same time check if it's not already presented in the list (to avoid duplication) by atomic update:
const email = "email_new#example.com";
const params = {
TableName: "myTable",
Key: {
id: "blackList"
},
AttributeUpdates: {
list: {
Action: "ADD",
Value: [email] // several emails can also be added with incorrect Expected check
},
},
Expected: {
list: {
ComparisonOperator: "NOT_CONTAINS",
Value: email
},
}
};
await docClient.update(params).promise();
The question is whether it's possible to perform the same atomic operation for several emails at once?
Use a string set if you want there to be no duplicates. If you want to see if they existed in the set before you added them, return the old item.
const email = "email_new#example.com";
const params = {
TableName: "myTable",
Key: {
id: "blackList"
},
UpdateExpression: "ADD #email :email",
ExpressionAttributeNames: {
"#email": "email"
},
ExpressionAttributeValues: {
":email": docClient.createSet(email)
}
};
await docClient.update(params).promise();
This will add the email_new#example.com to the email attribute as a string set. If the email attribute doesn't exist on the object it will be created.
See https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.ADD for the documentation.

Vue.js Change placeholder in template dynamically

I want change the placeholder in a template dynamically over the input of a textbox but it not work after change the value. Initial it work perfect.
Demo
https://jsfiddle.net/he4gx40g/
Update: Working example thanks #Roy J
https://jsfiddle.net/z3gbk0L2/
Example of the component (without the textbox logic)
<customValueComponent :item="config" :value="'ConfigValue1'" />
Code of the customValue component
customValueComponent: {
props: {
item: {
type: Object,
required: true
},
value: {
type: String,
required: true
}
},
watch: {
value: function (newVal, oldVal) { // watch it
console.log('Prop changed: ', newVal, ' | was: ', oldVal)
this.$options.template = '<div>{{ item.' + this.value + '}}</div>';
}
},
created: function () {
this.$options.template = '<div>{{ item.' + this.value + '}}</div>';
},
template: ''
}
Object
var config =
{
ConfigValue1: "Titanium",
ConfigValue2: "Gold",
ConfigValue3: "Silver",
ConfigValue4: "Bronze",
ConfigValue5: "Copper",
...
};
$options is read-only. This is not how you change values in a template. Vue updates values as they change. Your component definition should be
Vue.component('customvalue-component', {
props: {
item: {
type: Object,
required: true
},
value: {
type: String,
required: true,
}
},
template: '<div>{{value}}</div>'
});
And your binding on the component should be
<customvalue-component :item="config" :value="config[value1]" />

How to conditionally pass in a picture AND a child component's string

a Vue newbie here. I am constructing a navbar-brand element as part of my navbar.
<template>
<!--Navbar-->
<navbar position="top" className="red">
<!-- Navbar brand -->
<navbar-brand></navbar-brand>
...
I would like it to display its child - a string passed in between the tags, if present AND a picture, if the prop.src is not empty. How do I do that - how do I condition the render function? The code is here:
import classNames from 'classnames';
export const props = {
tag: {
type: String,
default: "a"
},
src: {
type: String,
required: true
},
alt: {
type: String,
default: 'brand logo'
},
href: {
type: String,
default: '#'
},
className: {
type: String
}
};
export default {
functional: true,
props,
render(h, { props, data, children }) {
const dataObj = {
class: classNames(
'navbar-brand',
props.className ? props.className : ''
),
attrs: {
href: 'props.href'
}
};
const img = [
h('img', {
class: [],
attrs: {
src: props.src,
alt: props.alt
}
})
];
const
return h(props.tag, dataObj, img);
}
};
PLS HALP
Yours, Paco