Menu

DateTime column

Help
2011-12-14
2013-03-18
  • nenad cikic

    nenad cikic - 2011-12-14

    Sorry, again me.
    I have the need to use datetime column in database. I think i need timestamp in postgre. How should i define the dictionary?

    Nenad

     
  • nenad cikic

    nenad cikic - 2011-12-14

    I have found on clarion newsgroup the following:
    I have a table in each that includes the usual DateTime definition in
    the Clarion dct:
    DateTimeSTR  STRING(8)
    DateTimeGRP  GROUP,OVER(DateTimeSTR)
    DateField            DATE
    TimeField            TIME
    END

    I will try if it works in c2j.

     
  • Andrew Barnham

    Andrew Barnham - 2011-12-15

    Hi

    Currently timestamp using technique of OVER() is not supported.  In my coding, I define separate DATE and TIME postgres types.

    I've looked at source code for runtime.  I do not think that adding support for the way clarion does this will be difficult.  Let me know if you need this and I will take a look.

     
  • nenad cikic

    nenad cikic - 2011-12-15

    I would be very gratefull if you could this. This column is defined by specs as datetime. I have to finish this project in about 30 days. So there is no immediate rush. I will though ask the refeence person in the bank to ask if they could soften the specs.
    Thanks
    Nenad

     
  • nenad cikic

    nenad cikic - 2011-12-15

    I got a quick response from the bank. I can format the colum as yyyymmddhhmmss so there is no need for DATETIME:)

     
  • Andrew Barnham

    Andrew Barnham - 2011-12-16

    I've just added datetime support to c2j, as per how it is done in clarion; using string(8) and OVER() with a group containing a date and time. 

    Code is in runtime. I also added a test to compiler to ensure that datetime files actually compile and behave as expected when written as clarion code.  compiler changes also include something you pointed out to me some time ago.  CODE and DATA blocks are now more relaxed about whitespace preceeding them.

     
  • nenad cikic

    nenad cikic - 2011-12-17

    OK, thanks. CODE,DATA thing works.

    timetamp works as above. I have tried to add a row and the postgre column type and value is OK. When reading back the data is ok.

    What is not working is when i add the timestamp column in a key.
    For example:
    blagajnicke_transakcije FILE,DRIVER('ODBC'),OWNER('wmj'),NAME('blagajnicke_transakcije'),PRE(bt),CREATE,BINDABLE,THREAD
    KeyBT_datum_broj         KEY(bt:tec_tl_datum_tecajne_liste,bt:tec_tl_broj_tecajne_liste),NOCASE,OPT
    Record                   RECORD,PRE()
    serijski_broj               STRING(10)
    datum_i_vrijeme_transakcije STRING(8)
    datum_i_vrijeme_transkacijeG GROUP,OVER(datum_i_vrijeme_transakcije)
    datum                         DATE
    vrijeme                       TIME
                                END
    tec_tl_broj_tecajne_liste   LONG
    tec_tl_datum_tecajne_liste  DATE
                             END
                         END        

    If i add at the end of the key the field datum_i_vrijeme_transakcije c2j compiles but crashes at runtime.
    If i add at the end datum_i_vrijeme_transakcijeG or datum_i_vrijeme_transakcijeG.datum,datum_i_vrijeme_transakcijeG.vrijeme then c2j will not compile.

    Also if it was possible to add the datum_i_vrijeme_transakcije to the key, for the purpose of PREVIOUS command i have the need to do something as clear(datum_i_vrijeme_transakcije ,1). Would that work? Would work maybe
    clear(datum_i_vrijeme_transakcijeG.datum,1)
    clear(datum_i_vrijeme_transakcijeG.vrijeme,1)
    ?

    Now this is not strictly a showstopper, since i can duplicate the date,time columns just for the purpose of the key definition. Just wanted to point to the problem.

    I will submit one more report in the help forum, which is more important. I feel i am close to the end with bugs or feature requests since I have tried all the functionality I need and I will stick with this solution.

    Thanks
    Nenad

     
  • Andrew Barnham

    Andrew Barnham - 2011-12-17

    Putting a key on the string component (datum_i_vrijeme_transakcije) should work.  

    Make sure you remove NOCASE.  This will confuse c2j and cause SQL operations to not work on date key.

    Code in regression test works fine.

       program
    Franch               FILE,DRIVER('ODBC'),OWNER('c8'),NAME('testdate'),PRE(PSI),BINDABLE
    PrimaryKey               KEY(PSI:ID),NAME('pkey'),PRIMARY
    dateKEY                  KEY(PSI:timeStampField),DUP,NAME('datekey'),OPT
    Record                   RECORD,PRE()
    id                          LONG,NAME('id')
    timeStampField              string(8),NAME('timeStampField')
    timeStampGroup              group,over(timeStampField)
    date                        long
    time                        long
    .
                             END
                         END
       code
       create(franch)
       open(franch)
       assert(errorcode()=0,'#1')
                    
       psi:id=1
       psi:timeStampGroup.date=today()
       psi:timeStampGroup.time=clock()
       add(franch)
                    
       clear(franch)
       assert(psi:timeStampGroup.date=0,'#2')
       assert(psi:timeStampGroup.time=0,'#3')
       set(psi:dateKEY)
       next(franch)
       assert(psi:timeStampGroup.date=today(),'#4')
       assert(abs(psi:timeStampGroup.time-clock())<200,'#5')
       next(franch)
    
     
  • nenad cikic

    nenad cikic - 2011-12-19

    I have taken off the nocase and now i do not get any more runtime crashes. But it is behaving inconsistently .
    With blagajnicke_transakcije if i have the following situations defined then I can not add any row.

    Situation 1:Just one primary key with just bt:datum_i_vrijeme_transakcije
    Situation 2:Jst one primary key as
    KEY(bt:tec_tl_datum_tecajne_liste,bt:tec_tl_broj_tecajne_liste,bt:datum_i_vrijeme_transakcije),DUP,OPT,,PRIMARY
    Situation 3: Two keys
    KeyBT_datum_broj         KEY(bt:tec_tl_datum_tecajne_liste,bt:tec_tl_broj_tecajne_liste),NOCASE,OPT,PRIMARY
    KeyBT_datTrans           KEY(bt:tec_tl_datum_tecajne_liste,bt:tec_tl_broj_tecajne_liste,bt:datum_i_vrijeme_transakcije),DUP,OPT

    Only when i have the following keys I can add rows.
    KeyBT_datum_broj         KEY(bt:tec_tl_datum_tecajne_liste,bt:tec_tl_broj_tecajne_liste),NOCASE,OPT,PRIMARY
    KeyBT_datTrans           KEY(bt:datum_i_vrijeme_transakcije),DUP,OPT

    May I ask why you have NAME('datekey'), i.e. seems as you are forcing lowcase on keys but not on fields; for example NAME('timeStampField'). Is this necessary?

    Thanks
    Nenad

     
  • Andrew Barnham

    Andrew Barnham - 2011-12-19

    A couple of points:

    * postgres is case insensitive for labels. So NAME('datekey') and NAME('dateKey') are the same thing.  It is just what I happened to type when writing the code

    * Postgres index collation is locale specific, and generally upper and lower cases collate very close together. i.e. in postgres: i.e.
    SELECT 'a'<'b'  = true
    SELECT 'a'<'B'  = true

    Whereas clarion .DAT files would collate based on ascii code. So the above 'a'<'B' = false for DAT files.  The postgres method is far more powerful and useful, (but sometimes annoying if you need to anticipate collation order in application, I recently wrote some code that had to do this).  I find that notion of case insensitive keys for c2j + postgres is rarely useful.  Suggest remove NOCASE.  Only situation where it is required is if you wish to force constraints relating to case sensitivity.

    * OPT is currently not implemented in c2j.  I think this may case problems. If you have OPT set, but not DUP; you may be trying to manage multiple empty keys.  In such a situation, add DUP setting.  If you need OPT and DUP to work properly, let me know.  When I originally wrote SQL layer for c2j, I was unsure how to build in OPT+NODUP behaviour.   But now I know how to go about it.  But work involved is fiddly; I might not get to it until next week.
    In meantime there is a test you can try: manually modify your postgres index. For example consider an index I have on my system:
    "teststock_partkey_1" UNIQUE, btree (franchise, partnum)
    franchise = smallint, partnum=varchar

    Redefining the index thus will help (to make it non DUP and OPT):
    CREATE UNIQUE INDEX teststock_partkey_1 ON teststock (franchise,partnum) WHERE franchise>0 or partnum>'';

    Note that with above in place, performance of c2j indexes will be poor with the above until I make necessary changes. To work around this you may need to define two indexes, one that is essentially the constraint, and another which is for browsing/performance.
    CREATE UNIQUE INDEX teststock_partkey_constraint ON teststock (franchise,partnum) WHERE franchise>0 or partnum>'';
    CREATE INDEX teststock_partkey_constraint ON teststock (franchise,partnum);

     
  • nenad cikic

    nenad cikic - 2011-12-19

    I have managed to narrow down. I have the following debug code immediatelly after the "Initialising database" message in the main frame.

    !   clear(blagajnicke_transakcije)
    !   bt:tec_tl_datum_tecajne_liste=date(1,2,2014)
    !   bt:tec_tl_broj_tecajne_liste=1
    !   clear(bt:datum_i_vrijeme_transkacijeG.datum,1)
    !   clear(bt:datum_i_vrijeme_transkacijeG.vrijeme,1)
    !   set(bt:KeyBT_datum_broj_trans,bt:KeyBT_datum_broj_trans)
    !   loop
    !      previous(blagajnicke_transakcije)
    !      if errorcode() or (not bt:tec_tl_datum_tecajne_liste=date(1,2,2014)) or (not bt:tec_tl_broj_tecajne_liste=1)
    !         break
    !      end
    !      if jj=0
    !         jj=bt:tec_tl_broj_tecajne_liste
    !      end
    !      message(format(bt:datum_i_vrijeme_transkacijeG.datum,@d6) & ' ' & format(bt:datum_i_vrijeme_transkacijeG.vrijeme,@t4))
    !   end

       clear(blagajnicke_transakcije)
       bt:tec_tl_broj_tecajne_liste=1
       bt:tec_tl_datum_tecajne_liste=date(1,2,2014)
       bt:datum_i_vrijeme_transkacijeG.datum=today()
       bt:datum_i_vrijeme_transkacijeG.vrijeme=clock()
       add(blagajnicke_transakcije)
       if errorcode()
          message('error')
       end

    At init time the table is empty.
    If I put in any of the keys the datum_i_vrijeme_transakcije, and if i uncomment the commented bloc of above (previous(blagajnicke…) then the ADD fails, even if bt:KeyBT_datum_broj_trans does not contain the timestamp column.

    But if I comment the code, as i did above then i can put the timestamp column in the main primary key.
    Btw, i took away OPT on all keys.

    Does this make sense? Note that in your progression test you first add one row and then you get it back with NEXT.
    Nenad

     
  • Andrew Barnham

    Andrew Barnham - 2011-12-19

    Can you get log output using Debug().  It might be possible that the previous() is failing.  Unlikely, but not impossible.  I would like to rule it out.

    Also - on ADD() good to dump the exact error you are getting. I am expecting either duplicate key error or a transaction already aborted error. If latter, it implies that the previous fetch code is broken in some way.  Possibly table/index creation is somehow broken.

     
  • nenad cikic

    nenad cikic - 2011-12-20

    This is the file:
    blagajnicke_transakcije FILE,DRIVER('ODBC'),OWNER('wmj'),NAME('blagajnicke_transakcije'),PRE(bt),CREATE,BINDABLE,THREAD
    KeyBT_datum_broj         KEY(bt:tec_tl_datum_tecajne_liste,bt:tec_tl_broj_tecajne_liste,bt:datum_i_vrijeme_transakcije),PRIMARY
    Record                   RECORD,PRE()
    serijski_broj               STRING(10)
    datum_i_vrijeme_transakcije STRING(8)
    datum_i_vrijeme_transkacijeG GROUP,OVER(datum_i_vrijeme_transakcije)
    datum                         DATE
    vrijeme                       TIME
                                END
    tec_tl_broj_tecajne_liste   LONG
    tec_tl_datum_tecajne_liste  DATE
                             END
                         END 

    This is the code:
    compile('java-end',java)
       @java-dependency 'java.util.logging.Level'
       @java-dependency 'java.util.logging.Logger'
       @java-code 'Logger log = Logger.getLogger(Thiswindow.class.getName());'
       @java-code 'log.log(Level.WARNING,"Nenad1",thisWindow);'
    java-end

       clear(blagajnicke_transakcije)
       bt:tec_tl_datum_tecajne_liste=date(1,2,2014)
       bt:tec_tl_broj_tecajne_liste=1
       clear(bt:datum_i_vrijeme_transkacijeG.datum,1)
       clear(bt:datum_i_vrijeme_transkacijeG.vrijeme,1)
       set(bt:KeyBT_datum_broj,bt:KeyBT_datum_broj)
       loop
          previous(blagajnicke_transakcije)
          if errorcode() or (not bt:tec_tl_datum_tecajne_liste=date(1,2,2014)) or (not bt:tec_tl_broj_tecajne_liste=1)
             break
          end
          if jj=0
             jj=bt:tec_tl_broj_tecajne_liste
          end
          message(format(bt:datum_i_vrijeme_transkacijeG.datum,@d6) & ' ' & format(bt:datum_i_vrijeme_transkacijeG.vrijeme,@t4))
       end
      

       clear(blagajnicke_transakcije)
       bt:tec_tl_broj_tecajne_liste=1
       bt:tec_tl_datum_tecajne_liste=date(1,2,2014)
       bt:datum_i_vrijeme_transkacijeG.datum=today()
       bt:datum_i_vrijeme_transkacijeG.vrijeme=clock()
       add(blagajnicke_transakcije)
       if errorcode()
          message(error())

    compile('java-end',java)
       @java-code 'log.log(Level.WARNING,"Nenad:" + Clarion.newString(CError.error()),thisWindow);'
    java-end
       end
                                                      
    compile('java-end',java)
       @java-code 'log.log(Level.WARNING,"Nenad2",thisWindow);'
    java-end

    The code is being called after
      SETCURSOR(Cursor:Wait)
      OPEN(SQLOpenWindow)
      ACCEPT
        IF EVENT() = Event:Timer
      Relate:apoen.SetOpenRelated()
      Relate:apoen.Open                                        ! File blagajnicke_transakcije used by this procedure, so make sure it's RelationManager is open
      Relate:blagajnicke_transakcije.Open                      ! File blagajnicke_transakcije used by this procedure, so make sure it's RelationManager is open
      Relate:blagajnicko_mjesto.Open                           ! File blagajnicke_transakcije used by this procedure, so make sure it's RelationManager is open
      Relate:osoba.Open                                        ! File blagajnicke_transakcije used by this procedure, so make sure it's RelationManager is open
      Relate:vrsta_transakcije.Open                            ! File blagajnicke_transakcije used by this procedure, so make sure it's RelationManager is open
      Access:tecajna_lista.UseFile                             ! File referenced in 'Other Files' so need to inform it's FileManager
      Access:vrsta_mjenjackog_tecaja.UseFile                   ! File referenced in 'Other Files' so need to inform it's FileManager
      Access:valuta.UseFile                                    ! File referenced in 'Other Files' so need to inform it's FileManager
      Access:vrsta_cek.UseFile                                 ! File referenced in 'Other Files' so need to inform it's FileManager
      Access:gloparam.UseFile                                  ! File referenced in 'Other Files' so need to inform it's FileManager
      Access:platni_instrumenti.UseFile                        ! File referenced in 'Other Files' so need to inform it's FileManager
      Access:kodirani_tecajevi.UseFile                         ! File referenced in 'Other Files' so need to inform it's FileManager
      Access:provizija.UseFile                                 ! File referenced in 'Other Files' so need to inform it's FileManager
      Access:tecajevi.UseFile                                  ! File referenced in 'Other Files' so need to inform it's FileManager
      SELF.FilesOpened = True
          POST(EVENT:CloseWindow)
        END
      END
      CLOSE(SQLOpenWindow)
      SETCURSOR()

    and before opening the frame.

    This is finally the log:
    12/20 07:31:18 W Wmj001 - Nenad1
    12/20 07:31:18 F ClarionSQLFile - SELECT serijski_broj,datum_i_vrijeme_transakcije,tec_tl_broj_tecajne_liste,tec_tl_datum_tecajne_liste FROM blagajnicke_transakcije WHERE ((tec_tl_datum_tecajne_liste IS NULL OR tec_tl_datum_tecajne_liste<='2014-01-02') AND ((tec_tl_datum_tecajne_liste IS NULL OR tec_tl_datum_tecajne_liste<'2014-01-02') OR (tec_tl_broj_tecajne_liste<=1 AND (tec_tl_broj_tecajne_liste<1 OR (datum_i_vrijeme_transakcije<='1411-07-08 65:13:56'))))) ORDER BY tec_tl_datum_tecajne_liste DESC NULLS LAST,tec_tl_broj_tecajne_liste DESC,datum_i_vrijeme_transakcije DESC NULLS LAST []
    12/20 07:31:18 W ClarionSQLFile - SQLException : ERROR: date/time field value out of range: "1411-07-08 65:13:56"
      Position: 404 22008
    org.postgresql.util.PSQLException: ERROR: date/time field value out of range: "1411-07-08 65:13:56"
      Position: 404
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:271)
    at org.jclarion.clarion.ClarionSQLFile.iterate(ClarionSQLFile.java:531)
    at org.jclarion.clarion.ClarionSQLFile.previous(ClarionSQLFile.java:420)
    at clarion.Wmj001.main_SetDef(Wmj001.java:174)
    at clarion.Thiswindow.init_SetDef(Thiswindow.java:102)
    at clarion.Thiswindow.init(Thiswindow.java:89)
    at clarion.Windowmanager.run(Windowmanager.java:489)
    at clarion.Wmj001.main(Wmj001.java:50)
    at clarion.Main.begin(Main.java:347)
    at clarion.Main.main(Main.java:331)
    12/20 07:31:18 F ClarionSQLFile - INSERT INTO blagajnicke_transakcije (serijski_broj,datum_i_vrijeme_transakcije,tec_tl_broj_tecajne_liste,tec_tl_datum_tecajne_liste) VALUES ('','2011-12-20 07:31:18',1,'2014-01-02') []
    12/20 07:31:18 W ClarionSQLFile - SQLException : ERROR: current transaction is aborted, commands ignored until end of transaction block 25P02
    org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:353)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:345)
    at org.jclarion.clarion.ClarionSQLFile.add(ClarionSQLFile.java:118)
    at clarion.Wmj001.main_SetDef(Wmj001.java:188)
    at clarion.Thiswindow.init_SetDef(Thiswindow.java:102)
    at clarion.Thiswindow.init(Thiswindow.java:89)
    at clarion.Windowmanager.run(Windowmanager.java:489)
    at clarion.Wmj001.main(Wmj001.java:50)
    at clarion.Main.begin(Main.java:347)
    at clarion.Main.main(Main.java:331)
    12/20 07:31:18 F runtime.CWinImpl - Target is null on thread:Thread
    12/20 07:31:24 W Wmj001 - Nenad:ERROR: current transaction is aborted, commands ignored until end of transaction block
    12/20 07:31:24 W Wmj001 - Nenad2

     
  • Andrew Barnham

    Andrew Barnham - 2011-12-20

    Ah.   The following lines are problematic.

       clear(bt:datum_i_vrijeme_transkacijeG.datum,1) 
       clear(bt:datum_i_vrijeme_transkacijeG.vrijeme,1) 
       set(bt:KeyBT_datum_broj,bt:KeyBT_datum_broj)
       loop 
         previous(blagajnicke_transakcije)
    

    The above code sets date and time to their maximum possible value and then scans backwards from there. 

    Problem is that what clarion code considers maximum allowed date/time, and how it renders required SQL.  I need to do some work here.

    Suggest following alternative code:

       set(bt:KeyBT_datum_broj)
       loop 
         previous(blagajnicke_transakcije)
    

    Details of the problem.  Relates to clear(1) and set(key,key)

    Date field first.  clear(1) sets it to 2^31-1 days since 28th Dec 1800.  Or 5881411-07-08. Currently c2j trims this to 4 year date or : 1411-07-08.  This is a bug, c2j should represent this correctly.

    For time:  again clear(1) sets it to 2^31-1.  Which c2j treats as (2^31-2)/100 seconds since midnight. Or
    5965:13:56;  again c2j trims numbers; so it becomes 65:13:56.

    I will fix these shortly. So that clear() when performed  on a DATE or TIME variable, set limits as you would expect.

     
  • Andrew Barnham

    Andrew Barnham - 2011-12-20

    Committed a fix so that clear(1) on sets correct values. Cross checked these against a compiled clarion 6 program.

     
  • nenad cikic

    nenad cikic - 2011-12-21

    It is OK now.
    Thanks
    Nenad

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.