TypeOrm condition on queryBuilder and entityManager preforms differently - typeorm

I found these queries have different result but the logics should be same, did I do something wrong or it is a bug?
console.log(
await em
.createQueryBuilder(OrderItemEntity, 'orderItem')
.where({ id: orderItem.id })
.andWhere({ ownedByInvoice: IsNull() })
.getCount(),
); //->0 correct, expected result
console.log(
await em.count(OrderItemEntity, {
where: { id: orderItem.id, ownedByInvoice: IsNull() },
}),
); //->1 incorrect, count the one has ownedByInvoice

Try enabling query level logging(Logging | TypeORM) in TypeORM and you can find out what is the query generated by TypeORM

Related

Neo4j set Label via neo4j driver query

Hi how can I set Label in query;
exports.addNewLabel = function(req, res) {
session
.run("MATCH (n:User {id:{userId}}) SET n:{newLabel} RETURN n", {
userId: req.params.userId,
newLabel: req.body.newLabel
})
.then(function(result) {
res.status(200).send({ succeed: true, data: result.records[0]._fields });
session.close();
})
.catch(function(err) {
console.log(err);
res.status(404).send({ succeed: false, data: err });
});
};
my post api query:
rest/user/addnewlabel/5a423325507c093948e9ef91
body :
{
"newLabel":"Firm"
}
when I call my api for create new label I take this mistake as below code. when I set relationships as like also I get this error.
Neo4jError: Invalid input '{': expected whitespace or a label name (line 1,
column 36 (offset: 35))
"MATCH (n:User {id:{userId}}) SET n:{newLabel} RETURN n"
You cannot set labels dynamically via parameters, the same is true for relationship types as well.
You can use string concatenation instead :
session
.run("MATCH (n:User {id:{userId}}) SET n:`" + req.body.newLabel + "` RETURN n", {
userId: req.params.userId
})
I would suggest to validate the request though.
I found new solution also I can write a query.
exports.addNewLabel = function(req, res) {
var query ="MATCH (n:User {id:'"+req.params.userId+"'}) SET n:"+req.body.newLabel+" RETURN n"
session
.run(query)
.then(function(result) {
res.status(200).send({ succeed: true, data: result });
session.close();
})
.catch(function(err) {
console.log(err);
res.status(404).send({ succeed: false, data: err });
});
};
I think that a simpler, safer and more elegant way is to use the addLabels procedure from the APOC library:
session
.run(
`
MATCH (n:User {id: {userId}})
CALL apoc.create.addLabels(n, {newLabels}) YIELD node
RETURN node AS n
`, {
userId: req.params.userId,
newLabels: [req.body.newLabel]
})

Electron Nedb findOne returns null?

I am calling a simple query with findOne, so far the data in users.db is:
{"id":40, "is_admin":1,"name":"John Smith"},
{"id":43, "is_admin":1,"name":"Laura Smith"}
// Users
var users = new Datastore({ filename: 'db/users.db' });
var id_user = 43;
console.log("-------------geting users db");
//
users.loadDatabase(function (err) {
console.log("------------- users db loaded--", id_user);
// find user by id
users.findOne({ id: id_user }, function (err, a,b,c) {
console.log(a,b,c); // displays null undefined undefined
});
});
Any idea why is returning null?
I think function being passed in findOne should take 2 parameters. First parameter will be the result of query and
second parameter will be error if something goes wrong . First parameter will be Null if there is no match in db .otherwise it should return the match result.
Function(result, error ){
}
It will be you function prototype
I tested your code in my app
db.findOne({ "c2cId":"292" }, function (err, a,b,c) {
console.log(a,b,c);
});
It return one doc and undefined, undefined.
If you use findOne I guess you just want to find the first doc, so looking at the
doc at
You can see there is only two parameters err and the doc
Concerning the null: in your query are you using a variable named id? or is it the key, in last case you should use quotes....

Connection error with Relay

