Data Queues

XMLSERVICE.DataQueues History

Hide minor edits - Show changes to output

Added lines 6-11:


!!! THIS PAGE IS COMPLETELY OUT OF DATE (WRONG)
* please see Tony Cairns examples [[XMLSERVICE/TonyXMLServiceGemSamples]]

! do not use
Changed lines 8-9 from:
XMLService does not directly provide data queue support. But what XMLService makes it easy to call any IBMi command or program. To work with data queues all you need is the CRTDTAQ and DLTDTAQ commands and the QSNDDTAQ and QRCVDTAQ programs. The following creates a data queue:
to:
XMLService does not directly provide data queue support. Nevertheless, because XMLService makes it easy to call any IBMi command or program, you can easily work with data queues with the CRTDTAQ and DLTDTAQ commands and the QSNDDTAQ and QRCVDTAQ programs. The following creates a data queue:
Changed lines 71-79 from:
  DQ_COL_NAMES = ["FIRST", "LAST", "STREET", "CITY", "STATE", "ZIP"]
  DQ_COL_HASH = Hash[DQ_COL_NAMES.map.with_index.to_a]
  dq_array = Array.new(DQ_COL_HASH.size, ' ')
  dq_array[DQ_COL_HASH['FIRST']] = 'Don'
  dq_array[DQ_COL_HASH['LAST']] = 'Denoncourt'
  dq_array[DQ_COL_HASH['STREET']] = '11203 Pinewood Ct.'
  dq_array[DQ_COL_HASH['CITY']] = 'Richmond'
  dq_array[DQ_COL_HASH['STATE']] = 'VA'
  dq_array[DQ_COL_HASH['ZIP']] = '23238'
to:
  DQ_FIELD_NAMES = ["FIRST", "LAST", "STREET", "CITY", "STATE", "ZIP"]
  DQ_FIELDS = Hash[DQ_FIELD_NAMES.map.with_index.to_a]
  dq_array = Array.new(DQ_FIELDS.size, ' ')
  dq_array[DQ_FIELDS['FIRST']] = 'Don'
  dq_array[DQ_FIELDS['LAST']] = 'Denoncourt'
  dq_array[DQ_FIELDS['STREET']] = '11203 Pinewood Ct.'
  dq_array[DQ_FIELDS['CITY']] = 'Richmond'
  dq_array[DQ_FIELDS['STATE']] = 'VA'
  dq_array[DQ_FIELDS['ZIP']] = '23238'
Changed lines 89-91 from:
  DQ_COL_NAMES = ["FIRST", "LAST", "STREET", "CITY", "STATE", "ZIP"]
  DQ_COL_HASH = Hash[DQ_COL_NAMES.map.with_index.to_a]
  # dq_entry would be read from a data queue
to:
  DQ_FIELD_NAMES = ["FIRST", "LAST", "STREET", "CITY", "STATE", "ZIP"]
  DQ_FIELDS = Hash[DQ_FIELD_NAMES.map.with_index.to_a]
  # the dq_entry string would have been set from data queue read
Changed line 94 from:
  puts "Last name specifically from data queue: "+dq_array[DQ_COL_HASH['LAST']]
to:
  puts "Last name specifically from data queue: "+dq_array[DQ_FIELDS['LAST']]
Changed lines 57-58 from:
The Array class's pack method turns all the elements of an array into a string following the format passed to the pack method. For example, the following takes an array of integers and then "packs" them into a string using 10 bytes lengths:
to:
The Array class's pack method turns all the elements of an array into a string following the format passed to the pack method. For example, the following takes an array with my name and address and "packs" the elements into a string using lengths specified in the argument to the pack method:
Changed line 56 from:
Data queue entries on the IBMi usually contained information that is in a fixed format. Typically an RPG dataqueue processing program uses an existing record format when reading or writing entries. To format and parse data queue entries in your Ruby code the most straightforward solution is to use the pack and unpack methods of the Array and String classes respectively.
to:
Data queue entries on the IBMi usually contain information that is in a fixed format. Typically an RPG data queue processing program uses an existing record format when reading or writing entries. To format and parse data queue entries in your Ruby code the most straightforward solution is to use the pack and unpack methods of the Array and String classes respectively.
Changed line 95 from:
  puts "Now just dump the whole array"
