-
Notifications
You must be signed in to change notification settings - Fork 15
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
Make responsibilities more focused and clear #89
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ package com.lucidchart.relate | |
import java.sql.ResultSetMetaData | ||
import scala.collection.mutable | ||
import scala.language.higherKinds | ||
import scala.util.Using | ||
|
||
object SqlResult { | ||
def apply(resultSet: java.sql.ResultSet) = new SqlResult(resultSet) | ||
|
@@ -19,9 +20,8 @@ object SqlResult { | |
* The extraction methods (int, string, long, etc.) also have "strict" counterparts. The "strict" methods are slightly | ||
* faster, but do not do type checking or handle null values. | ||
*/ | ||
class SqlResult(val resultSet: java.sql.ResultSet) extends ResultSetWrapper with CollectionsSqlResult { | ||
|
||
def as[A: RowParser](): A = implicitly[RowParser[A]].parse(asRow) | ||
class SqlResult(private[relate] val resultSet: java.sql.ResultSet) extends CollectionsSqlResult { | ||
private[relate] def withResultSet[A](f: (java.sql.ResultSet) => A) = Using.resource(resultSet)(f) | ||
|
||
def asSingle[A: RowParser](): A = asCollection[A, Seq](1).head | ||
def asSingle[A](parser: SqlRow => A): A = asCollection[A, Seq](parser, 1).head | ||
|
@@ -42,20 +42,16 @@ class SqlResult(val resultSet: java.sql.ResultSet) extends ResultSetWrapper with | |
val mm: mutable.MultiMap[U, V] = new mutable.HashMap[U, mutable.Set[V]] with mutable.MultiMap[U, V] | ||
withResultSet { resultSet => | ||
while (resultSet.next()) { | ||
val parsed = parser(asRow) | ||
val parsed = parser(SqlRow(resultSet)) | ||
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. would it be worth replacing 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. If I did, I'd want it to be private to relate, as it doesn't really align with the rest of the public-facing interface, which all involves processing the whole |
||
mm.addBinding(parsed._1, parsed._2) | ||
} | ||
} | ||
mm.toMap.map(x => x._1 -> x._2.toSet) | ||
} | ||
|
||
def asScalar[A](): A = asScalarOption.get | ||
def asScalarOption[A](): Option[A] = { | ||
if (resultSet.next()) { | ||
Some(resultSet.getObject(1).asInstanceOf[A]) | ||
} else { | ||
None | ||
} | ||
def asScalarOption[A](): Option[A] = withResultSet { resultSet => | ||
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. Can we make this 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. Honestly, I'd rather go the opposite direction, and make |
||
Option.when(resultSet.next())(resultSet.getObject(1).asInstanceOf[A]) | ||
} | ||
|
||
/** | ||
|
This file was deleted.
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.
Something I noticed, when looking over this, is that if we stop iterating over the iterator, then we won't close the resultSet.
I wonder if we should also replace
asIterator
withwithIterator
that calls a function with the Iterator, and ensure that it is closed at the end.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.
:upvote:
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.
I think
asIterator
intentionally skips the auto-closing stuff to give the user more control. I looked into this but wasn't able to quickly decide a good way to structure things as there are a lot of different pieces involved (e.g. this is the only place that uses StreamedStatementPreparer). I think it could be good to take a more comprehensive look at cleaning up/improving relate, but my main goal here is just to try to track down some data service issues, so I'm going to say this is out of scope