SubSonic3 Update Question - subsonic3

Is it possible to do something like this in SubSonic3?
_db.Update<Product>()
.Set("UnitPrice")
.EqualTo(UnitPrice + 5)
.Where<Product>(x=>x.ProductID==5)
.Execute();
I would need something lik this:
UPDATE Blocks
SET OrderId = OrderId - 1
WHERE ComponentId = 3
But in SubSonic3

I think you can here is a sample for demonstrating how you can use subsonic 3
// One thing you might not have seen with Linq To Sql is the ability to run Updates
//and Inserts, which I've always missed and have now implemented with SubSonic 3.0:
db.Update<Products>().Set(
x => x.Discontinued == false,
x => x.ReorderLevel == 100)
.Where(x=>x.Category==5)
.Execute();
db.Insert.Into<Region>(x => x.RegionID, x => x.RegionDescription)
.Values(6, "Hawaii")
.Execute();
and here a link to the full demonstration

i do it as a select
var model = ClassName.SingleOrDefault(x => x.id == 1);
model.name = "new name";
model.tel = " new telephone;
model.save();
done

Related

How to remove double quotes from keys in RDD and split JSON into two lines?

I need to modify the data to give input to CEP system, my current data looks like below
val rdd = {"var":"system-ready","value":0.0,"objectID":"2018","partnumber":2,"t":"2017-08-25 11:27:39.000"}
I need output like
t = "2017-08-25 11:27:39.000
Check = { var = "system-ready",value = 0.0, objectID = "2018", partnumber = 2 }
I have to write RDD map operations to achieve this if anybody suggests better option welcome. colcount is the number of columns.
rdd.map(x => x.split("\":").mkString("\" ="))
.map((f => (f.dropRight(1).split(",").last.toString, f.drop(1).split(",").toSeq.take(colCount-1).toString)))
.map(f => (f._1, f._2.replace("WrappedArray(", "Check = {")))
.map(f => (f._1.drop(0).replace("\"t\"", "t"), f._2.dropRight(1).replace("(", "{"))) /
.map(f => f.toString().split(",C").mkString("\nC").replace(")", "}").drop(0).replace("(", "")) // replacing , with \n, droping (
.map(f => f.replace("\" =\"", "=\"").replace("\", \"", "\",").replace("\" =", "=").replace(", \"", ",").replace("{\"", "{"))
Scala's JSON parser seems to be a good choice for this problem:
import scala.util.parsing.json
rdd.map( x => {
JSON.parseFull(x).get.asInstanceOf[Map[String,String]]
})
This will result in an RDD[Map[String, String]]. You can then access the t field from the JSON, for example, using:
.map(dict => "t = "+dict("t"))

Size check on future list in Scala

I have a method which return Future[List[Employee]]. I want to check the list size for various purpose. I am not able to call size on list and I think its because its in Future. Any suggestion?
val employees: Future[List[Employee]] = companyService.findEmployeesWorkingOn(someDate)
employees match {
case emp if(emp.size == 1) => Logger.info("Only one employee working")
case emp if(emp.size == 0) => Logger.info("No one working")
case _ => Logger.info("Multiple employees working")
}
You need to "wait" for the future to happen or not. You can use map to map the Future[List[Employee]] to a Future[Int] and use the onSuccess callback.
val sizeFuture = employees.map(_.size) // returns a Future[Int]
sizeFuture onSuccess {
case size:Int => println(size) // do your stuff here
}
Use a for comprehension which desugars to a flatMap,
for ( e <- employees ) yield e.size match {...}
Here list e is matched only if the future succeeds.
No need to check the size for your use case:
val employees: Future[List[Employee]] = …
val result = employees map {
case Nil => "no employees"
case List(e) => "one employee"
case es => "multiple employees"
}

slick 3 two leftJoin query result to classes mapping

Current question is relative with next one, but now I need to read the data from database instead of insert.
I have next three case classes:
case class A (id: Long, bList: List[B])
case class B (id: Long, aId: cList: List[C])
case class C (id: Long, bId: Long)
And query with two leftJoin functions and incomingAId for filtering aTable results:
val query = (for {
((aResult,bResult),cResult) <- aTable.filter(_.id === incomigAId)
.joinLeft(bTable).on(_.id === _.aId)
.joinLeft(cTable).on(_._2.map(_.id) === _.bId)
} yield ((aResult,bResult),cResult)).result.transactionally
Next query works and the result looks valid, but isn't easy to handle it to the case classes. Also, executionResult has Seq[Nothing] type and process of mapping requires something like that:
database.run(query).map{ executionResult =>
executionResult.map { vectorElement: [Tuple2[Tuple2[A, Option[B]], Option[C]]]
...
}
}
Is there any proper way to prevent Seq[Nothing] (changes in query)?
Or if the query result type is fine, could you please share solution how to map it to the case classes above?
Right now I'm using next solution, but I suppose that some part of code can be optimized (e.g. groupBy replacing with something else).
execute(query).mapTo[Vector[((A, Option[B]), Option[C])]]
.flatMap { insideFuture =>
insideFuture.groupBy(_._1._1).mapValues { values =>
//scala groupBy losts ordering
val orderedB = values.groupBy(_._1._2).toSeq.sortBy(_._1.map(_.id)).toMap
orderedB.mapValues(_.map(_._2))
}.headOption match {
case Some(data) => Future.successful {
data._1.copy(bList = data._2.map {
case (Some(bElement), optionCElements) =>
bElement.copy(cList = optionCElements.toList.flatten)
case _ =>
throw new Exception("Invalid query result. Unable to find B elements")
}.toList)
}
case None => Future.failed(new Exception("Unable to find A with next id " + incomigAId))
}
}
}

