How can I call a sequence.nextVal using kotlin exposed - kotlin

We have a project where we use a Postgres sequence for generating an increasing number, but I cannot figure out how to actually use the sequence in kotlin exposed.
I see there is a Sequence class and a NextVal class encapsulating a sequence but those cannot be used by its own as far as I can see. I thought I could use Sequence.nextLongVal() but this one returns the NextVal class, no way to get the through value out of this one.
So how can I get the value of the nextVal() execution?

We stumbled across the same problem trying to utilize Sequence.nextLongVal() directly using Postgre and exposed. We found the following workaround.
A solution using exec
Assuming we have defined and created a sequence in our datasource:
val sequence = Sequence(/* our sequence's parameters */)
...
transaction {
SchemaUtils.createSequence(sequence)
}
We suggest to define a helper function to retrieve the next value of a given sequence using exposed's exec.
fun Transaction.nextValueOf(sequence: Sequence): Long = exec("SELECT nextval('${sequence.identifier}');") { resultSet ->
if (resultSet.next().not()) {
throw Error("Missing nextValue in resultSet of sequence '${sequence.identifier}'")
}
else {
resultSet.getLong(1)
}
} ?: throw Error("Unable to get nextValue of sequence '${sequence.identifier}'")
Now, we can use this function in a transaction as shown here:
transaction {
...
val nextValue = nextValueOf(sequence)
...
}

Related

Why can't I use map on Kotlins Regex Result sequence

I worked with Kotlin's Regex API to get occurences of some regular expression. I wanted to convert the finding directly into another object so I intuitively used map() on the result sequence.
I was very surprised that the map function is never called but forEach is working. This example should make it clear:
val regex = "a.".toRegex()
val txt = "abacad"
var counter = 0
regex.findAll(txt).forEach { counter++ }
println(counter) // 3
regex.findAll(txt).map { counter++ }
println(counter) // still 3 since map is not called
regex.findAll(txt).forEach { counter++ }
println(counter) // 6
My question is why? Did I oversee it in the documentation?
(tested on Kotlin 1.5.30)
findAll() returns a Sequence<MatchResult>. Operations on Sequence are classified either as intermediate or terminal. The documentation for the functions declares which type they are. map and onEach are intermediate. Their action is deferred until a terminal operation is made. forEach is terminal.
Manipulating a Sequence with map returns a new Sequence that will perform the mapping function only when it is actually iterated, such as by a call to forEach or using it in a for loop.
This is the purpose of Sequence, to defer mutating functional calls. It can reduce allocations of intermediate Lists, or in some cases avoid applying the mutations on every single item, such as if the terminal call in the chain is a find() call.

Create empty IFutureEnumerable instance

I have a method which performs an NHibernate query, and returns the values as an IEnumerable<long>. It is running a future query so the result is actually of type IFutureEnumerable<long>.
public static IEnumerable<long> GetQueryResults(IEnumerable<long> idsToFilterOn)
{
if((idsToFilterOn == null) || !(idsToFilterOn.Any()))
{
return Enumerable.Empty<long>();
}
else
{
IQueryOver<MyTable> query = GenerateTheBigQuery(idsToFilterOn);
return query.Future<long>();
}
}
I want this result to return IFutureEnumerable<long>, but I still want to first check the parameters, and if I know the result will be empty I want to just return an empty value without running a query.
If I just change the return type to IFutureEnumerable<long>, the line of code that returns Enumerable.Empty<long>() generates a compiler error (Cannot implicitly convert type...)
Is there some static method like FutureEnumerable.Empty<long>() which generates an IFutureEnumerable that returns an empty list?
Looking at the code, there doesn't appear to be any native support for that concept. IFutureEnumerable is implemented by two types, one of which is deprecated and neither offer the notion of emptiness.
I suppose that leaves it up to you to create a type that implements IFutureEnumerable<T> that supports emptiness.

How to repeat Mono while not empty

