Skip to content

Commit

Permalink
Merge branch 'beta' into BackmergeBeta133
Browse files Browse the repository at this point in the history
  • Loading branch information
do4gr committed May 14, 2019
2 parents 9121fdf + 3baa8e4 commit 191c4bc
Show file tree
Hide file tree
Showing 14 changed files with 279 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ trait BuilderBase extends JooqExtensions with JdbcExtensions with SlickExtension
def modelColumn(fieldModel: com.prisma.shared.models.Field): Field[AnyRef] = field(name(project.dbName, fieldModel.model.dbName, fieldModel.dbName))
def modelIdColumn(model: Model) = field(name(project.dbName, model.dbName, model.dbNameOfIdField_!))
def modelIdColumn(alias: String, model: Model) = field(name(alias, model.idField_!.dbName))
def relationColumn(relation: Relation, side: Value) = field(name(project.dbName, relation.relationTableName, relation.columnForRelationSide(side)))
def relationColumn(rf: RelationField) = field(name(project.dbName, rf.relation.relationTableName, rf.relation.columnForRelationSide(rf.relationSide)))
def relationIdColumn(relation: Relation) = field(name(project.dbName, relation.relationTableName, relation.idColumn_!))
def inlineRelationColumn(relation: Relation, mani: EmbeddedRelationLink) = field(name(project.dbName, relation.relationTableName, mani.referencingColumn))
def scalarListColumn(scalarField: ScalarField, column: String) = field(name(project.dbName, scalarListTableName(scalarField), column))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,22 +93,22 @@ trait FilterConditionBuilder extends BuilderBase {
relationFilter.nestedFilter match {
case nested: RelationFilter =>
val condition = inStatementForRelationCondition(
jooqField = relationColumn(relation, relationField.oppositeRelationSide),
jooqField = relationColumn(relationField.relatedField),
condition = nested.condition,
subSelect = relationFilterSubSelect(newAlias, nested)
)
sql
.select(relationColumn(relation, relationField.relationSide))
.select(relationColumn(relationField))
.from(relationTable(relation))
.where(condition.invert(invertConditionOfSubSelect))

case nested =>
val condition = buildConditionForFilter(nested, newAlias)
sql
.select(relationColumn(relation, relationField.relationSide))
.select(relationColumn(relationField))
.from(relationTable(relation))
.innerJoin(modelTable(relationField.relatedModel_!).as(newAlias))
.on(modelIdColumn(newAlias, relationField.relatedModel_!).eq(relationColumn(relation, relationField.oppositeRelationSide)))
.on(modelIdColumn(newAlias, relationField.relatedModel_!).eq(relationColumn(relationField.relatedField)))
.where(condition.invert(invertConditionOfSubSelect))
}
}
Expand All @@ -131,7 +131,7 @@ trait FilterConditionBuilder extends BuilderBase {

case false =>
val select = sql
.select(relationColumn(relation, relationField.relationSide))
.select(relationColumn(relationField))
.from(relationTable(relation))

modelIdColumn(alias, relationField.relatedModel_!).notIn(select)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ trait ImportActions extends BuilderBase with SharedJdbcExtensions {
.insertInto(relationTable(relation))
.columns(
relationIdColumn(relation),
relationColumn(relation, relation.modelAField.relationSide),
relationColumn(relation, relation.modelBField.relationSide)
relationColumn(relation.modelAField),
relationColumn(relation.modelBField)
)
.values(placeHolder, placeHolder, placeHolder)

Expand All @@ -106,8 +106,8 @@ trait ImportActions extends BuilderBase with SharedJdbcExtensions {
val query = sql
.insertInto(relationTable(relation))
.columns(
relationColumn(relation, relation.modelAField.relationSide),
relationColumn(relation, relation.modelBField.relationSide)
relationColumn(relation.modelAField),
relationColumn(relation.modelBField)
)
.values(placeHolder, placeHolder)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,12 @@ trait NodeSingleQueries extends BuilderBase with NodeManyQueries with FilterCond
}

private def parentIdConditionSubselect(parentField: RelationField, parentIds: Vector[Any]) = {
val relation = parentField.relation
val childIdField = relationColumn(relation, parentField.oppositeRelationSide)
val parentIdField = relationColumn(relation, parentField.relationSide)
val childIdField = relationColumn(parentField.relatedField)
val parentIdField = relationColumn(parentField)

sql
.select(childIdField)
.from(relationTable(relation))
.from(relationTable(parentField.relation))
.where(parentIdField.in(placeHolders(parentIds)))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ trait RelationActions extends BuilderBase {
.insertInto(relationTable(relation))
.columns(
relationIdColumn(relation),
relationColumn(relation, relationField.relationSide),
relationColumn(relation, relationField.oppositeRelationSide)
relationColumn(relationField),
relationColumn(relationField.relatedField)
)
.values(placeHolder, placeHolder, placeHolder)
.onConflictDoNothing()
Expand All @@ -55,8 +55,8 @@ trait RelationActions extends BuilderBase {
val query = sql
.insertInto(relationTable(relation))
.columns(
relationColumn(relation, relationField.relationSide),
relationColumn(relation, relationField.oppositeRelationSide)
relationColumn(relationField),
relationColumn(relationField.relatedField)
)
.values(placeHolder, placeHolder)
.onConflictDoNothing()
Expand All @@ -73,7 +73,7 @@ trait RelationActions extends BuilderBase {
def deleteRelationRowByChildId(relationField: RelationField, childId: IdGCValue): DBIO[_] = {
assert(!relationField.relatedField.isList)
val relation = relationField.relation
val condition = relationColumn(relation, relationField.oppositeRelationSide).equal(placeHolder)
val condition = relationColumn(relationField.relatedField).equal(placeHolder)

relation.inlineManifestation match {
case Some(manifestation) =>
Expand All @@ -100,9 +100,9 @@ trait RelationActions extends BuilderBase {

def deleteRelationRowByChildIdAndParentId(relationField: RelationField, childId: IdGCValue, parentId: IdGCValue): DBIO[_] = {
val relation = relationField.relation
val condition = relationColumn(relation, relationField.oppositeRelationSide)
val condition = relationColumn(relationField.relatedField)
.equal(placeHolder)
.and(relationColumn(relation, relationField.relationSide).equal(placeHolder))
.and(relationColumn(relationField).equal(placeHolder))

relation.inlineManifestation match {
case Some(manifestation) =>
Expand Down Expand Up @@ -133,7 +133,7 @@ trait RelationActions extends BuilderBase {

def deleteRelationRowByParentId(relationField: RelationField, parentId: IdGCValue): DBIO[_] = {
val relation = relationField.relation
val condition = relationColumn(relation, relationField.relationSide).equal(placeHolder)
val condition = relationColumn(relationField).equal(placeHolder)
relation.inlineManifestation match {
case Some(manifestation) =>
val query = sql
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ trait ValidationActions extends BuilderBase with FilterConditionBuilder {
def ensureThatNodeIsNotConnected(relationField: RelationField, id: IdGCValue): DBIO[Unit] = {
val relation = relationField.relation
val idQuery = sql
.select(relationColumn(relation, relationField.oppositeRelationSide))
.select(relationColumn(relationField.relatedField))
.from(relationTable(relation))
.where(
relationColumn(relation, relationField.oppositeRelationSide).equal(placeHolder),
relationColumn(relation, relationField.relationSide).isNotNull
relationColumn(relationField.relatedField).equal(placeHolder),
relationColumn(relationField).isNotNull
)

queryToDBIO(idQuery)(
Expand All @@ -32,11 +32,11 @@ trait ValidationActions extends BuilderBase with FilterConditionBuilder {
def ensureThatNodesAreConnected(relationField: RelationField, childId: IdGCValue, parentId: IdGCValue)(implicit ec: ExecutionContext): DBIO[Unit] = {
val relation = relationField.relation
val idQuery = sql
.select(relationColumn(relation, relationField.oppositeRelationSide))
.select(relationColumn(relationField.relatedField))
.from(relationTable(relation))
.where(
relationColumn(relation, relationField.oppositeRelationSide).equal(placeHolder),
relationColumn(relation, relationField.relationSide).equal(placeHolder)
relationColumn(relationField.relatedField).equal(placeHolder),
relationColumn(relationField).equal(placeHolder)
)

queryToDBIO(idQuery)(
Expand All @@ -63,11 +63,11 @@ trait ValidationActions extends BuilderBase with FilterConditionBuilder {
)(implicit ec: ExecutionContext): DBIO[Unit] = {
val relation = relationField.relation
val idQuery = sql
.select(relationColumn(relation, relationField.relationSide))
.select(relationColumn(relationField))
.from(relationTable(relation))
.where(
relationColumn(relation, relationField.relationSide).equal(placeHolder),
relationColumn(relation, relationField.oppositeRelationSide).isNotNull
relationColumn(relationField).equal(placeHolder),
relationColumn(relationField.relatedField).isNotNull
)

queryToDBIO(idQuery)(
Expand All @@ -90,18 +90,17 @@ trait ValidationActions extends BuilderBase with FilterConditionBuilder {
}

def errorIfNodesAreInRelation(parentIds: Vector[IdGCValue], field: RelationField)(implicit ec: ExecutionContext): DBIO[Unit] = {
val relation = field.relation
val query = sql
.select(relationColumn(relation, field.oppositeRelationSide))
.from(relationTable(relation))
.select(relationColumn(field.relatedField))
.from(relationTable(field.relation))
.where(
relationColumn(relation, field.oppositeRelationSide).in(placeHolders(parentIds)),
relationColumn(relation, field.relationSide).isNotNull
relationColumn(field.relatedField).in(placeHolders(parentIds)),
relationColumn(field).isNotNull
)

queryToDBIO(query)(
setParams = pp => parentIds.foreach(pp.setGcValue),
readResult = rs => if (rs.next) throw RequiredRelationWouldBeViolated(relation)
readResult = rs => if (rs.next) throw RequiredRelationWouldBeViolated(field.relation)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ object APIErrors {
extends ClientApiError(s"No Node for the model ${where.model.name} with value ${where.value} for ${where.field.name} found.", 3039)

case class NullProvidedForWhereError(modelName: String)
extends ClientApiError(s"You provided an invalid argument for the where selector on $modelName.", 3040)
extends ClientApiError(s"You provided an invalid argument for the where selector on $modelName. Please provide exactly one unique field and value.", 3040)

case class NodesNotConnectedError(relation: Relation, parent: Model, parentWhere: Option[NodeSelector], child: Model, childWhere: Option[NodeSelector])
extends ClientApiError(pathErrorMessage(relation, parent, parentWhere, child, childWhere), 3041)
Expand Down Expand Up @@ -138,6 +138,12 @@ object APIErrors {
3044
)

case class TwoManyUniquesForWhereError(modelName: String)
extends ClientApiError(
s"You provided more than one field for the unique selector on $modelName. If you want that behavior you can use the many query and combine fields with AND / OR.",
3045
)

case class ExecuteRawError(e: SQLException) extends ClientApiError(e.getMessage, e.getErrorCode)

def pathErrorMessageNative(relation: String, parent: String, parentWhere: Option[NodeSelectorInfo], child: String, childWhere: Option[NodeSelectorInfo]) = {
Expand Down
8 changes: 6 additions & 2 deletions server/prisma-rs/prisma-models/src/field/relation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ impl RelationField {
Some(RelationLinkManifestation::Inline(ref m)) => {
let is_self_rel = relation.is_self_relation();

if is_self_rel && (self.relation_side == RelationSide::B || self.related_field().is_hidden) {
if is_self_rel && self.is_hidden {
self.name.clone()
} else if is_self_rel && (self.relation_side == RelationSide::B || self.related_field().is_hidden) {
m.referencing_column.clone()
} else if is_self_rel && self.relation_side == RelationSide::A {
self.name.clone()
Expand All @@ -107,7 +109,9 @@ impl RelationField {
Some(RelationLinkManifestation::Inline(ref m)) => {
let is_self_rel = relation.is_self_relation();

if is_self_rel && (self.relation_side == RelationSide::B || self.related_field().is_hidden) {
if is_self_rel && self.is_hidden {
false
} else if is_self_rel && (self.relation_side == RelationSide::B || self.related_field().is_hidden) {
true
} else if is_self_rel && self.relation_side == RelationSide::A {
false
Expand Down
48 changes: 32 additions & 16 deletions server/prisma-rs/prisma-models/src/relation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ pub struct InlineRelation {
pub referencing_column: String,
}

impl InlineRelation {
fn referencing_column(&self, table: Table) -> Column {
let column_name: &str = self.referencing_column.as_ref();
let column = Column::from(column_name);

column.table(table)
}
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RelationTable {
Expand Down Expand Up @@ -210,15 +219,19 @@ impl Relation {
match self.manifestation {
Some(RelationTable(ref m)) => m.model_a_column.clone().into(),
Some(Inline(ref m)) => {
let model = self.model_a();

if m.in_table_of_model_name == model.name && !self.is_self_relation() {
model.fields().id().as_column()
let model_a = self.model_a();
let model_b = self.model_b();

if self.is_self_relation() && self.field_a().is_hidden {
model_a.fields().id().as_column()
} else if self.is_self_relation() && self.field_b().is_hidden {
model_b.fields().id().as_column()
} else if self.is_self_relation() {
m.referencing_column(self.relation_table())
} else if m.in_table_of_model_name == model_a.name && !self.is_self_relation() {
model_a.fields().id().as_column()
} else {
let column_name: &str = m.referencing_column.as_ref();
let column = Column::from(column_name);

column.table(self.relation_table())
m.referencing_column(self.relation_table())
}
}
None => Self::MODEL_A_DEFAULT_COLUMN.into(),
Expand All @@ -231,15 +244,18 @@ impl Relation {
match self.manifestation {
Some(RelationTable(ref m)) => m.model_b_column.clone().into(),
Some(Inline(ref m)) => {
let model = self.model_b();

if m.in_table_of_model_name == model.name {
model.fields().id().as_column()
let model_b = self.model_b();

if self.is_self_relation() && self.field_a().is_hidden {
m.referencing_column(self.relation_table())
} else if self.is_self_relation() && self.field_b().is_hidden {
m.referencing_column(self.relation_table())
} else if self.is_self_relation() {
model_b.fields().id().as_column()
} else if m.in_table_of_model_name == model_b.name && !self.is_self_relation() {
model_b.fields().id().as_column()
} else {
let column_name: &str = m.referencing_column.as_ref();
let column = Column::from(column_name);

column.table(self.relation_table())
m.referencing_column(self.relation_table())
}
}
None => Self::MODEL_B_DEFAULT_COLUMN.into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,18 @@ case class CoolArgs(raw: Map[String, Any]) {
}

def extractNodeSelector(model: Model): NodeSelector = {
raw.asInstanceOf[Map[String, Option[Any]]].collectFirst {
val map = raw.asInstanceOf[Map[String, Option[Any]]]
val uniquesWithValues = map.collect {
case (fieldName, Some(value)) =>
NodeSelector(model,
model.getScalarFieldByName_!(fieldName),
GCAnyConverter(model.getFieldByName_!(fieldName).typeIdentifier, isList = false).toGCValue(value).get)
} getOrElse {
throw APIErrors.NullProvidedForWhereError(model.name)
}

uniquesWithValues.size match {
case 0 => throw APIErrors.NullProvidedForWhereError(model.name)
case 1 => uniquesWithValues.head
case _ => throw APIErrors.TwoManyUniquesForWhereError(model.name)
}
}

Expand Down
Loading

0 comments on commit 191c4bc

Please sign in to comment.