How do I do a where OR on two columns in the same table?

I have a membership model, and I want to search OR on two columns....not sure how to do it.
I tried this:
u1.all_memberships.where(inviter: u2, invited: u2)
Membership Load (6.8ms) SELECT "memberships".* FROM "memberships" WHERE (memberships.user_id = 1 OR memberships.invited_id = 1) AND "memberships"."user_id" = 3 AND "memberships"."invited_id" = 3
=> []
But note the 2 AND on both queries, when ideally what I would like to do is literally just replace all the ANDs with ORs.
So I would love if the query looked something like this:
Membership Load (6.8ms) SELECT "memberships".* FROM "memberships" WHERE (memberships.user_id = 1 OR memberships.invited_id = 1) OR (memberships.user_id = 3 OR memberships.invited_id = 3)
Assuming that my modification is syntactically correct SQL ofcourse.
How do I do that with a where clause? Is that possible?
I expect It can help
where("inviter_id = ? OR invited_id = ? ", u2.id, u2.id)
DRYer solution
where("inviter_id = :uid OR invited_id = :uid ", uid: u2.id)

Faking an enumerator in FakeItEasy

How can I create a fake with FakeItEasy that allows different return values on successive calls. This is one example of what I would like to be able to do:
var enumerator = A.Fake<IDictionaryEnumerator>();
A.CallTo(() => enumerator.MoveNext()).Returns(true); //Expected value for first call
A.CallTo(() => enumerator.Key).Returns("key1");
A.CallTo(() => enumerator.Value).Returns("value1");
A.CallTo(() => enumerator.MoveNext()).Returns(false); //Expected value for second call
Assert.IsTrue(enumerator.MoveNext()); //Fails
Assert.IsFalse(enumerator.MoveNext());
The assertion will fail since it the last set up of MoveNext will overwrite the first one.
Is it possible to do what I want in FakeItEasy?
.
[Edit]
Clarified the original question's example and provided a working example below.
Based on Patrik's answer this code shows how you can set up the fake. The trick is to reverse all setups and use Once().
var enumerator = A.Fake<IDictionaryEnumerator>();
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
A.CallTo(() => enumerator.MoveNext()).Returns(true).NumberOfTimes(2);
A.CallTo(() => enumerator.Key).Returns("key2").Once();
A.CallTo(() => enumerator.Value).Returns("value2").Once();
A.CallTo(() => enumerator.Key).Returns("key1").Once();
A.CallTo(() => enumerator.Value).Returns("value1").Once();
while(enumerator.MoveNext())
{
Debug.WriteLine(enumerator.Key + ": "+ enumerator.Value);
}
This will print:
key1: value1
key2: value2
I'm not entirely sure that I understand what you mean, the code you supplied will always fail. However if you mean that you want it to return true the second time it's called it can be done. There are a couple of different ways that I can think of, two of them are:
A.CallTo(() => enumerator.MoveNext()).ReturnsNextFromSequence(false, true);
The other way is:
A.CallTo(() => enumerator.MoveNext()).Returns(true);
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
Edit:
On second though I guess I understand your question better, what you want to happen is that MoveNext should return true the first time and false the second time? If that's the case just change the orders of the values in the examples above.
FakeItEasy does not use a record/replay model and you are correct in that the latest configured rule has precedence over any earlier specified rules. That's why you have to specify repeat - ".Once()" - on the latest configuration for it only to be valid once.
There are many reasons why the latest has precedence, one of the most important ones is that it lets you set up a default return value in the setup of your fixture and override it to return specific values in some of your tests, this is impossible when using a record/replay model.
The OP's example based on Patrik's answer is fine ... but tedious if the sequence grows large. To supplement that answer consider that even though fake/mock examples most often show a bunch of straight line code to Arrange themselves you actually have the full power of a programming language at your command. Conditionals, loops, and even procedures.
So consider the following:
public static void AFakeDictionaryEnumeratorReturns(
IDictionaryEnumerator enumerator, params object[] pairs)
{
if (0 != pairs.Length % 2)
throw new ArgumentException("pairs must have even number of elements", "pairs");
int n = pairs.Length / 2;
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
A.CallTo(() => enumerator.MoveNext()).Returns(true).NumberOfTimes(n);
for (int i = pairs.Length; i > 0; i -= 2)
{
A.CallTo(() => enumerator.Key).Returns(pairs[i - 2]).Once();
A.CallTo(() => enumerator.Value).Returns(pairs[i - 1]).Once();
}
}
and now the test becomes:
var enumerator = A.Fake<IDictionaryEnumerator>();
AFakeDictionaryEnumeratorReturns(enumerator,
"key1", "value1", "key2", "value2", "key3", "value3");
var keys = new List<object>();
var values = new List<object>();
while (enumerator.MoveNext())
{
keys.Add(enumerator.Key);
values.Add(enumerator.Value);
}
Assert.Equal(new List<object> { "key1", "key2", "key3" }, keys);
Assert.Equal(new List<object> { "value1", "value2", "value3" }, values);
(An IDictionaryEnumerator deals in pairs, so this example isn't as clearly beneficial as it could be. For a standard IEnumerator<T> a single static generic method would serve for a whole bunch of different enumerators.)