I have a method which returns like this!
Mono<Integer> getNumberFromSomewhere();
I need to keep calling this until it has no more items to emit. That is I need to make this as Flux<Integer>.
One option is to add repeat. the point is - I want to stop when the above method emits the first empty signal.
Is there any way to do this? I am looking for a clean way.
A built-in operator that does that (although it is intended for "deeper" nesting) is expand.
expand naturally stops expansion when the returned Publisher completes empty.
You could apply it to your use-case like this:
//this changes each time one subscribes to it
Mono<Integer> monoWithUnderlyingState;
Flux<Integer> repeated = monoWithUnderlyingState
.expand(i -> monoWithUnderlyingState);
I'm not aware of a built-in operator which would do the job straightaway. However, it can be done using a wrapper class and a mix of operators:
Flux<Integer> repeatUntilEmpty() {
return getNumberFromSomewhere()
.map(ResultWrapper::new)
.defaultIfEmpty(ResultWrapper.EMPTY)
.repeat()
.takeWhile(ResultWrapper::isNotEmpty)
}
// helper class, not necessarily needs to be Java record
record ResultWrapper(Integer value) {
public static final ResultWrapper EMPTY = new ResultWrapper(null);
public boolean isNotEmpty() {
return value != null;
}
}

Async Wait Efficient Execution

I need to iterate 100's of ids in parallel and collect the result in list. I am trying to do it in following way
val context = newFixedThreadPoolContext(5, "custom pool")
val list = mutableListOf<String>()
ids.map {
val result:Deferred<String> = async(context) {
getResult(it)
}
//list.add(result.await()
}.mapNotNull(result -> list.add(result.await())
I am getting error at
mapNotNull(result -> list.add(result.await())
as await method is not available. Why await is not applicable at this place? Instead commented line
//list.add(result.await()
is working fine.
What is the best way to run this block in parallel using coroutine with custom thread pool?
Generally, you go in the right direction: you need to create a list of Deferred and then await() on them.
If this is exactly the code you are using then you did not return anything from your first map { } block, so you don't get a List<Deferred> as you expect, but List<Unit> (list of nothing). Just remove val result:Deferred<String> = - this way you won't assign result to a variable, but return it from the lambda. Also, there are two syntactic errors in the last line: you used () instead of {} and there is a missing closing parenthesis.
After these changes I believe your code will work, but still, it is pretty weird. You seem to mix two distinct approaches to transform a collection into another. One is using higher-order functions like map() and another is using a loop and adding to a list. You use both of them at the same time. I think the following code should do exactly what you need (thanks #Joffrey for improving it):
val list = ids.map {
async(context) {
getResult(it)
}
}.awaitAll().filterNotNull()

Combine row.Scan and rows.Scan interfaces in go?

I have two queries against a particular table in Go - one to retrieve a single item and the other to return a list. The first one uses sql.DB.QueryRow because it only needs to retrieve a single row, and the second one uses sql.DB.Query to return a few different results.
The problem is that serialization takes some work and I'd like to DRY it up by having a single method that scans from a database row and reads it into a Go type. My code right now looks like:
// Some type which varies considerably from its DB representation, and takes some effort to serialize.
type Foo struct {
Baz *Baz
Board [8][8]int
}
// Get one foo by its id
func GetFoo(id int) {
row := db.QueryRow("select * from foo where id = ?", id)
// Work that's duplicated from below...
var foo Foo
row.Scan(&foo.blah, &foo.etc)
// Do more work to serialize the type...
}
// Get all of the fooes
func GetFooes() {
rows, err := db.Query("select * from foo")
for rows.Next() {
// Work that's duplicated from above...
var foo Foo
rows.Scan(&foo.blah, &foo.etc)
// Do more work to serialize the type...
}
}
However combining row.Scan and rows.Scan is proving to be a little tricky. I thought I could use something like:
func serializeFoo(scanner sql.Scanner) (*Foo, error) {
}
though sql.Scanner takes a single (value interface{}) and not a list of (...value interface{}).
Any advice here? Another solution would be to convert the single QueryRow call into a db.Query.
db.QueryRow is a convenience function. There is no reason to use it unless it will save on typing/code-complexity. In this case, it doesn't so I recommend you just use db.Query.
See http://golang.org/src/pkg/database/sql/sql.go?s=25740:25802#L966 for more details
As you mentioned, neither Row nor Rows implement the Scanner interface. Scanner is used for arguments of the variatic scan functions.
If you want to have a parameter that allows either Row or Rows, you need to make your own interface For example:
func serializeFoo(scanner interface{Scan(dest ...interface{}) error}) (*Foo, error) {
}