to:
  puts "Now just dump the whole array:"
Changed lines 102-106 from:
=> nil
>>  puts "Now just dump the whole
array"
Now just dump the whole array
=> nil
>>  puts dq_array
to:
Now just dump the whole array:
Deleted line 108:
=> nil
Changed lines 73-80 from:
  dq_entry = Array.new(DQ_COL_HASH.size, ' ')
  dq_entry[DQ_COL_HASH['FIRST']] = 'Don'
  dq_entry[DQ_COL_HASH['LAST']] = 'Denoncourt'
  dq_entry[DQ_COL_HASH['STREET']] = '11203 Pinewood Ct.'
  dq_entry[DQ_COL_HASH['CITY']] = 'Richmond'
  dq_entry[DQ_COL_HASH['STATE']] = 'VA'
  dq_entry[DQ_COL_HASH['ZIP']] = '23238'
  dq_entry.pack(DQ_FORMAT)
to:
  dq_array = Array.new(DQ_COL_HASH.size, ' ')
  dq_array[DQ_COL_HASH['FIRST']] = 'Don'
  dq_array[DQ_COL_HASH['LAST']] = 'Denoncourt'
  dq_array[DQ_COL_HASH['STREET']] = '11203 Pinewood Ct.'
  dq_array[DQ_COL_HASH['CITY']] = 'Richmond'
  dq_array[DQ_COL_HASH['STATE']] = 'VA'
  dq_array[DQ_COL_HASH['ZIP']] = '23238'
  dq_entry = dq_array.pack(DQ_FORMAT)
Added lines 83-116:
The dq_entry string can then be pushed to a data queue with a call to QSNDDTAQ.

But to then read an entry retrieved from a data queue you would use the following:

[@
  DQ_FORMAT = 'A5A15A20A10A2A9'
  DQ_COL_NAMES = ["FIRST", "LAST", "STREET", "CITY", "STATE", "ZIP"]
  DQ_COL_HASH = Hash[DQ_COL_NAMES.map.with_index.to_a]
  # dq_entry would be read from a data queue
  dq_entry = "Don  Denoncourt    11203 Pinewood Ct.  Richmond  VA23238    "
  dq_array = dq_entry.unpack(DQ_FORMAT)
  puts "Last name specifically from data queue: "+dq_array[DQ_COL_HASH['LAST']]
  puts "Now just dump the whole array"
  puts dq_array
@]

Which outputs:
[@
Last name specifically from data queue: Denoncourt
=> nil
>>  puts "Now just dump the whole array"
Now just dump the whole array
=> nil
>>  puts dq_array
Don
Denoncourt
11203 Pinewood Ct.
Richmond
VA
23238
=> nil
@]

