Rails Unit Test - ruby-on-rails-3

Please help. I am trying to write a unit test for a method in my model. It keeps giving me the following error:
{ 1) Error:
test_Total_for_a_given_date_range_for_Campaigns(LetterTest):
TypeError: can't convert ActiveSupport::Duration into String
c:/Users/Kay/rails-app/CS5942/app/models/letter.rb:19:in +'
c:/Users/Kay/rails-app/CS5942/app/models/letter.rb:19:intribe_total_on'
test/unit/letter_test.rb:17:in `block in '}
This is what i have in my test file:
test "Total for a given date range for Campaigns" do
end_date = (Date.today + 1.day).to_date.strftime('%Y-%m-%d')
expected = Letter.where("letter_campaign_id = '1' and created_at between '#{ (Date.today - 1.day).to_date.strftime('%Y-%m-%d')}' and #{end_date}").count
data = Letter.tribe_total_on( 1 , (Date.today - 1.day).to_date.strftime('%Y-%m-%d') , (Date.today).to_date.strftime('%Y-%m-%d'))
assert_equal expected, data
end
It seems to have a problem with the plus sign. I would be very happy if i could find a solution to it. Thanks.
This is the tribe_total_on method:
def self.tribe_total_on(tribe, start_date, end_date)
#Letter.connection.execute("SELECT COUNT(id) FROM letters WHERE letter_campaign_id = #{tribe} AND created_at BETWEEN '#{start_date.to_date.strftime('%Y-%m-%d')}' and '#{end_date.to_date.strftime('%Y-%m-%d')}'")[0][0]
end_date = end_date + 1.day #This is line 19 ...Had to include the one day to accomodate dates like 2011-06-05 01:02:03
Letter.where("letter_campaign_id = #{tribe} AND created_at between ? and ?", start_date.to_date, end_date.to_date).count
end

Open up Rails console and type in what you're trying to do and you'll get this:
(Date.today).to_date.strftime('%Y-%m-%d') + 1.day
TypeError: can't convert ActiveSupport::Duration into String
from (irb):20:in `+'
You're either going to have to do the conversion to strftime before you pass it to tribe_total_on or you're going to have to add 1.day to the date before you call strftime before you pass it to tribe_total_on.
So:
(Date.today + 1.day).to_date.strftime('%Y-%m-%d')
or:
def self.tribe_total_on(tribe, start_date, end_date)
end_date = (end_date + 1.day).to_date.strftime('%Y-%m-%d')

Related

