Table Data Records

Osborne

Active Member
The error means one of your handle variables has not been created or set:

An invalid object handle has been encountered. This typically occurs when querying or setting an object attribute when the handle for it is still the unknown value(?).

If I had to guess it looks to be fh as you are referencing it but cannot see where it is being assigned/created:

Code:
hTemp:ADD-LIKE-FIELD(fh:NAME,fh).
...
ASSIGN fh = bh:BUFFER-FIELD( _field._field-name )
             vBufferValue = fh:BUFFER-VALUE() NO-ERROR.
 
The error means one of your handle variables has not been created or set:



If I had to guess it looks to be fh as you are referencing it but cannot see where it is being assigned/created:

Code:
hTemp:ADD-LIKE-FIELD(fh:NAME,fh).
...
ASSIGN fh = bh:BUFFER-FIELD( _field._field-name )
             vBufferValue = fh:BUFFER-VALUE() NO-ERROR.
Yes I have resolved this but JSON produced by this code is also having only last Index field (same like my code). Seems the same issue that Stefan mentioned above, creating dynamic temp-table inside for each causing memory leak. :- CREATE TEMP-TABLE hTemp.
 

Osborne

Active Member
I am really not sure on this. It may be possible you want something like this:
Code:
/* Firstly create a dynamic temp-table for all the required fields */
CREATE TEMP-TABLE hTemp.
/* Add all the fields */
FOR FIRST _file NO-LOCK
    WHERE _file._file-name = "test"
    ,FIRST _index OF _file NO-LOCK
     WHERE _unique = TRUE
    ,EACH _index-field OF _index NO-LOCK
  ,FIRST _field OF _index-field NO-LOCK:  
   fld = _field._field-name.
   hTemp:ADD-LIKE-FIELD(fld,_file._file-name + "." + fld).
   /* Record all the fields in a variable to avoid the later reading of FOR FIRST _file */
END.
/* Complete the dynamic temp-table */
hTemp:TEMP-TABLE-PREPARE("ttDelete").
hDefault = hTemp:DEFAULT-BUFFER-HANDLE.

/* Create a Dynamic Query for the database records */
CREATE buffer bh for table vTable.
CREATE QUERY qh.
qh:SET-BUFFERS(bh).
qh:QUERY-PREPARE( "for each " + vTable + " no-lock" ).
qh:QUERY-OPEN().
qh:GET-FIRST().
DO WHILE NOT qh:QUERY-OFF-END:
   /* Create a dynamic temp-table record for each database record */
   /* Two possible options - not sure which one you require */

   /* Option 1 */
   hDefault:BUFFER-CREATE().
   FOR FIRST _file NO-LOCK
       WHERE _file._file-name = "test"
       ,FIRST _index OF _file NO-LOCK
        WHERE _unique = TRUE
       ,EACH _index-field OF _index NO-LOCK
     ,FIRST _field OF _index-field NO-LOCK:
      ASSIGN fh = bh:BUFFER-FIELD( _field._field-name )
             vBufferValue = fh:BUFFER-VALUE() NO-ERROR.
      hDefault:BUFFER-FIELD(_field._field-name):BUFFER-VALUE = vBufferValue.
   END.
   hDefault:BUFFER-RELEASE().

   /* Option 2
   FOR FIRST _file NO-LOCK
       WHERE _file._file-name = "test"
       ,FIRST _index OF _file NO-LOCK
        WHERE _unique = TRUE
       ,EACH _index-field OF _index NO-LOCK
     ,FIRST _field OF _index-field NO-LOCK:
      ASSIGN fh = bh:BUFFER-FIELD( _field._field-name )
             vBufferValue = fh:BUFFER-VALUE() NO-ERROR.
      hDefault:BUFFER-CREATE().
      hDefault:BUFFER-FIELD(_field._field-name):BUFFER-VALUE = vBufferValue.
      hDefault:BUFFER-RELEASE().
   END.
   */
   qh:GET-NEXT().
END.
qh:QUERY-CLOSE().

/* All database records read so now write to the JSON file */
ASSIGN
   vTargetType = "file"
   vFile       = _vTable + "_ttDelete.json"
   lformatted  = TRUE
   lretok      = hTemp:WRITE-JSON(vTargetType, vFIle, lformatted).

/* Finished with dynamic objects so clean up so that we don't produce a memory leak */
DELETE OBJECT qh.
DELETE OBJECT bh.
DELETE OBJECT hTemp.
ASSIGN qh = ?
       bh = ?
       hTemp = ?.
 
I am really not sure on this. It may be possible you want something like this:
Code:
/* Firstly create a dynamic temp-table for all the required fields */
CREATE TEMP-TABLE hTemp.
/* Add all the fields */
FOR FIRST _file NO-LOCK
    WHERE _file._file-name = "test"
    ,FIRST _index OF _file NO-LOCK
     WHERE _unique = TRUE
    ,EACH _index-field OF _index NO-LOCK
  ,FIRST _field OF _index-field NO-LOCK: 
   fld = _field._field-name.
   hTemp:ADD-LIKE-FIELD(fld,_file._file-name + "." + fld).
   /* Record all the fields in a variable to avoid the later reading of FOR FIRST _file */
