How extract information from my model on the handler in yesod? - entity

my question is about how can I extract from a list of query result the year of each entity Post.
My model is this:
Post
name Text
content Text
date UTCTime default=CURRENT_TIME
deriving Show
And my handler looks like this:
getYearR :: Integer -> Handler Html
getYearR year = do
posts <- runDB $ selectList [] [Desc PostDate]
years <- --some function with posts for extract the list of years
defaultLayout $ do
aDomId <- newIdent
setTitle "Blog"
$(widgetFile "homepage")
Maybe the solution is related with some basic knowledge about monads but I don't know how that works for this situation.
Thanks for your time and I really appreciate your help

First I created a convenience function to extract the year. I referenced these docs on getting the Day from UTCTime, and these docs on getting the year from the Day.
import Data.Time
getYear :: UTCTime -> Integer
getYear time =
let (year,_,_) = toGregorian $ utctDay time
in year
Using this function, I can get a list of years by extracting the Haskell record from the Entity using entityVal, extract the UTCTime using postDate, then extract the year using my getYear function
let years = map (getYear . postDate . entityVal) posts
If you're using the list of years in Hamlet, you could skip creating the intermediate years value and just iterate through posts:
<ul>
$forall Entity id post <- posts
<li>
<h4>The year is #{getYear $ postDate post}</a>

Related

I have an error when I try to subtract in Kotlin

val year : Int = spinYear.getSelectedItem() as Int
selDate.text = "$year / $month / $date"
val curTime = LocalDateTime.now()
val curYear : Int = curTime.year
val difYear : Int = curYear - year
ageInMins.text = difYear.toString()
The language is Kotlin, and this is a part of my code.
The value year comes from a spinner named spinYear, and I got the selected value as an integer. Ultimately I want to substitute the text ageInMins with the value difYear.
I'm trying to define my difYear by subtracting the two variables: curYear and year, but the app crashes every time.
It seems like both of the variables I'm subtracting are of type Int, so I have no idea what to do with this problem.
If someone could give me an advice it would be great :)
I searched around Google to find information about this, but there was no useful information. I also tried to put .toInt() to the values but it didn't work. I tried every single thing I can think of, but it did not work. So I am seeking help from you guys.

Bad performance when filtering Azure logs - WCF Data Services filters

