Prisma: Type '{ where: { variable: "value"; }; }' is not assignable to type 'boolean' - sql

So I am using prisma and I am trying to get the count of votes on thread where the vote value is VoteStatus.down. I am following the docs here.
I am getting Type '{ where: { vote: "down"; }; }' is not assignable to type 'boolean'. when I do this:
await this.prisma.thread.findMany({
select: {
_count: {
select: {
votes: { where: { vote: VoteStatus.down } }
}
}
}
});
Here are my models in schema.prisma (note: I have modified for simplicity of the question):
model Thread {
id Int #id #default(autoincrement())
votes ThreadVote[]
}
model ThreadVote {
id Int #id #default(autoincrement())
thread Thread #relation(fields: [threadId], references: [id])
threadId Int
vote VoteStatus
}
enum VoteStatus {
up
down
}
I'm wondering if there is a bug in prisma? It seems to line up with the docs perfectly. Note that I am on Prisma 4.3.1.
Edit: I am now thinking it is because I have to add the filter relation count:
generator client {
provider = "prisma-client-js"
previewFeatures = ["filteredRelationCount"]
}

Related

Find all items with empty many to many relationship in vapor fluent

Given the example from the vapor docs:
// Example of a pivot model.
final class PlanetTag: Model {
static let schema = "planet+tag"
#ID(key: .id)
var id: UUID?
#Parent(key: "planet_id")
var planet: Planet
#Parent(key: "tag_id")
var tag: Tag
init() { }
init(id: UUID? = nil, planet: Planet, tag: Tag) throws {
self.id = id
self.$planet.id = try planet.requireID()
self.$tag.id = try tag.requireID()
}
}
final class Planet: Model {
// Example of a siblings relation.
#Siblings(through: PlanetTag.self, from: \.$planet, to: \.$tag)
public var tags: [Tag]
}
final class Tag: Model {
// Example of a siblings relation.
#Siblings(through: PlanetTag.self, from: \.$tag, to: \.$planet)
public var planets: [Planet]
}
How can I query with fluent all planets which do not have a tag?
Planet.query(on: req.db).filter(?).all()
EDIT: Solution but with async/await
let pivots = try await PlanetTag.query(on: req.db).unique().all()
let planetsWithTags = pivots.map { $0.$planet.id }
let planetsWithoutTags = Planet.query(on: req.db).filter(\.$id !~ planetsWithTags)
return try await planetsWithoutTags.paginate(for: req).map(\.detail)
I haven't checked this out but, intuitively, this should work if you want to make use of the Sibling relationship:
Planet.query(on:req.db).with(\.$tags).all().map { allPlanets in
let planetWithoutTags = allPlanets.filter { $0.tags.isEmpty }
// continue processing
}
This is a bit wasteful, since you are fetching (potentially) lots of records that you don't want. A better approach is to get the planets that do have tags and then exclude those:
PlanetTag.query(on:req.db).unique().all(\.$planet).flatMap { planetTags in
return Planet.query(on:req.db).filter(\.$id !~ planetTags.map { $0.$planet.$id }).all().flatMap { planetsWithoutTags in
// continue processing
}
}

How to reference Composite ID in Gorm 6 or 7 to prevent IllegalArgumentException: Unable to locate Attribute with the the given name

I have this model which works with Gorm3
class UserDataPoint implements Serializable {
User user
DataPoint dataPoint
static mapping = {
id composite: ['user', 'dataPoint']
}
static List<Long> getReadDataPointIds(User user, List<Long> locationIds = null) {
createCriteria().list {
eq('user', user)
dataPoint {
listing {
location {
inList('id', locationIds)
}
}
}
projections {
property('dataPoint.id')
}
} as List
}
}
but now it runs this exception :
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given
name [dataPoint] on this ManagedType [user.UserDataPoint]
Some debug allows me to understand what is happening, it seems that GORM remove the user and dataPoint properties from HibernateProperties because the are a part of the Composite ID
public abstract class AbstractPersistentEntity<T extends Entity> implements PersistentEntity {
.......
IdentityMapping identifier = mapping != null ? mapping.getIdentifier() : null;
if(identity == null && identifier != null) {
final String[] identifierName = identifier.getIdentifierName();
final MappingContext mappingContext = getMappingContext();
if(identifierName.length > 1) {
compositeIdentity = mappingContext.getMappingSyntaxStrategy().getCompositeIdentity(javaClass, mappingContext);
}
for (String in : identifierName) {
final PersistentProperty p = propertiesByName.get(in);
if(p != null) {
persistentProperties.remove(p);
}
persistentPropertyNames.remove(in);
}
disableDefaultId();
}
......
}
So I understand the problem, but I don't know how to fix it ?
how to reference the composite ID and it fields in the projection ?
It seems to be fixed with this recent version https://github.com/grails/gorm-hibernate5/releases/tag/v7.2.1