// didn't add node definitions because this problem occurs on initial data fetch
// user type
const userType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: globalIdField('User'),
email: { type: GraphQLString },
posts: {
type: postConnection,
args: connectionArgs,
// getUserPosts() function is below
resolve: (user, args) => connectionFromArray(getUserPosts(user.id), args),
},
}),
interfaces: [nodeInterface],
})
// post type
const postType = new GraphQLObjectType({
name: 'Post',
fields: () => ({
id: globalIdField('Post'),
title: { type: GraphQLString },
content: { type: GraphQLString },
}),
interfaces: [nodeInterface],
})
// connection type
const {connectionType: postConnection} =
connectionDefinitions({name: 'Post', nodeType: postType})
// Mongoose query on other file
exports.getUserPosts = (userid) => {
return new Promise((resolve, reject) => {
Post.find({'author': userid}).exec((err, res) => {
err ? reject(err) : resolve(res)
})
})
}
I get the following warning in browser console:
Server request for query App failed for the following reasons:
Cannot read property 'length' of undefined
_posts40BFVD:posts(first:10) {
^^^
That's the only information I got, there's no more errors or references. What could be the reason?
This code is from relay-starter-kit, I only replaced all the Widget code with Post. Everything is almost the same as in starter, therefore I think the cause is somewhere around the database code.
But I can't see the problem because getUserPosts() returns same structure: array of objects..
What was the problem?
resolve: (user, args) => connectionFromArray(getUserPosts(user.id), args)
getUserPosts() returned a promise (blocking code would probably be a bad idea) but there was no callback. What happened in my opinion was that connectionFromArray() continued executing the code but it didn't have the data from getUserPosts() yet, which caused the whole system to fail.
One possible solution
I use Babel and JavaScript "future features" anyway, therefore I decided to use async and await. But there still was a problem and getUserPosts() returned an empty array.
Then I discovered that if another function is called with await in a async function, that another function has to be async as well, otherwise all await-s fail. Here's my final solution that works:
// async function that makes db query
exports.getUserPosts = async (userId) => {
try {
// db query
const posts = await Post.find({author: args}).exec()
return posts
} catch (err) {
return err
}
}
// and resolve method in Schema, also async
resolve: async (user, args) => {
const posts = await getUserPosts(user._id)
return connectionFromArray(posts, args)
}
Im not still sure though if it's the best way. My logic tells me that I should use async as much as possible in Node but Im far from Node expert. I'll update the question when I know more about it.
I would be glad to know if there's a better or even a recommended way to deal with this database query situation using Relay.
The problem is with the resolve function of posts field.
resolve: (user, args) => connectionFromArray(getUserPosts(user.id), args),
First, getUserPosts is an asynchronous function which returns a promise. You have to take that into account while writing resolve function. Second, user.id is a global ID field generated for you by graphql-relay module's globalIdField helper function. That ID should be converted to local ID.
With relay-starter-kit, you can use async and await. The code will look like:
resolve: async (user, args) => {
let userId = fromGlobalId(user.id).id;
// convert this userId string to Mongo ID if needed
// userId = mongoose.Types.ObjectId(userId).
const posts = await getUserPosts(userId);
return connectionFromArray(posts, args),
},
In your async version of getUserPosts, the err object is returned in case of error.
exports.getUserPosts = async (userId) => {
try {
// db query
const posts = await Post.find({author: args}).exec()
return posts
} catch (err) {
return err
}
}
A good practice is to either re-throw the error or return an empty array.
graphql-relay provides a connectionFromPromisedArray function which waits until the promise resolves. resolve: (user, args) => connectionFromPromisedArray(getUserPosts(user.id), args), which probably is the most recommended/easiest way when dealing with promised connections.
If your user.id is a global ID field then you have to extract the real DB ID from the base64 string const { type, id } = fromGlobalId(user.id);.
or
resolve: (user, args) => connectionFromPromisedArray(getUserPosts(fromGlobalId(user.id).id), args),
In a app I work on which is using Relay and Mongoose I found it better to write my own connection implementation to handle pagination and filtering on the DB level rather than on the app level. I took a lot of inspiration from graffiti-mongoose when I wrote it.

How to create a join table using sequelize and sqlite?

I am trying to establish a many-to-many relationship between tables in sqlite using sequelize.
I want to add records to a join table (assign tasks to a user) and retrieve data from that table. For some reason, this does not work. Here is my code:
var orm = new Sequelize('db_name', '', '', {
dialect: 'sqlite',
storage: path.join(__dirname, 'db_name')
});
var User = orm.define('User', {
username: {type: Sequelize.STRING, unique: true}
});
var Task = orm.define('Task', {
id: {type: Sequelize.STRING, unique: true},
taskName: Sequelize.STRING
});
Task.hasMany(User);
User.hasMany(Task);
Task.sync();
User.sync();
Having read documentation (http://sequelize.readthedocs.org/en/latest/api/associations/#hasmanytarget-options), I expect that a join table TasksUsers should be created. I also expect .addTask method do be available. Then in another file I have:
db.User.findOrCreate({where:{username: "fakeUser"}}); //this seems to work
//some code to populate "Tasks" table;
db.User.find({where: {username: "fakeUser"}}).
complete(function(err,user){
console.log("user", user); //the user is found
db.Task.find({where: {id: "some_value"}}).
complete(function(err, task) {
console.log("task", task); //the task is found, so it works up to this point
user.addTask(task). //this line does not work
complete(function(err, results){
console.log("posting error", err);
});
})
});
I get an error "Possibly unhandled SequelizeDatabaseError: Error: SQLITE_ERROR: no such table: TasksUsers". The user.getTasks() method (without any arguments in the parentheses) does not work for the same reason.
Another observation: for testing purposes, I added these lines of code after establishing hasMany relationships:
orm.query("SELECT name FROM sqlite_master WHERE type = 'table'").success(function (res) {
console.log("tables", res);
})
The result that I get is tables [ 'Tasks', 'Users' ]
The versions: sequelize 2.0.0-rc2, sqlite3 3.0.4. I would be very grateful for any help.

Node-Neo4j How to check if node exists(persistently)?

I'm using Node-Neo4j client for my db. I want to create unique node, but I couldn't find how to do that in the documentation of Node-Neo4j. I used the logic below to check if a node exists or not:
person_param = {'name': namesurname, 'userid': userid };
person_node = db.createNode(person_param);
if (!person_node.exists){
person_node.save(function(err, result){
//if(err) and if(!err) stuff
});
}
But, from what I understand, createNode creates a new node from scratch, and when I use exists on it, it just checks if the newly created node saved into database or not.
How can I check if a node with supplied properties already exists in db or not?
Thanks in advance.
The only solution I can think of, is the following:
Create your properties object
Query the Neo4J instance for those properties
If a result is returned use that
otherwise save it
In code:
var person_param = {'name': namesurname, 'userid': userid };
// Build a Cypher query
var query = [
'MATCH (user: {name: {name}, id: {userid}})',
'RETURN user'
].join('\n');
// use your params in the query
var params = person_param;
// Send the Cypher query
db.query(query, params, function (err, results) {
if (err) throw err;
// no node with such properties found
if(!results.length){
saveNode(params, callback)
} else {
// carry on with your code...
}
});
function saveNode(person_param, callback){
var person_node = db.createNode(person_param);
person_node.save(function(err, result){
//if(err) and if(!err) stuff
// call the callback here
});
}
The downside of this approach is that you need to build a Cypher query for each type of node you have, because there's no way (as far as I know) to pass both properties name and values to Cypher.

Resources