END.
/* Complete the dynamic temp-table */
hTemp:TEMP-TABLE-PREPARE("ttDelete").
hDefault = hTemp:DEFAULT-BUFFER-HANDLE.

/* Create a Dynamic Query for the database records */
CREATE buffer bh for table vTable.
CREATE QUERY qh.
qh:SET-BUFFERS(bh).
qh:QUERY-PREPARE( "for each " + vTable + " no-lock" ).
qh:QUERY-OPEN().
qh:GET-FIRST().
DO WHILE NOT qh:QUERY-OFF-END:
   /* Create a dynamic temp-table record for each database record */
   /* Two possible options - not sure which one you require */

   /* Option 1 */
   hDefault:BUFFER-CREATE().
   FOR FIRST _file NO-LOCK
       WHERE _file._file-name = "test"
       ,FIRST _index OF _file NO-LOCK
        WHERE _unique = TRUE
       ,EACH _index-field OF _index NO-LOCK
     ,FIRST _field OF _index-field NO-LOCK:
      ASSIGN fh = bh:BUFFER-FIELD( _field._field-name )
             vBufferValue = fh:BUFFER-VALUE() NO-ERROR.
      hDefault:BUFFER-FIELD(_field._field-name):BUFFER-VALUE = vBufferValue.
   END.
   hDefault:BUFFER-RELEASE().

   /* Option 2
   FOR FIRST _file NO-LOCK
       WHERE _file._file-name = "test"
       ,FIRST _index OF _file NO-LOCK
        WHERE _unique = TRUE
       ,EACH _index-field OF _index NO-LOCK
     ,FIRST _field OF _index-field NO-LOCK:
      ASSIGN fh = bh:BUFFER-FIELD( _field._field-name )
             vBufferValue = fh:BUFFER-VALUE() NO-ERROR.
      hDefault:BUFFER-CREATE().
      hDefault:BUFFER-FIELD(_field._field-name):BUFFER-VALUE = vBufferValue.
      hDefault:BUFFER-RELEASE().
   END.
   */
   qh:GET-NEXT().
END.
qh:QUERY-CLOSE().

/* All database records read so now write to the JSON file */
ASSIGN
   vTargetType = "file"
   vFile       = _vTable + "_ttDelete.json"
   lformatted  = TRUE
   lretok      = hTemp:WRITE-JSON(vTargetType, vFIle, lformatted).

/* Finished with dynamic objects so clean up so that we don't produce a memory leak */
DELETE OBJECT qh.
DELETE OBJECT bh.
DELETE OBJECT hTemp.
ASSIGN qh = ?
       bh = ?
       hTemp = ?.
Hi Osborne, sorry couldn't share my requirement well but this is exactly what I required. Thanks again for your time and continues help. :)
 

Stefan

Well-Known Member
Have a class based example as a starting point:


Code:
def var odelete as delete no-undo.
def var lcjson  as longchar no-undo.

odelete = new delete( 'order' ).

odelete:populate().
lcjson = odelete:write().

message string( substring( lcjson, 1, 30000 ) ).

delete.cls:
Code:
class delete:

def var p_ht    as handle no-undo.
def var p_hb    as handle no-undo.

constructor delete ( i_ctable as char ):

    create buffer p_hb for table i_ctable.

    create temp-table p_ht.

    for _file
        where _file._file-name = i_ctable
    no-lock,
    first _index 
        where _index._file-recid = recid( _file )
        and   _index._unique = true
    no-lock,
    each _index-field
        where _index-field._index-recid = recid( _index )
    no-lock,
    _field
        where recid( _field ) = _index-field._field-recid
    no-lock:

        p_ht:add-like-field(
            _field._field-name,
            p_hb:buffer-field( _field._field-name )
        ).

    end.

    p_ht:temp-table-prepare( i_ctable ).

end constructor.

method void populate ():

    def var hq as handle no-undo.
    def var hb as handle no-undo.

    create buffer hb for table p_ht.

    create query hq.
    hq:add-buffer( p_hb ).
    hq:query-prepare( substitute( 'for each &1', p_hb:name ) ).
    hq:query-open().
    do while hq:get-next():

        hb:buffer-create().
        hb:buffer-copy( p_hb ).
        
    end.

    finally:
        delete object hb no-error.
        delete object hq no-error.
    end finally.    

end method.

method longchar write ():

    def var lcc as longchar no-undo.

    p_ht:write-json(
        'longchar',
          lcc,
          true      
    ).

    return lcc.

end method.

destructor delete ():

    delete object p_ht no-error.
    delete object p_hb no-error.

end destructor.

end class.
 
Top