Squeryl partial update does not compile - squeryl

I'm not sure what squeryl is trying to tell me here:
Error: Cannot prove that org.squeryl.dsl.fsm.Unconditioned =:= org.squeryl.dsl.fsm.Conditioned.
On:
inTransaction {
update(AppDB.postTable) { p =>
where(p.id === postId)
set(p.upVotes := p.upVotes.~ + 1)
}
The error is on the set clause
schema:
object AppDB extends Schema {
val postTable = table[Post]("post")
val replyTable = table[Reply]("reply")
val postToReplies = oneToManyRelation(postTable, replyTable)
.via((p,r) => p.id === r.postId)
}
case class Post(body: String, image:Option[String]) extends KeyedEntity[Long] {
val id: Long = 0
val posted: Date = new Date()
var upVotes: Long = 0
var downVotes: Long = 0
}
case class Reply(postId: Long, body: String, image:Option[String]) extends KeyedEntity[Long] {
val id: Long = 0
val posted: Date = new Date()
}
Thanks for any help.

Try using () instead of {} around your where and set clauses, like:
inTransaction {
update(AppDB.postTable) ( p =>
where(p.id === postId)
set(p.upVotes := p.upVotes.~ + 1)
)
}
I am not sure why, but I have had issues with {} in the past. When I tested the change against your code, the problem seemed to get resolved.

Related

How to traverse an inner array in motoko?

I am new to Motoko and internet computer, when I am working I am having too much difficulties that might look simple, I am having difficulties doing this, posting the link to forum question here
https://forum.dfinity.org/t/how-to-traverse-inner-array-of-a-trie/12941?u=manubodhi
Please help if somebody is well versed in Motoko and Dfinity
I prepared a small code in motoko playground for you in order to see how you can traverse inner array and achieve your goal of filtering Trie. Here is as well saved project in motoko playground: https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/?tag=1150943578
Shortly to filter through inner array you can use:
let trieOfDishes = Trie.filter<DishId, Dish>(dishes, func (k, v) {
Array.find<MealTypeId>(v.mealTypeId, func(x : MealTypeId) { x == mealTypeId }) != null ;
});
Full code of canister implementation:
import Trie "mo:base/Trie";
import Array "mo:base/Array";
import Iter "mo:base/Iter";
import Nat32 "mo:base/Nat32";
actor Dishes {
type DishId = Nat32;
type DishTypeId = Nat32;
type MealTypeId = Nat32;
public type Dish = {
dishId: DishId;
dishTypeId : DishTypeId;
mealTypeId : [MealTypeId]
};
var dishes: Trie.Trie<DishId, Dish> = Trie.empty();
private func key(x : DishId) : Trie.Key<DishId> {
return { hash = x; key = x };
};
public func add_dish(dish: Dish) : async Dish {
dishes := Trie.replace(dishes, key(dish.dishId), Nat32.equal, ?dish).0;
return dish;
};
public query func getDishesByDishId (dishTypeId : DishTypeId) : async [(DishId, Dish)] {
let trieOfDishes = Trie.filter<DishId, Dish>(dishes, func (k, v) { v.dishId == dishTypeId } );
let arrayOfDishes : [(DishId, Dish)] = Iter.toArray(Trie.iter(trieOfDishes));
return arrayOfDishes;
};
public query func getDishesBymealTypeId (mealTypeId : MealTypeId) : async [(DishId, Dish)] {
let trieOfDishes = Trie.filter<DishId, Dish>(dishes, func (k, v) {
Array.find<MealTypeId>(v.mealTypeId, func(x : MealTypeId) { x == mealTypeId }) != null ;
});
let arrayOfDishes : [(DishId, Dish)] = Iter.toArray(Trie.iter(trieOfDishes));
return arrayOfDishes;
};
}

I tried to run this code and every time I run it shows this result

private fun moveMarkerAnimation(key: String, newData: AnimationModel, marker: Marker?, from: String, to: String) {
if (!newData.isRun)
{
compositeDisposable.add(
iGoogleAPI.getDirections(
"driving",
"less_driving",
from, to,
getString(R.string.google_api_key1)
)!!.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { returnResult ->
Log.d("API_RETURN",returnResult,)
try {
val jsonObject = JSONObject(returnResult)
val jsonArray = jsonObject.getJSONArray("routes")
for ( i in 0 until jsonArray.length())
{
val route = jsonArray.getJSONObject(i)
val poly = route.getJSONObject("overview_polyLine")
val polyLine = poly.getString("points")
polylineList = Common.decodePoly(polyLine) as java.util.ArrayList<LatLng?>
}
handler = Handler()
index = -1
next = 1
val runnable = object :Runnable{
override fun run() {
if (polylineList!!.size > 1)
{
if (index< polylineList!!.size)
{
index ++
next = index+1
start = polylineList!![index] !!
end = polylineList!![next]!!
}
val valueAnimator = ValueAnimator.ofInt(0,1)
valueAnimator.duration = 3000
valueAnimator.interpolator = LinearInterpolator()
valueAnimator.addUpdateListener { value ->
v = value.animatedFraction
lat = v*end !!.latitude + (1-v) * start!!.latitude
lng = v*end !!.longitude+ (1-v) * start!!.longitude
val newPos = LatLng(lat,lng)
marker!!.position = newPos
marker!!.setAnchor(0.5f,0.5f)
marker!!.rotation = Common.getBearing(start!!,newPos)
}
valueAnimator.start()
if (index < polylineList!!.size-2)
{
handler!!.postDelayed(this,1500)
}else if (index < polylineList!!.size-1)
{
newData.isRun = false
Common.driversSubscrib.put(key,newData)
}
}
}
}
handler!!.postDelayed(runnable,1500)
}
catch (e:java.lang.Exception){
Snackbar.make(requireView(),e.message!!,Snackbar.LENGTH_LONG).show()
}
When the site changes from from firebase this result appears
022-04-26 13:19:30.912 23482-23482/com.example.bustrackerriderapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bustrackerriderapp, PID: 23482
io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading
what should I do to fix this problem

Compare multiple fields of Object to those in an ArrayList of Objects

I have created a 'SiteObject' which includes the following fields:
data class SiteObject(
//Site entry fields (10 fields)
var siteReference: String = "",
var siteAddress: String = "",
var sitePhoneNumber: String = "",
var siteEmail: String = "",
var invoiceAddress: String = "",
var invoicePhoneNumber: String = "",
var invoiceEmail: String = "",
var website: String = "",
var companyNumber: String = "",
var vatNumber: String = "",
)
I want to filter an ArrayList<SiteObject> (call it allSites) by checking if any of the fields of the objects within the list match those in a specific <SiteObject> (call it currentSite).
So for example, I know how to filter looking at one field:
fun checkIfExistingSite(currentSite: SiteObject) : ArrayList<SiteObject> {
var matchingSites = ArrayList<SiteObject>()
allSites.value?.filter { site ->
site.siteReference.contains(currentSite.siteReference)}?.let { matchingSites.addAll(it)
}
return matchingSites
}
But I am looking for an elegant way to create a list where I compare the matching fields in each of the objects in allSites with the corresponding fields in currentSite..
This will give me a list of sites that may be the same (allowing for differences in the way user inputs data) which I can present to the user to check.
Use equals property of Data Class:
val matchingSites: List<SiteObject> = allSites
.filterNotNull()
.filter { it.equals(currentSite) }
If you are looking for a more loose equlity criteria than the full match of all fields values, I would suggest usage of reflection (note that this approach could have performance penalties):
val memberProperties = SiteObject::class.memberProperties
val minMatchingProperties = 9 //or whatever number that makes sense in you case
val matchingItems = allSites.filter {
memberProperties.atLeast(minMatchingProperties) { property -> property.get(it) == property.get(currentSite) }
}
fun <E> Iterable<E>.atLeast(n: Int, predicate: (E) -> Boolean): Boolean {
val size = count()
return when {
n == 1 -> this.any(predicate)
n == size -> this.all(predicate)
n > size - n + 1 -> this.atLeast(size - n + 1) { !predicate.invoke(it) }
else -> {
var count = 0
for (element in this) {
if (predicate.invoke(element)) count++
if (count >= n) return true
}
return false
}
}
}
you could specify all the fields by which you want to match the currentSite inside the filter predicate:
fun checkIfExistingSite(currentSite: SiteObject) =
allSites.filter {
it.siteAddress == currentSite.siteAddress
|| it.sitePhoneNumber == currentSite.sitePhoneNumber
|| it.siteReference == currentSite.siteReference
}
Long but fast solution because of short circuiting.
If the list is nullable you can transform it to a non nullable list like:
allSites?filter{...}.orEmpty()
// or imho better
allSites.orEmpty().filter{...}

Pass by value. Array

I have two arrays. But when I change second - first change too.
I tried
.clone()
.copyOf()
but it didn't work for me.
object MatrixObject {
var table: Array<Array<Int>>? = null
fun randOf(n: Int) {
table= Array(n, { Array(n, { Random().nextInt(100 - 0) + 0 }) })
}
var tableF: Array<Array<Int>>? = null
get() {
if (field==null)
factorization()
return field
}
fun factorization() {
tableF = table!!
... //here I change elements of tableF
}
}
I tried
for(row in 0 until table!!.size)
tableF!![row] = Arrays.copyOf(table!![row], table!![row].size)
and
for(row in 0 until table!!.size)
tableF!![row] = table!![row].clone() // and copyOf()
but it still doesn't work.
I found the solution.I initialized the array.
tableF= Array(table!!.size, { Array(table!!.size, {0}) })
for(row in 0 until table!!.size)
tableF!![row] = table!![row].clone()

Squeryl geo queries with a postgres backend?

How can I perform geo queries using Squeryl with a postgres backend? The sort of queries I want to run are "return all users within x kilometres", etc.
If geo queries aren't supported directly/through a plugin, how can I run raw SQL queries? I saw one gist and it looked complicated.
Update
Specifically I want to run the following query:
SELECT events.id, events.name FROM events
WHERE earth_box( {current_user_lat}, {current_user_lng},
{radius_in_metres}) #> ll_to_earth(events.lat, events.lng);
This is taken from http://johanndutoit.net/searching-in-a-radius-using-postgres/
This object should solve your problem.
object object RawSql {
def q(query: String, args: Any*) =
new RawTupleQuery(query, args)
class RawTupleQuery(query: String, args: Seq[Any]) {
private def prep = {
val s = Session.currentSession
val st = s.connection.prepareStatement(query)
def unwrap(o: Any) = o match {
case None => null
case Some(ob) => ob.asInstanceOf[AnyRef]
case null => null
case a#AnyRef => a
case a#_ => a
}
for(z <- args.zipWithIndex) {
st.setObject(z._2 + 1, unwrap(z._1))
}
st
}
def toSeq[A1]()(implicit f1 : TypedExpressionFactory[A1,_]) = {
val st = prep
val rs = st.executeQuery
try {
val ab = new ArrayBuffer[A1]
val m1 = f1.thisMapper.asInstanceOf[PrimitiveJdbcMapper[A1]]
while(rs.next)
ab.append(m1.convertFromJdbc(m1.extractNativeJdbcValue(rs, 1)))
ab
}
finally {
rs.close()
st.close()
}
}
def toTupleSeq[A1,A2]()(implicit f1 : TypedExpressionFactory[A1,_], f2 : TypedExpressionFactory[A2,_]) = {
val st = prep
val rs = st.executeQuery
try {
val ab = new ArrayBuffer[(A1,A2)]
val m1 = f1.thisMapper.asInstanceOf[PrimitiveJdbcMapper[A1]]
val m2 = f2.thisMapper.asInstanceOf[PrimitiveJdbcMapper[A2]]
while(rs.next)
ab.append(
(m1.convertFromJdbc(m1.extractNativeJdbcValue(rs, 1)),
m2.convertFromJdbc(m2.extractNativeJdbcValue(rs, 2))))
ab
}
finally {
rs.close()
st.close()
}
}
}
}
I got from this gist:
https://gist.github.com/max-l/9250053