Error in if (req_dur > maxdur) { : missing value where TRUE/FALSE needed

I am trying to call water level data from NOAA using the rnoaa library. Water level data is restricted to 31 days and I need data across multiple months. I found the following 'while' loop when looking for similar questions: Looking for a solution in R to loop through a date range to get climate data from NOAA API
When I run the code below, I get the following error:
Error in if (req_dur > maxdur) { : missing value where TRUE/FALSE needed
beginDate <- as.Date('2022-01-01')
endDate <- as.Date('2022-05-01')
date <- beginDate
while (date <= endDate){
water_level <- coops_search(
station_name = 8418150,
begin_date = date,
end_date = date + 1,
product = 'water_level',
datum = 'MHW',
units = 'metric',
time_zone = 'lst')
date <- date + 1
}
I've tried changing the beginDate and endDate parameters to the following and still get the same error:
beginDate<- as.Date("20220101",format = "%Y%m%d")
endDate <- as.Date("20220501",format = "%Y%m%d" )
Any suggestions? Thank you!

SpringJPA - inconsistent datatypes: expected NUMBER got BINARY

Im using SPRING JPA in my application and trying to run a native query as follows:
#Query (value="select max(ts) from abc.test s \n" +
"where abc.getTest(s.user_id) = :#{#userId} \n" +
"and upper(app_name) = 'TAX' and INSTR(s.user_id, '.') > 0 \n" +
"group by user_id, app_name", nativeQuery=true)
Timestamp getLastLogin(BigDecimal userId);
I am getting exception as follows:
Caused by: Error : 932, Position : 110, Sql = select max(ts) from abc.test s
where ac.getTest(s.user_id) = :1
and upper(app_name) = 'TAX' and INSTR(s.user_id, '.') > 0
group by user_id, app_name, OriginalSql = select max(ts) from abc.test s
where abc.getTest(s.user_id) = ?
and upper(app_name) = 'TAX' and INSTR(s.user_id, '.') > 0
group by user_id, app_name, Error Msg = ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:514)
... 109 more
<org.hibernate.engine.jdbc.spi.SqlExceptionHelper> <SqlExceptionHelper> <logExceptions> <SQL Error: 932, SQLState: 42000>
<org.hibernate.engine.jdbc.spi.SqlExceptionHelper> <SqlExceptionHelper> <logExceptions> <ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
>
I tried to convert the max(ts) to string using to_char and changed the coresponding getter/setter to String still getting the same issue.
Update:
I fixed it with this small change
String getLastLogin(#Param("userId") BigDecimal userId);
Didnt add #Param for the arguments.
That query return null value thats why that null values can not assign to number. We can not assign null to int(primitive) in java.

Need to convert a numeric field to date in this query

I am running this in sql server but there is an error on the date compare as the column cadodt is a numeric. Is there a quick and easy way to convert that col to numeric? It's date is in YYYYMMDD but I cannot compare against a date field like current date.
select * from openquery(IBSIBM, 'select CABANO, CABCRC, CABCTR, CABCUR, CABKCO, CACLVL, CACOTI,
CACRDT, CACTTP, CADODT, CADOTY, CAEXRT, CAIDNO, CAJONO, CANCRX,
CAPERI, CAREFX, CARSCD, CASCRC, CASCTR, CASTAT, CASTMT, CASYID,
CATIML, CATREF, CATTXT, CATYPC, CAUSER, CAVADT, CAVODT, CAVONO,
CAVOTY ,NANAME from CA1665AFCV.SROCBA,
CA1665AFCV.srolta,
CA1665AFCV.sronam
WHERE CADOTY = ''CHK'' and cajono=ctjono and cadodt = CURRENT DATE()
and caperi=ctperi and caidno=ctidno and ctveno=nanum
and CASTAT = ''Y''')
Assuming cadodt is actually an integer or numeric field and not a character string, try this:
select * from openquery(IBSIBM,
'select CABANO, CABCRC, CABCTR, CABCUR, CABKCO, CACLVL, CACOTI,
CACRDT, CACTTP, CADODT, CADOTY, CAEXRT, CAIDNO, CAJONO, CANCRX,
CAPERI, CAREFX, CARSCD, CASCRC, CASCTR, CASTAT, CASTMT, CASYID,
CATIML, CATREF, CATTXT, CATYPC, CAUSER, CAVADT, CAVODT, CAVONO,
CAVOTY, NANAME
from CA1665AFCV.SROCBA, CA1665AFCV.srolta, CA1665AFCV.sronam
WHERE CADOTY = ''CHK''
and cajono = ctjono
and cadodt = YEAR(CURRENT DATE) * 10000 + MONTH(CURRENT DATE) * 100 + DAY(CURRENT DATE)
and caperi = ctperi
and caidno = ctidno
and ctveno = nanum
and CASTAT = ''Y''')
Aside: I would strongly recommend against using comma joins. The longer ANSI 92 join syntax is much easier to read and maintain. I'd also strongly recommend using qualified column names. This schema is not the easiest to follow as it is. No need to make it even more arcane.
You have these options
convert cadodt from string to date
convert cadodt from intger to date
convert current date to YYYYMMDD string
convert current date to YYYYMMDD integer
1 and 3 assume cadodt is a string
2 and 4 assume cadodt is an intger
3 and 4 are the more efficient approaches as you only change one value.
e.g.
(3) if cadodt is a string in YYYMMDD format:
AND cadodt = VARCHAR_FORMAT(CURRENT DATE, 'YYYYMMDD')
(4) if cadodt is an integer representing YYYYMMDD
AND cadodt = YEAR(CURRENT DATE) * 10000 + MONTH(CURRENT DATE) * 100 + DAY(CURRENT DATE)
the CURRENT DATE() may be causing you some issues use CURRENT_DATE()
Try this:
select * from openquery(IBSIBM, 'select CABANO, CABCRC, CABCTR, CABCUR, CABKCO, CACLVL, CACOTI,
CACRDT, CACTTP, CADODT, CADOTY, CAEXRT, CAIDNO, CAJONO, CANCRX,
CAPERI, CAREFX, CARSCD, CASCRC, CASCTR, CASTAT, CASTMT, CASYID,
CATIML, CATREF, CATTXT, CATYPC, CAUSER, CAVADT, CAVODT, CAVONO,
CAVOTY ,NANAME from CA1665AFCV.SROCBA,
CA1665AFCV.srolta,
CA1665AFCV.sronam
WHERE CADOTY = ''CHK'' and cajono=ctjono and cadodt = CURRENT_DATE()
and caperi=ctperi and caidno=ctidno and ctveno=nanum
and CASTAT = ''Y''')
Replace CADODT = CURRENT DATE() with:
date(substr(char(CADODT), 1, 4) || '-'|| substr(char(CADODT),5, 2) || '-'|| substr(char(CADODT), 7, 2)) = CURRENT DATE
That should convert it from an integer to a date.

ORA-01847 day of month must be between 1 and last day of month - but data is OK

Problem is solved - see end of this post.
when i call to_date in select clause everything works fine - get a resultset of 12 records:
select value1,to_date(value1,'DD.MM.YYYY')
from variableindex
where
value1 is not null
and value1 <> '0'
and creation_time_ > to_timestamp('20140307','YYYYMMDD')
order by 2
returns
'VALUE1' 'TO_DATE(VALUE1,'DD.MM.YYYY')'
'25.11.2013' 25.11.13
'12.03.2014' 12.03.14
'12.03.2014' 12.03.14
'12.03.2014' 12.03.14
'12.03.2014' 12.03.14
'12.03.2014' 12.03.14
'14.03.2014' 14.03.14
'14.03.2014' 14.03.14
'14.03.2014' 14.03.14
'14.03.2014' 14.03.14
'20.03.2014' 20.03.14
'20.03.2014' 20.03.14
Every datestring has been converted as expected.
If i add the following line to where clause
and to_date(value1,'DD.MM.YYYY') < to_date('20140301','YYYYMMDD')
i'll receive:
ORA-01847: Tag des Monats muss zwischen 1 und letztem Tag des Monats liegen
01847. 00000 - "day of month must be between 1 and last day of month"
*Cause:
*Action:
No it really gets nasty... i changed my query to
where id_ in (...)
and used the same 12 recordsets ids as in original query. No Error...
Many thanks to #GordonLinoff - this is how i use the query now:
select value1,to_date(value1,'DD.MM.YYYY') from variableindex
where
(case when value1 <> '0' then to_date(value1,'DD.MM.YYYY') end) > to_timestamp('20131114','YYYYMMDD')
and creation_time_ > to_timestamp('20140307','YYYYMMDD')
order by 2;
This is your query with the where clause:
select value1, to_date(value1,'DD.MM.YYYY')
from variableindex
where value1 is not null and
value1 <> '0' and
creation_time_ > to_timestamp('20140307', 'YYYYMMDD') and
to_date(value1 'DD.MM.YYYY') < to_date('20140301', 'YYYYMMDD')
order by 2;
Oracle does not guarantee the order of processing of clauses in the where. So, value <> '0' is not guaranteed to run before the last condition. This happens to be a big problem on SQL Server. One solution is to use a case statement:
select value1,to_date(value1, 'DD.MM.YYYY')
from variableindex
where value1 is not null and
value1 <> '0' and
creation_time_ > to_timestamp('20140307', 'YYYYMMDD') and
(case when value <> '0' then to_date(value1, 'DD.MM.YYYY') end) <
to_date('20140301', 'YYYYMMDD')
order by 2;
Rather ugly, but it just might solve your problem.
If you're using OracleParameter in SQL with parameter name and value binding, check you set the oracleCommand.BindByName = true then it'll bind by name, and not by parameter adding order.
I just want to add that we got the same ORA-01847 error when the user's web browser language encoding was changed from English to Portuguese.
The line of code that failed was:
IF TO_DATE(NEW_DATE,'DD-MON-YYYY') = TO_DATE(OLD_DATE,'DD-MON-YYYY') THEN
Which was fixed by rewriting it to:
IF TO_CHAR(NEW_DATE,'DD-MON-YYYY') = TO_CHAR(OLD_DATE,'DD-MON-YYYY') THEN
It appears Oracle detected the change of language and assumed the date value will be formatted for the Portuguese locale.

DTP routine to find timestamp range

I am working on a DTP filter routine for a timestamp field in the format of YYYYMMDDhhmmss. I am trying to declare the range as ({timestamp 3 months ago} to {current timestamp}). I am very new to ABAP and basically have the code set up right now so it doesn't have any syntax errors. I am currently having trouble getting the correct timestamp to be filled when I assign it to "l_ts".
*$*$ begin of routine - insert your code only below this line *-*
BREAK-POINT.
DATA: l_idx LIKE sy-tabix,
l_ts TYPE rstimestmp,
l_ts2 TYPE rstimestmp.
READ TABLE l_t_range WITH KEY
fieldname = 'TIMESTAMP'.
l_idx = sy-tabix.
* Capture the Current Date
l_ts = sy-datlo + sy-timlo.
l_ts2 = ( sy-datlo + sy-timlo ) - 93.
IF l_idx <> 0.
* fill the Selection table.
l_t_range-low = l_ts.
l_t_range-sign = 'I'.
l_t_range-option = 'BT'.
l_t_range-high = l_ts2.
MODIFY l_t_range INDEX l_idx.
ELSE.
* fill the Selection table.
l_t_range-fieldname = 'TIMESTAMP'.
l_t_range-low = l_ts.
l_t_range-high = l_ts2.
l_t_range-sign = 'I'.
l_t_range-option = 'BT'.
APPEND l_t_range.
ENDIF.
p_subrc = 0.
*$*$ end of routine - insert your code only before this line *-*
You're mixing up timestamps and discrete date and time calculations - won't work this way. What you'll really want is probably something like this:
DATA: l_date TYPE d,
l_time TYPE t,
l_ts TYPE rstimestmp.
FIELD-SYMBOLS: <ls_param> LIKE LINE OF l_t_range.
* ensure that the parameter exists
READ TABLE l_t_range ASSIGNING <ls_param> WITH KEY fieldname = 'TIMESTAMP'.
IF sy-subrc <> 0.
APPEND INITIAL LINE TO l_t_range ASSIGNING <ls_param>.
<ls_param>-fieldname = 'TIMESTAMP'.
ENDIF.
<ls_param>-sign = 'I'.
<ls_param>-option = 'BT'.
* "from" date = three months ago, more or less - probably the start of the day?
l_date = sy-datlo - 93.
l_time = '000000'. " or sy-timlo.
CONVERT DATE l_date TIME l_time INTO TIME STAMP l_ts TIME ZONE sy-zonlo.
<ls_param>-low = l_ts.
* "to" date = today - probably the end of the day?
l_date = sy-datlo.
l_time = '235959'. " or sy-timlo.
CONVERT DATE l_date TIME l_time INTO TIME STAMP l_ts TIME ZONE sy-zonlo.
<ls_param>-high = l_ts.