-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue#4 Adding .singleOption
#34
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,15 @@ trait Queryable[-Q, R] { | |
*/ | ||
def isSingleRow(q: Q): Boolean | ||
|
||
/** | ||
* Whether this query expects a single row to be returned, if so we can assert on | ||
* the number of rows and raise an error if 2+ rows are present. Returns | ||
* None if 0 rows are present. | ||
* @param q | ||
* @return | ||
*/ | ||
def isSingleRowOption(q: Q): Boolean | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if instead of adding another method I think the danger with the current approach is that we end up with two somewhat mutually exclusive cases: |
||
|
||
/** | ||
* Converts the given queryable value into a [[SqlStr]], that can then be executed | ||
* by the underlying SQL JDBC interface | ||
|
@@ -91,6 +100,7 @@ object Queryable { | |
def isGetGeneratedKeys(q: Q): Option[Queryable.Row[?, ?]] = None | ||
def isExecuteUpdate(q: Q): Boolean = false | ||
def isSingleRow(q: Q): Boolean = true | ||
def isSingleRowOption(q: Q): Boolean = true | ||
def walkLabels(): Seq[List[String]] | ||
def walkLabels(q: Q): Seq[List[String]] = walkLabels() | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ trait Query[R] extends Renderable { | |
protected def queryWalkLabels(): Seq[List[String]] | ||
protected def queryWalkExprs(): Seq[Expr[?]] | ||
protected def queryIsSingleRow: Boolean | ||
protected def queryIsSingleRowOption: Boolean | ||
protected def queryGetGeneratedKeys: Option[Queryable.Row[?, ?]] = None | ||
protected def queryIsExecuteUpdate: Boolean = false | ||
|
||
|
@@ -26,6 +27,7 @@ object Query { | |
protected def queryWalkLabels(): Seq[List[String]] = Nil | ||
protected def queryWalkExprs(): Seq[Expr[?]] = Nil | ||
protected override def queryIsSingleRow = true | ||
protected override def queryIsSingleRowOption = true | ||
protected override def queryIsExecuteUpdate = true | ||
} | ||
|
||
|
@@ -38,6 +40,7 @@ object Query { | |
protected def queryWalkLabels() = query.queryWalkLabels() | ||
protected def queryWalkExprs() = query.queryWalkExprs() | ||
protected override def queryIsSingleRow = query.queryIsSingleRow | ||
protected override def queryIsSingleRowOption = query.queryIsSingleRowOption | ||
protected override def queryIsExecuteUpdate = query.queryIsExecuteUpdate | ||
} | ||
|
||
|
@@ -49,6 +52,7 @@ object Query { | |
protected def queryWalkLabels() = qr.walkLabels(expr) | ||
protected def queryWalkExprs() = qr.walkExprs(expr) | ||
protected override def queryIsSingleRow = qr.isSingleRow(expr) | ||
protected override def queryIsSingleRowOption = qr.isSingleRowOption(expr) | ||
protected override def queryIsExecuteUpdate = qr.isExecuteUpdate(expr) | ||
} | ||
|
||
|
@@ -57,6 +61,7 @@ object Query { | |
def walkLabels[R](q: Query[R]) = q.queryWalkLabels() | ||
def walkSqlExprs[R](q: Query[R]) = q.queryWalkExprs() | ||
def isSingleRow[R](q: Query[R]) = q.queryIsSingleRow | ||
def isSingleRowOption[R](q: Query[R]) = q.queryIsSingleRowOption | ||
def construct[R](q: Query[R], args: Queryable.ResultSetIterator) = q.queryConstruct(args) | ||
|
||
/** | ||
|
@@ -70,6 +75,7 @@ object Query { | |
override def walkLabels(q: Q) = q.queryWalkLabels() | ||
override def walkExprs(q: Q) = q.queryWalkExprs() | ||
override def isSingleRow(q: Q) = q.queryIsSingleRow | ||
override def isSingleRowOption(q: Q) = q.queryIsSingleRowOption | ||
|
||
def renderSql(q: Q, ctx: Context): SqlStr = q.renderSql(ctx) | ||
|
||
|
@@ -86,4 +92,17 @@ object Query { | |
protected override def queryConstruct(args: Queryable.ResultSetIterator): R = | ||
query.queryConstruct(args).asInstanceOf[R] | ||
} | ||
|
||
/** | ||
* A [[Query]] that wraps another [[Query]] but sets [[queryIsSingleRow]] to `true` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment should state: sets [[queryIsSingleRowOption]] to |
||
*/ | ||
class SingleOption[R](protected val query: Query[Seq[R]]) extends Query.DelegateQuery[R] | ||
{ | ||
protected override def queryIsSingleRowOption: Boolean = true | ||
|
||
private[scalasql] def renderSql(ctx: Context): SqlStr = Renderable.renderSql(query)(ctx) | ||
|
||
protected override def queryConstruct(args: Queryable.ResultSetIterator): R = | ||
query.queryConstruct(args).asInstanceOf[R] | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this on
DbApi
..single
is implemented onSelect
and doesn't need any dedicated methods onDbApi
, so I would expectsingleOption
would be similar