Azure Diagnostics is pushing Windows Events into a storage table "WADWindowsEventLogsTable".
I would like to query this storage Table using VisualStudio(2015) and CloudExplorer.
As this table has an huge content, I'm indefinitely waiting for the results..
Here is a query sample:
EventId eq 4096 and Timestamp gt datetime'2016-06-24T08:20:00' and Timestamp lt datetime'2016-06-24T10:00:00'
I suppose that this query is correct ?
Does exist a way to improve performance ?
filter result columns ?
return only TOP X results ?
another usefull tips ?
I know that a better way would be to script that; for example using Python, but I would like to use the UI as much as possible..
(Edit) following Gaurav Mantri answer I used this little C# program to build my query. The answer is so quick and that solve my initial performance issue:
static void Main(string[] args)
{
string startDate = "24 June 2016 8:20:00 AM";
string endDate = "24 June 2016 10:00:00 AM";
string startPKey = convertDateToPKey(startDate);
string endPKey = convertDateToPKey(endDate);
Debug.WriteLine("(PartitionKey gt '" + startPKey + "'"
+ " and PartitionKey le '" + endPKey +"')"
+ " and (EventId eq 4096)"
);
}
private static string convertDateToPKey(string myDate)
{
System.DateTime dt = System.Convert.ToDateTime(myDate);
long dt2ticks = dt.Ticks;
string ticks = System.Convert.ToString(dt2ticks);
return "0" + ticks;
}
NB: for those, like me, who are searching so far away how to export results to a CSV file, you should know that this icon is your answer (and it's not a 'undo' ;) ):
In your query, you're filtering on Timestamp attribute which is not indexed (Only PartitionKey and RowKey attributes are indexed). Thus your query is making a full table scan (i.e. going from the 1st record till the time it finds a matching record) and hence not optimized.
In order to avoid full table scan, please use PartitionKey in your query. In case of WADWindowsEventLogsTable, the PartitionKey essentially represents the date/time value in ticks. What you would need to do is convert the date/time range for which you want to get the data into ticks, prepend a 0 in front of it and then use it in the query.
So your query would be something like:
(PartitionKey gt 'from date/time value in ticks prepended with 0' and PartitionKey le 'to date/time value in ticks prepended with 0') and (EventId eq 4096)
I wrote a blog post about it some time ago that you may find useful: http://gauravmantri.com/2012/02/17/effective-way-of-fetching-diagnostics-data-from-windows-azure-diagnostics-table-hint-use-partitionkey/

Dates for different calendars

I am working on a project which is running in 2 countries already. Everything was fine until we deployed the project in Nepal. The problem is they are not working with standard Gregorian calendar. They have their own calendar called Bikram Sanwant Calendar. Our existing database has DateTime/Date columns which I cannot use any more because few months in their calendar have 32 days which is not a valid date according to the Gregorian calendar. So we have thought of saving all the dates in 3 different columns like Day,Month and year. Not just that but we also have used inbuilt standard SQL DateTime Functions like DateAdd, DateDiff etc... So I will also have to write my own functions and change all the queries, Stored Procedures and Functions.
Does anyone know how to deal with this or have better idea about this issue?
Please give your input and suggestions.
Thanks in advance.
Check this php code to convert AD to BS. Hope this will help you in understanding more.
<?php
//The Vikram Samvat calendar is 56 years 8 months and 14 days ahead (in count) of the solar Gregorian calendar
//date_default_timezone_set('Asia/Kathmandu');
$date = date('Y-m-d');
$ts1 = strtotime($date);
$year1 = date('Y', $ts1) + 56;
$month1 = date('m', $ts1) + 8;
$day1 = date('d', $ts1) + 14;
if($month1 >12) {
$year1 = $year1+1;
//$remMonth = $month1-12;
$month1 = $month1-12;
}
if($day1 >30) {
$month1 = $month1+1;
//$remMonth = $month1-12;
$day1 = $day1-30;
}
//$day1 = date('d', $ts1);
echo $year1."-".$month1."-".$day1;
?>

How create utctime query from model on yesod?

Hi everyone my question is about how can I create a query on Yesod from my database for get only the instance which satisfy the condition by UTCtime.
My model is this:
Post
name Text
content Text
date UTCTime default=CURRENT_TIME
deriving Show
And I want a query which I can extract only the post which satisfy a date whit the year 2014, for example. I suppose my handler for the query must look something similar like this:
getYearR :: Integer -> Handler Html
getYearR year = do
posts <- runDB $ selectList [*With some code here about the date and year*] [Desc PostDate]
defaultLayout $ do
aDomId <- newIdent
setTitle "Blog"
$(widgetFile "homepage")
Maybe the solution is create a raw sql query, but I think that is not a right solution.
Thanks for your time and I really appreciate your help
You can try something like this:
let date = fromGregorian 2014 1 1
time = timeOfDayToTime $ TimeOfDay 0 0 0
posts <- runDB $ selectList [PostDate >. UTCTime date time] [Desc PostDate]
I'm not aware of any function in Persistent that can do this. Raw SQL query will also work.

Searching users by age range based on a birthdate in a database table

Now, I have a database table which stores information about users along with their birhtdate in the "datetime" format. This database table correlates with a respective ActiveRecord model.
In the user search form I want to implement search by age range (with two form dropdown fields, "from" and "to" age respectively).
I take it I have to convert age submitted via form into the actual "datetime" date before executing search against the database table.
I still don't have enough understanding of CDb Criteria and Yii in general. It seems like a common thing in social networks, but I haven't been able to find a sufficient answer to my question.
I kinda found a solution while I was waiting for some reply. But I figure I might not have been thinking straight so I probably came up with something not quite reasonable. But it works.
I created two variables in my User model:
public $fromBirthdate;
public $toBirthdate;
I changed the search fields in the search form from a single birthdate field to the fields "to" and "from", which hold integers signifying minimum and maximum age respectively.
I tied those fields to the newly created variables in the model.
<div class="row">
<?php echo $form->label($model,'fromBirthdate'); ?>
<?php echo $form->textField($model,'fromBirthdate'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'toBirthdate'); ?>
<?php echo $form->textField($model,'toBirthdate'); ?>
</div>
>
Then I wrote a function which transforms age into birthdate based on the current time:
//transforms age into birthdate based on current date
//#param integer age
//#param integer default age (what age should be applied in case the age parameter is null)
//$returns string date formatted MySQL timestamp
public function getBirthdate($age, $defaultAge)
{
if($age == null)
$age = $defaultAge;
$birthDate = date('Y-m-d H:i:s',strtotime("-" . $age . "years", time()));
return $birthDate;
}
I fiddled a little with the instance of CDbCriteria in the search() function of the model by adding the following line:
//specifies range of age the users should be searched within
//if either of the age fields ("to" or "from" age") was not filled, default age is applied
//default age range is from 10 to 110 years old.
$criteria->addBetweenCondition('birthdate', $this->getBirthdate($this->toBirthdate, 110), $this->getBirthdate($this->fromBirthdate, 10));
All in all, when a user submits age range via the search form, it gets stored in those two variables as integers. Then they get overwritten with the strings containing datetime stamps which are transformed from the age submitted.
I had to introduce so called "default min and max age values into the play" in case a user didn't specify min and max ages on search. I am not sure this one was the wisest idea ever, but it works fine with me.
I would recommend using a parameterized named scope for this: http://www.yiiframework.com/doc/guide/1.1/en/database.ar#named-scopes
Add the method below into your model, making sure to change createtime to the name of your own datetime column:
public function byAge($to, $from)
{
$from = new DateTime("-$from years");
$fromDate = $from->format('Y-m-d H:i:s');
$to = new DateTime("-$to years");
$toDate = $to->format('Y-m-d H:i:s');
$this->getDbCriteria()->mergeWith(array(
'condition' => 't.createtime BETWEEN :from AND :to',
'params' => array(
':from' => $fromDate,
':to' => $toDate,
),
'order' => 't.createtime DESC', // Youngest first
));
return $this;
}
Get the values of $to and $from from your form, where $to is the younger age and $from is the older age. Then to use the method, change the way you search by doing something like:
$model = new User;
$to = 12;
$from = 25;
// Set other model attributes based on user input
$dataProvider = $model->byAge($to, $from)->search();
I tested this with my own data and it worked, but let me know if you have trouble getting it to work with yours.