Prepend or append to values obtained from Knex js SQL queries - sql

I have a simple people table which has two columns id and name.
I can query all the names along with the id as follows
const persons = await knex('people').select('id','name');
I want to add Dr. in front of all the names.
For example
{id:1, name: 'Tom'}
should return
{id:1, name: 'Dr. Tom'}
How do I do this in knex js ?

I believe you could easily do it in memory using JS map, but apparently you want to do it on db level.
Basically, you need the following query:
select CONCAT('Dr. ', people.name) as 'name', people.id as 'id' from people;
(Tested in w3schools online fiddler)
So, effectively we could try the following (basing on Identifier Syntax from http://knexjs.org/):
knex({ people: 'people' })
.select({
id: 'people.id',
name: 'CONCAT("Dr. ", people.name)'
})
But I'm not sure if knex will substitute it properly.
The problem is, however, that CONCAT is not supported by all SQL dialects, as far as I am concerned.

Related

Return inserted id with TypeORM & NestJS raw query: await connection.manager.query(`INSERT INTO

I'm looking to return the id or better yet, all information that was inserted, using a raw query with TypeORM and NestJS. Example as follows:
await connection.manager.query(`INSERT INTO...`)
When assigning the query to a constant and console logging it below, it does not yield any helpful information:
OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
serverStatus: 2,
warningCount: 1,
message: '',
protocol41: true,
changedRows: 0
}
As you can see, it returns no pertinent information, the insertId above is obviously incorrect, and it returns this every time, regardless of the actual parameters of the query.
I know with more typical TypeORM queries you can use .return(['name_of_column_you_want_returned']).execute()
and it will return the relevant information just fine. Is there any way to do this with a raw query? Thank you!
tl;dr You're getting the raw mariadb driver response (OkPacket) from the INSERT command, and you'd need a new SELECT query to see the data.
You're using the TypeORM EntityManager, and the docs don't mention a return value. Looking at the source code for query, the return type is any. Since it's a raw query, it probably returns an object based on the type of database you're using rather than having a standard format.
In this case, you're using MariaDb, which returned an OkPacket. Here's the documentation:
https://mariadb.com/kb/en/ok_packet/

Karate graphql variables inside query

I am trying to insert previously defined variable inside graphql query but I'm not able to find any example on how to do that except creating variables outside of query text and then making request with variables.
There is one problem for me for example in this example
queries: [{type: TERM, match: EQUAL, field: "fieldOne", value: "#(id)"},
{type: TERM, match: EQUAL, field: "fieldTwo", value: null}]
I want to insert value #(id) only for the first object in graphql query. Can anyone please provide some example for me or any suggestions on how to do that?
Alright I was thinking that it will be possible to directly replace text inside query, but I found solution from karate documentation with.
queries: [{type: TERM, match: EQUAL, field: "fieldOne", value: "<id>"},
{type: TERM, match: EQUAL, field: "fieldTwo", value: null}]
enclose id inside query text in angle brackets <> and then replace id inside query with id stored in variable id by calling
* replace query.id = id

Neo4j.rb How to use it with Rails

I am using neo4j version 3.X, I am using searchkick
currently using
User.search(params[:term], operator: 'or',
fields: [:first_name, :last_name],
misspellings: { below: 5 },
match: :word_start,
page: params[:page], per_page: params[:rpp], padding: params[:offset])
instead of
User.where('(sp.first_name + sp.last_name) =~ ?', /.*#{params[:term].sub(/\s/, '')}.*/i)
But I have problem where I have to make more cypher queries at the same time with searching How to do that?
For exmaple
Neo4j::ActiveBase.new_query.match(n: {User: { uuid: current_user.uuid }}).break
.match('(n)-[:connected_to {status: 2}]-(sp:User)')
.return('DISTINCT sp')
I want to seach in this query with elasctic search with first name & last name
In my model I have defined searchkick word_start: [:first_name, :last_name]
It's been a while since I've used searchkick, but I would suggest trying to use the ActiveNode syntax instead of the neo4j-core Query syntax so that you can append .search on the end:
current_user.connected_users.rel_where(status: 2).distinct.search(...)
This is assuming that there is a connected_users association which uses the connected_to relationship type. You may have another, similar, association in your User model but I didn't know what it was.
I'm not 100% sure if the distinct will work with the search or not, but you could perhaps drop the .distinct part and searchkick might return you a distinct set anyway.

Why does Rails .select alias change attributes to lowercase?

In our controller, we are trying to show a video series, which should return JSON similar to this:
{
id: 1,
name: "Series Name",
videos: [
id: 2,
name: "Video Name",
isInPlaylist: true,
isFavorite: false
]
}
We are adding the isInPlaylist and isInFavorite attributes via another table where we store data if a user has acted upon a video (rated it, favorited it, etc.).
videos = series.videos
.where('videos.is_live = true')
.joins("some join to user_videos join_table")
.select(
'videos.*,
coalesce(user_videos.rating, 0.0) as user_rating,
coalesce(user_videos.enqueue, \'false\') as isInPlaylist,
coalesce(user_videos.favorite, \'false\') as isFavorite'
)
Note that in our select statement those attributes are explicitly aliased as camel-cased values. However when we execute this query, these attributes are returned lower case instead:
{
isinplaylist: true,
isfavorite: false
}
This is not a Rails behavior, but rather a SQL behavior. Alias's are folded to lower case unless explicitly quoted. For an example, here is the output of a simple query in psql (the Postgres CLI program).
=# select created_at as theTimeNow from users limit 5;
thetimenow
----------------------------
2013-03-05 18:45:11.127092
2013-09-07 16:43:01.349823
2013-03-05 18:53:35.888306
2013-09-07 16:53:06.553129
2013-10-29 00:38:56.909418
(5 rows)
=# select created_at as "theTimeNow" from users limit 5;
theTimeNow
----------------------------
2013-03-05 18:45:11.127092
2013-09-07 16:43:01.349823
2013-03-05 18:53:35.888306
2013-09-07 16:53:06.553129
2013-10-29 00:38:56.909418
(5 rows)
Notice the column name outputs
Wrapping the alias in double quotes preserves case-sensitivity.
.select('foo as Bar') # => { bar: true }
.select('foo as "Bar"') # => { Bar: true }
The change to lower case is not an issue with the Rails .select() method but is enforced by the DB, in our case PostgreSQL, and is a practice called "Folding". Its worth noting that while PSQL will fold to lowercase letters, mySQL will fold to upper case letters.
I would argue however that it should still be included in the Rails API docs
¯\_(ツ)_/¯
I like you answer. The behaviour you see is rails default. As an alternative and
a more classic 'rails way' would be to use a json serializing library like jBuilder. It gives you lot more control over your API but your problem would be easy to fix in that using:
json.key_format! camelize: :lower
json.first_name 'David'
# => { "firstName": "David" }
To use something like this you would alias the columns as is_in_playlist format.
Here's a good place to start with jBuilder learning:
http://railscasts.com/episodes/320-jbuilder
Good tutorial on more json serializers:
http://railscasts.com/episodes/409-active-model-serializers

Ordering of columns in where clause when using SQL::Abstract

I have been reading some recipes in the Perl Hacks book. Recipe #24 "Query Databases Dynamically without SQL" looked interesting. The idea is to use SQL-Abstract to generate the SQL statement for you.
The syntax to generate a select statement looks something like this:
my($stmt, #bind) = $sql->select($table, \#fields, \%where, \#order);
To illustrate further, an example could look like this (taken from the perldoc):
my %where = (
requestor => 'inna',
worker => ['nwiger', 'rcwe', 'sfz'],
status => { '!=', 'completed' }
);
my($stmt, #bind) = $sql->select('tickets', '*', \%where);
The above would give you something like this:
$stmt = "SELECT * FROM tickets WHERE
( requestor = ? ) AND ( status != ? )
AND ( worker = ? OR worker = ? OR worker = ? )";
#bind = ('inna', 'completed', 'nwiger', 'rcwe', 'sfz');
Which you could then use in DBI code like so:
my $sth = $dbh->prepare($stmt);
$sth->execute(#bind);
Now, sometimes the order of the columns in the WHERE clause is very important, especially if you want to make good use of indexes.
But, since the columns to the WHERE clause generator in SQL-Abstract are specified by means of a hash - and as is known, the order that data is retrieved out of perl hashes cannot be guaranteed - you seem to loose the ability to specify the order of the columns.
Am i missing something? Is there an alternate facility to guarantee the order that columns appear in the WHERE clause when using SQL-Abstract ?
I originally misinterpreted your question.
You can use -and to achieve the desired ordering.
For example:
#!/usr/bin/perl
use strict; use warnings;
use SQL::Abstract;
my $sql = SQL::Abstract->new;
my ($stmt, #bind) = $sql->select(
tickets => '*',
{
-and => [
requestor => 'inna',
status => { '!=', 'completed' },
worker => ['nwiger', 'rcwe', 'sfz'],
],
}
);
print "$stmt\n";
See Nested conditions, -and/-or prefixes.
This module cannot do everything -- it is meant as a convenience for constructing queries that will do the job "most of the time". Sometimes you still may need to write a query by hand. I use SQL::Abstract in my main $work::app and have never run into the situation that you describe. A good SQL engine will know which keys are indexed, and optimize the query to use those first, no matter the ordering you specify. Are you sure that your engine is not the same, and that the order you specify in the query is really significant?
If you really need to order your WHERE clauses in a special order, you may find it easier to write subqueries instead. SQL::Abstract can make this easier too.