Changed line 118 from:
[[https://github.com/ryanwood/slither | Slither: A Dsl for Parsing Fixed Width Text Files]]
to:
[[https://github.com/ryanwood/slither | Slither: A Dsl for Parsing Fixed Width Text Files]]
Changed lines 83-84 from:
Note that there are string parser and formatter utilities available such as [[https://github.com/ryanwood/slither |
Slither: A Dsl for Parsing Fixed Width Text Files]]
to:
Note that there are string parser and formatter utilities available such as
[[https://github.com/ryanwood/slither | Slither: A Dsl for Parsing Fixed Width Text Files]]
Changed line 83 from:
Note that there are string parser and formatter utilities available such as [[https://github.com/ryanwood/slither | https://github.com/ryanwood/slither
to:
Note that there are string parser and formatter utilities available such as [[https://github.com/ryanwood/slither |
Changed lines 65-84 from:
@]
to:
@]

If you'd like to use field names that match what is in the RPG data queue processing program,  a simple strategy is to map field names to array entries is to use a parallel array with a hash to references values:

[@
  DQ_FORMAT = 'A5A15A20A10A2A9'
  DQ_COL_NAMES = ["FIRST", "LAST", "STREET", "CITY", "STATE", "ZIP"]
  DQ_COL_HASH = Hash[DQ_COL_NAMES.map.with_index.to_a]
  dq_entry = Array.new(DQ_COL_HASH.size, ' ')
  dq_entry[DQ_COL_HASH['FIRST']] = 'Don'
  dq_entry[DQ_COL_HASH['LAST']] = 'Denoncourt'
  dq_entry[DQ_COL_HASH['STREET']] = '11203 Pinewood Ct.'
  dq_entry[DQ_COL_HASH['CITY']] = 'Richmond'
  dq_entry[DQ_COL_HASH['STATE']] = 'VA'
  dq_entry[DQ_COL_HASH['ZIP']] = '23238'
  dq_entry.pack(DQ_FORMAT)
@]

Note that there are string parser and formatter utilities available such as [[https://github.com/ryanwood/slither | https://github.com/ryanwood/slither
Slither: A Dsl for Parsing Fixed Width Text Files]
]
Changed line 64 from:
=> "Don  Denoncourt    11203 Pinewood Ct.  Richmond  VA23238    "
to:
"Don  Denoncourt    11203 Pinewood Ct.  Richmond  VA23238    "
Changed line 60 from:
[1,2,3].collect {|x| x.to_s}.pack("A10A10A10")
to:
['Don', 'Denoncourt', '11203 Pinewood Ct.', 'Richmond', 'VA', '23238'].pack('A5A15A20A10A2A9')
Changed lines 64-65 from:
=> "1        2         3        "
to:
=> "Don  Denoncourt    11203 Pinewood Ct.  Richmond  VA23238    "
Added lines 59-66:
[@
[1,2,3].collect {|x| x.to_s}.pack("A10A10A10")
@]
produces:
[@
=> "1        2        3        "

@]
Changed lines 53-58 from:
!!Parsing and Formatting data queue entries
to:

!!Parsing and Formatting data queue entries

Data queue entries on the IBMi usually contained information that is in a fixed format. Typically an RPG dataqueue processing program uses an existing record format when reading or writing entries. To format and parse data queue entries in your Ruby code the most straightforward solution is to use the pack and unpack methods of the Array and String classes respectively.
The Array class's pack method turns all the elements of an array into a string following the format passed to the pack method. For example, the following takes an array of integers and then "packs" them into a string using 10 bytes lengths:

Changed lines 50-52 from:
For detailed information on the QSNDDTAQ and QRCVDTAQ programs see IBM's information  \\
[[http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Fapis%2Fqsnddtaq.htm | Send Data Queue program detail]]
and \\
to:
For detailed information on the QSNDDTAQ and QRCVDTAQ programs see IBM's documentation:  \\
[[http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Fapis%2Fqsnddtaq.htm | Send Data Queue program detail]] \\
Changed line 50 from:
For detailed information on the QSNDDTAQ and QRCVDTAQ programs see IBM's information
to:
For detailed information on the QSNDDTAQ and QRCVDTAQ programs see IBM's information  \\
Added line 52:
and \\
Added line 52:
[[http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/apis/qrcvdtaq.htm?resultof=%22%51%52%43%56%44%54%41%51%22%20%22%71%72%63%76%64%74%61%71%22%20 | Receive Data Queue program detail]]
Changed lines 50-51 from:
to:
For detailed information on the QSNDDTAQ and QRCVDTAQ programs see IBM's information
[[http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Fapis%2Fqsnddtaq.htm | Send Data Queue program detail]]
Changed lines 40-41 from:
                     XMLService::I_a.new('dataOutput', 100, 'replace stuff here') <<
                    XMLService::I_p.new('waitTime', 5, 0, 20.0)
to:
                      XMLService::I_a.new('dataOutput', 100, 'replace stuff here') <<
                     XMLService::I_p.new('waitTime', 5, 0, 20.0)
Changed line 26 from:
                       XMLService::I_a.new('dataInput', 100, 'test data for queue')
to:
                       XMLService::I_a.new('dataInput', 100, 'test data from Ruby for queue')
Deleted line 30:
Deleted lines 47-48:

Changed lines 34-35 from:

to:
And now the following will retrieve the data queue entry just added above:

[@
    qrcvdtaq = XMLService::I_PGM.new("QRCVDTAQ") <<
                      XMLService::I_a.new('queueName',10, 'TESTDTAQ') <<
                      XMLService::I_a.new('libName',10, 'QGPL') <<
                      XMLService::I_p.new('lenData', 5, 0, 100.0) <<
                    XMLService::I_a.new('dataOutput', 100, 'replace stuff here') <<
                    XMLService::I_p.new('waitTime', 5, 0, 20.0)
    qrcvdtaq.xmlservice
    if qrcvdtaq.xmlservice_error
      puts qrcvdtaq.dump_all
    else
      response = qrcvdtaq.xml_PARM3.xml_dataOutput.to_s
    end


@]


Changed lines 22-28 from:
   qsnddtaq = XMLService::I_PGM.new("QSNDDTAQ")
    qsnddtaq << XMLService::I_a.new('queueName',10,'TESTDTAQ')
    qsnddtaq << XMLService::I_a.new('libName',10,'QGPL')
    qsnddtaq << XMLService::I_p.new('lenData',5,0,9103.0)
    qsnddtaq << XMLService::I_a.new('dataInput',100, 'test data for queue')
    qsnddtaq << XMLService::I_p.new('keyLength',3,0, 1.0)
    qsnddtaq << XMLService::I_a.new('keyData',1, ' ')
to:
   qsnddtaq = XMLService::I_PGM.new("QSNDDTAQ", 'QSYS') <<
                       XMLService::I_a.new('queueName', 10, 'TESTDTAQ') <<
                      XMLService::I_a.new('libName', 10, 'QGPL') <<
                     XMLService::I_p.new('lenData', 5 , 0, 100.0) <<
                      XMLService::I_a.new('dataInput', 100, 'test data for queue
')
Changed lines 28-31 from:
to:
   if qsnddtaq.xmlservice_error
      puts qsnddtaq.dump_all
    end

Changed lines 8-9 from:
XMLService does not directly provide data queue support. But what XMLService makes it easy to call any IBMi command or program. To work with data queues all you need is the CRTDTAQ and DLTDTAQ commands and the QSNDDTAQ and QRCVDTAQ programs. The following creates and then deletes a data queue:
to:
XMLService does not directly provide data queue support. But what XMLService makes it easy to call any IBMi command or program. To work with data queues all you need is the CRTDTAQ and DLTDTAQ commands and the QSNDDTAQ and QRCVDTAQ programs. The following creates a data queue:
Deleted line 16:
   XMLService::I_CMD.new("DLTDTAQ DTAQ(QGPL/TESTDTAQ)").xmlservice
Added lines 19-34:
The following puts an entry on the data queue by calling QSNDDTAQ:

[@
    qsnddtaq = XMLService::I_PGM.new("QSNDDTAQ")
    qsnddtaq << XMLService::I_a.new('queueName',10,'TESTDTAQ')
    qsnddtaq << XMLService::I_a.new('libName',10,'QGPL')
    qsnddtaq << XMLService::I_p.new('lenData',5,0,9103.0)
    qsnddtaq << XMLService::I_a.new('dataInput',100, 'test data for queue')
    qsnddtaq << XMLService::I_p.new('keyLength',3,0, 1.0)
    qsnddtaq << XMLService::I_a.new('keyData',1, ' ')
    qsnddtaq.xmlservice

@]


Changed lines 8-19 from:
to:
XMLService does not directly provide data queue support. But what XMLService makes it easy to call any IBMi command or program. To work with data queues all you need is the CRTDTAQ and DLTDTAQ commands and the QSNDDTAQ and QRCVDTAQ programs. The following creates and then deletes a data queue:

[@
    ActiveXMLService::Base.establish_connection connection: 'ActiveRecord'
    crtq = XMLService::I_CMD.new("CRTDTAQ DTAQ(QGPL/TESTDTAQ) MAXLEN(100)")
    crtq.xmlservice
    if crtq.xmlservice_error
      puts crtq.dump
    end
    XMLService::I_CMD.new("DLTDTAQ DTAQ(QGPL/TESTDTAQ)").xmlservice
@]

Added lines 6-9:

!!The Basics

!!Parsing and Formatting data queue entries
Added lines 1-5:
(:quicktoc:)
>>round frame bgcolor=#ffffdd<<
!!! Ruby Toolkit Don: Reading and Writing to Data Queues
[[XMLSERVICERubyDonWork]]
>><<