Seconds scalar is always null in vue-apollo

I'm trying to pass an int value as seconds scalar to my graphql-backend.
The frontend uses vue-apollo and the backend is written in dotnet core using graphql-dotnet.
When I call the mutation via playground, everything works fine. Neither does my vue app throw any error/exception nor works the mutation. The mutation is called in the backend, but the value for s is null (and so 00:00:00 as it is a TimeSpan). The backend is written in dotnet core 3.1 but as I said the convertion from a given number to TimeSpanSecondsGraphType works via playground.
frontend code
My mutation looks like
updateS(
sId: ID = null
s: s = null
): SType
My input type s looks like
type s {
s: Seconds = null
}
And my SType looks like
type SType {
s: Seconds
}
Working example call (via playground)
mutation {
updateS(s: "08d924e8-69fb-425c-8130-de7342a2ca2a", s: {
s: 3600
}) {
s
}
}
This is the payload from chrome when I call the mutation in my vue-app (not working):
{"operationName":"updateS","variables":{"sId":"08d924e8-69fb-425c-8130-de7342a2ca2a","s":{"s":3600}},"query":"mutation updateS($sId: ID!, $s: s!) {\n updateS(sId: $sId, s: $s) {\n s\n__typename\n }\n}\n"}
Edit - Added backend code
dotnet core mutation and models
This is my mutation in the backend:
Field<SType>(
"updateS",
arguments: new QueryArguments(
new QueryArgument<IdGraphType> { Name = "sId" },
new QueryArgument<SInputType> { Name = "s" }
),
resolve: context =>
{
var sId = context.GetArgument<Guid>("sId");
var s = context.GetArgument<S>("s"); // s.S is always {00:00:00} when called from vue app.
return repo.UpdateS(sId, s);
});
My SInputType:
public class SInputType : InputObjectGraphType
{
public SInputType()
{
Name = "s";
Field<TimeSpanSecondsGraphType>("s");
}
}
And my S.cs:
public class S
{
public Guid Id { get; set; }
public TimeSpan S { get; set; }
}
Any suggestion?

Is this an error in Typescript compiler

I noticed an issue where a user defined typeguard on a union type doesn't behave symmetrically. I hope this an error on my end :-/
The issue shows up in test2() where the type is not inferred properly from the typeguard.
class PropPacket {
constructor(public key: string, public value: number) {}
}
class EventPacket {
constructor(public key: string) {}
}
type Packet = PropPacket | EventPacket;
function isPropPacket(p: EventPacket | PropPacket): p is PropPacket {
return p instanceof PropPacket;
}
function isEventPacket(p: EventPacket | PropPacket): p is EventPacket {
return p instanceof EventPacket;
}
function test1(p: Packet) {
if (isPropPacket(p)) {
// `p` is PropPacket
p.key;
p.value;
} else {
// `p` is EventPacket
p.key;
}
}
function test2(p: Packet) {
if (isEventPacket(p)) {
p.key;
} else {
// ERROR: thinks `p` is `never` type
p.key;
p.value;
}
}
You can see the issue by pasting the code in the typescript playground (https://www.typescriptlang.org/play/)
This happens because all EventPackets are in fact PropertyPackets. Typescript has a structural type system which does not consider two classes to be distinct by declaration, only by the properties and methods they contain.

Getting NHibernate to store unique object only once

I have got four tables in NHibernate
Job
{
DBID { int, primary key }
Name { string }
Media { fk_media (int) }
PublishInfo { fk_publishinfo (int) }
}
Media
{
DBID { int, primary key }
TransmissionID { string }
Series { string }
Title { string }
Description { string }
}
PublishInfo
{
DBID { int, primary key }
Destination { string }
AudioTrack_1 { fk_audiolanguage }
AudioTrack_2 { fk_audiolanguage }
AudioTrack_3 { fk_audiolanguage }
AudioTrack_4 { fk_audiolanguage }
}
AudioLanguage
{
Code { string, primary key }
Description { string }
}
What I want to achive with NHibernate is that it only stores unique records. So if a Media is used multiple times they all point to the same media entry. Same goes for PublishInfo.
A second issue I ran into is that when using the same audiolanguage for audiotrack_3 and 4 for instance it gives a error that is was already used in the session.
Any tips how I would do this properly?
This is a partial anwser to my own question. The reason it wasn't working correctly for the languages when using same lanuage on multiple tracks is because they got send back and forth between a client and server application. The way I solved this is by receiving it back to the server I lookup the proper objects stored in a list on the server and replace them.
I do not think this is the proper solution but it works.