XMLSERVICE Ruby Chat Work

[adc@oc7083008330 git]$ cd xmlservice/
[adc@oc7083008330 xmlservice]$ ls
ftpcompile.sh  lib  LICENSE  Rakefile  README_IBM_i  test  version.txt  xmlservice-1.3.0.gem  xmlservice-1.3.0.gemspec  zzall.sh
[adc@oc7083008330 xmlservice]$ cat version.txt 
1.3.0 GA3
[adc@oc7083008330 xmlservice]$ e version.txt &
[1] 6892
[adc@oc7083008330 xmlservice]$ git add .
[1]+  Done                    e version.txt
[adc@oc7083008330 xmlservice]$ git commit -m 'testing git'
[master 43e3405] testing git
 1 files changed, 1 insertions(+), 1 deletions(-)
[adc@oc7083008330 xmlservice]$ git push origin​ master
fatal: 'origin​' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
[adc@oc7083008330 xmlservice]$ git push
tcairns@kalypso.sealinc.org's password: 
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 264 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To ssh://tcairns@kalypso.sealinc.org/scm/xmlservice.git
   18a322b..43e3405  master -> master
[adc@oc7083008330 xmlservice]$ 

[adc@oc7083008330 ibm_db]$ git push
tcairns@kalypso.sealinc.org's password: 
To ssh://tcairns@kalypso.sealinc.org/scm/ibm_db
 ! [rejected]        ibm -> ibm (non-fast-forward)
error: failed to push some refs to 'ssh://tcairns@kalypso.sealinc.org/scm/ibm_db'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.
[adc@oc7083008330 ibm_db]$ 
[adc@oc7083008330 ibm_db]$ cat version.txt 
2.5.14 GA03-test3
[adc@oc7083008330 ibm_db]$ cat version.txt 
2.5.14 GA03-test4
[adc@oc7083008330 ibm_db]$ git checkout version.txt 
[adc@oc7083008330 ibm_db]$ cat version.txt 
2.5.14 GA03-test3
[adc@oc7083008330 ibm_db]$ 
      def select(sql, name = nil, binds = [])
        # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
        sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )

        results = []
        cols = []

        if(binds.nil? || binds.empty?)
          stmt = execute(sql, name)
        else
          stmt = exec_query(sql, name, binds)
        end

        if( stmt ) 
          cols = IBM_DB.resultCols(stmt)
          results = fetch_data(stmt)
        end

        if(@isAr3)
          return results
        else
          return ActiveRecord::Result.new(cols, results)
        end
      end




_ruby_ibm_db_SQLCreateDB_GIL_release

int _ruby_ibm_db_SQLCreateDB_helper(create_drop_db_args *data) {
  int rc = 0;
  if (_ruby_ibm_db_SQLCreateDB_GIL_release)
  rc = rb_thread_blocking_region( (void *)_ruby_ibm_db_SQLCreateDB_helper2, data,
                         (void *)_ruby_ibm_db_Connection_level_UBF, NULL);
  else
  rc = forget_blocking_region( (void *)_ruby_ibm_db_SQLCreateDB_helper2, data,
                         (void *)_ruby_ibm_db_Connection_level_UBF, NULL);
  return rc;
}

For DB2 Connect with IBM i, we need customers to follow our best practices, which have a highly optimized setup. We have taken all the feedback from IBM i and z/OS customers and created a new client package, with just the drivers, optimized for enterprise deployment. This page here:

is a step by step for using this package on the LU platforms, and one of the sub-pages:

There is a similar page for folks doing this on Windows:

I do apologize for using V10.1 links above, the V10.5 knowledge center is not working right now, but the TOC will be the same once it gets fixed, thus it should be easy enough to locate the equivalent pages.


The Kernel method at_exit provides an alternative to the END statement; 
it registers a block of code to be executed just before the interpreter exits. 
As with END blocks, the code associated with the first at_exit call will be executed last. 
If the at_exit method is called multiple times within a loop, then the 
block associated with it will be executed multiple times when the interpreter exits.

at_exit ruby ... Andrea

2.times {
  END { puts 'END'}
  at_exit { puts 'at_exit' }
}




$ xmlservice generate mypgm var1:char var2:char var3:dec1

ActiveXMLSERVICE::Base
initialize(inchara=>a1,inchara=>a2,[dschara=>t1, ..],..,a64)
input_parms(inchara=>a1,inchara=>a2,[dschara=>t1, ..],..,a64)
end

class MyPgm < ActiveXMLSERVICE::Base

@pgm =
   input_parms(inchara=>a1,inchara=>a2,[dschara=>t1, ..],..,a64) do
    char( :inchara,  1)
    char :incharb, 1
    dec :indec1, 7.4
    dec :indec2, 12.2
    struct :inds1,1 do
      char :dschara, 1
      char :dscharb, 1
      dec :indec1, 7.4
      dec :indec2, 12.2
      struct :inds2,1 do
        dec :indec1, 7.4
        dec :indec2, 12.2
      end
    end
  end 

end

      * <pgm mode='opm|ile' error='on|off|fast'>
      *   <name hex='on' before='cc1/cc2/cc3/cc4'>bin2hex('&fredflin')</name>
      *   <lib hex='on' before='cc1/cc2/cc3/cc4'>bin2hex('omlated')</lib>
      *   <func hex='on' before='cc1/cc2/cc3/cc4'>bin2hex('me&proc')</func>
      *   <parm> ...
      *   pgm parameters:
      *     <parm [io='in|out|both|omit' by='val|ref']>(see below)</parm> 
      *      (omit 1.2.3)
      *      data structure:
      *       <ds [dim='n' dou='label' len='label' data='records']>
      *         (data elements below)
      *       </ds>
      *       (len/setlen 1.5.4)
      *      data elements:
      *       <data type='data types' 
      *          [dim='n' varying='on|off|2|4' enddo='label' setlen='label' offset='label'
      *           hex='on|off' before='cc1/cc2/cc3/cc4' after='cc4/cc3/cc2/cc1' (1.6.8)
      *           trim='on|off'                                                 (1.7.1)
      *           ]>
      *       </data>




 down vote


You can make this very easy with the Docile gem, either by using the gem, or by reading the source code in order to understand how it works.

Say you want to make a Pizza via a DSL

Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)

And you use a builder pattern to make the Pizza

class PizzaBuilder
  def cheese(v=true); @cheese = v; end
  def pepperoni(v=true); @pepperoni = v; end
  def bacon(v=true); @bacon = v; end
  def sauce(v=nil); @sauce = v; end
  def build
    Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce)
  end
end

And you want a DSL, say something like

@sauce = :extra
pizza do
  bacon
  cheese
  sauce @sauce
end
# => should return Pizza.new(true, false, true, :extra)

All you have to do is define the pizza method as

require 'docile'

def pizza(&block)
  Docile.dsl_eval(PizzaBuilder.new, &block).build
end

And bang, you're done.


'''Call Ruby from RPG.  Is the below the best way?'''
http://174.79.32.155/wiki/index.php/PASE/RPG-2-PASE
http://174.79.32.155/Samples/Yips_util/dspfoil.php?afile=/www/zendsvr/htdocs/Samples/RPG_callpase/callpase.rpgle


'''Time ibm_db_adapter.rb:'''
when :ibm_i_time_fmt || "ibm_i_time_fmt" || IBM_DB::SQL_ATTR_TIME_FMT # Set connection's i5 time format
case value
when "iso" || IBM_DB::SQL_FMT_ISO
  conn_options[IBM_DB::SQL_ATTR_TIME_FMT] = IBM_DB::SQL_FMT_ISO
when "usa" || IBM_DB::SQL_FMT_USA
  conn_options[IBM_DB::SQL_ATTR_TIME_FMT] = IBM_DB::SQL_FMT_USA
when "eur" || IBM_DB::SQL_FMT_EUR
  conn_options[IBM_DB::SQL_ATTR_TIME_FMT] = IBM_DB::SQL_FMT_EUR
when "jis" || IBM_DB::SQL_FMT_JIS
  conn_options[IBM_DB::SQL_ATTR_TIME_FMT] = IBM_DB::SQL_FMT_JIS
when "hms" || IBM_DB::SQL_FMT_HMS
  conn_options[IBM_DB::SQL_ATTR_TIME_FMT] = IBM_DB::SQL_FMT_HMS
when "job" || IBM_DB::SQL_FMT_JOB
  conn_options[IBM_DB::SQL_ATTR_TIME_FMT] = IBM_DB::SQL_FMT_JOB
end


Rails Unit Test formal docs: http://guides.rubyonrails.org/testing.html

Difference between various dumps: http://guides.rubyonrails.org/migrations.html#types-of-schema-dumps

bash-4.2$ rake db:structure:dump
/PowerRuby/prV2R0M0/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:216: warning: Insecure world writable dir /PowerRuby/prV2R0M0 in PATH, mode 042777
undefined method `structure_dump' for #<ActiveRecord::ConnectionAdapters::IBM_DB2_I5:0x2161b784>
bash-4.2$ 



bash-4.2$ cat test/fixtures/histories.yml 
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html

one:
  command: MyText

two:
  command: MyText


> cat /test/test.log

   (8.6ms)  SET SCHEMA WART
   (8.6ms)  SET SCHEMA WART
   (74.5ms) DROP SCHEMA WART ... this is new
   (7.2ms)  SET SCHEMA WART
   (7.2ms)  SET SCHEMA WART
   (62.2ms) CREATE SCHEMA WART  ... this is new 
   (8.3ms)  SET SCHEMA WART
   (7.3ms)  SET SCHEMA WART
   (795.6ms)  DROP TABLE histories
   (1035.1ms)  CREATE TABLE histories (id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, command clob(1048576) NOT NULL, created_at timestamp, updated_at timestamp) 
   (5.0ms)  SELECT version FROM schema_migrations
   (7.1ms)  SET SCHEMA WART
   (7.5ms)  SET SCHEMA WART
  ActiveRecord::SchemaMigration Load (3.4ms)  SELECT schema_migrations.* FROM schema_migrations 
  ActiveRecord::SchemaMigration Load (2.2ms)  SELECT schema_migrations.* FROM schema_migrations 
  Fixture Delete (66.7ms)  DELETE FROM histories
  fixture insert (103.6ms)  INSERT INTO histories ( command, created_at, updated_at, id) VALUES (?,?,?,?)
  fixture insert (14.9ms)  INSERT INTO histories ( command, created_at, updated_at, id) VALUES (?,?,?,?)
---------------------------
HistoryTest: test_the_truth





SQLite3: https://github.com/rails/rails/blob/e1154a694d861abbcc1f8f1c8d557d2e349ba9c2/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb
Mysql: https://github.com/rails/rails/blob/db82e1d0bb21c2a13354b97733c09737719e946b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb#L60

http://guides.rubyonrails.org/migrations.html#schema-dumping-and-you

=======================
PostgreSQLDatabaseTasks
========================
def structure_dump(filename)
  set_psql_env
  search_path = configuration['schema_search_path']
  unless search_path.blank?
    search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
  end

  command = "pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"
  raise 'Error dumping database' unless Kernel.system(command)

  File.open(filename, "a") { |f| f << "SET search_path TO #{ActiveRecord::Base.connection.schema_search_path};\n\n" }
end

======================
SQLLiteDatabaseTasks
======================
def structure_dump(filename)
  dbfile = configuration['database']
  `sqlite3 #{dbfile} .schema > #{filename}`
end

==================
MySQLDatabaseTasks
==================
# File activerecord/lib/active_record/tasks/mysql_database_tasks.rb, line 57
      def structure_dump(filename)
        args = prepare_command_options('mysqldump')
        args.concat(["--result-file", "#{filename}"])
        args.concat(["--no-data"])
        args.concat(["#{configuration['database']}"])
        unless Kernel.system(*args)
          $stderr.puts "Could not dump the database structure. "                        "Make sure `mysqldump` is in your PATH and check the command output for warnings."
        end
      end

==================
IbmDbDatabaseTasks:
===================
      def task_structure_dump(task,filename=nil)
        if task.configuration.has_key?('ibm_i_dump_savf')
          if !task.configuration['ibm_i_dump_savf']
            return
          end
        end
        if filename.nil?
          filename = task_schema(task)
        end
        savlibtime = Time.now
        lastyear = Time.new(Time.now.year.to_i - 1)
        savf = "RB" + (Time.now.to_i - lastyear.to_i).to_s
        # create savlib
        begin
          cmd = "CRTSAVF FILE(QGPL/#{savf}) TEXT(''#{filename} #{savlibtime}'')"
          qcmdexc cmd
          task.log(cmd)
        rescue Exception => e
          puts e.message
          task.log("#{cmd} : #{e.message}")
        end
        # save the library
        begin
          cmd = "SAVLIB LIB(#{filename}) DEV(*SAVF) SAVF(QGPL/#{savf}) CLEAR(*ALL)"
          qcmdexc cmd
          task.log(cmd)
        rescue Exception => e
          puts e.message
          task.log("#{cmd} : #{e.message}")
        end
      end




bash-4.2$ rake db:schema:dump
/PowerRuby/prV2R0M0/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:216: warning: Insecure world writable dir /PowerRuby/prV2R0M0 in PATH, mode 042777
bash-4.2$ cat log/development.log 
start
   (7.9ms)  SET SCHEMA WART
   (9.8ms)  SET SCHEMA WART
  ActiveRecord::SchemaMigration Load (23.1ms)  SELECT schema_migrations.* FROM schema_migrations 
   (9.0ms)  SET SCHEMA WART
   (7.5ms)  SET SCHEMA WART
  ActiveRecord::SchemaMigration Load (3.1ms)  SELECT schema_migrations.* FROM schema_migrations 
bash-4.2$ 




def structure_dump(filename)
pg_dump is a utility for backing up a PostgreSQL database. 
mysqldump client is a backup program originally written by Igor Romanenko. It can be used to dump a database or a collection of databases for backup or transfer to another SQL server (not necessarily a MySQL server). 



    class IBM_DB2_I5 < IBM_DB2

if $rails_merge != 'R3'
      #############################
      # Unit testing (SQLLiteDatabaseTasks, MySQLDatabaseTasks, PostgreSQLDatabaseTasks)
      #############################
      def task_schema(task)
        if task.configuration.has_key?('schema')
          return task.configuration['schema']
        end
        task.configuration['username'];
      end
      def task_create(task)
        filename = task_schema(task)
        create_database filename
        task.log("CREATE SCHEMA #{filename}")
      end
      def task_drop(task)
        filename = task_schema(task)
        task_structure_dump(task,filename)
        drop_database filename
        task.log("DROP SCHEMA #{filename}")
      end
      def task_purge(task)
        begin
          task_drop(task)
        rescue Exception => e
        end
        task_create(task)
      end
      def task_charset(task)
        @adapter.connection.charset
      end
      def task_collation(task)
        @adapter.connection.collation
      end
      def task_structure_dump(task,filename=nil)
        if task.configuration.has_key?('ibm_i_dump_savf')
          if !task.configuration['ibm_i_dump_savf']
            return
          end
        end
        if filename.nil?
          filename = task_schema(task)
        end
        savlibtime = Time.now
        lastyear = Time.new(Time.now.year.to_i - 1)
        savf = "RB" + (Time.now.to_i - lastyear.to_i).to_s
        # create savlib
        begin
          cmd = "CRTSAVF FILE(QGPL/#{savf}) TEXT(''#{filename} #{savlibtime}'')"
          qcmdexc cmd
          task.log(cmd)
        rescue Exception => e
          puts e.message
          task.log("#{cmd} : #{e.message}")
        end
        # save the library
        begin
          cmd = "SAVLIB LIB(#{filename}) DEV(*SAVF) SAVF(QGPL/#{savf}) CLEAR(*ALL)"
          qcmdexc cmd
          task.log(cmd)
        rescue Exception => e
          puts e.message
          task.log("#{cmd} : #{e.message}")
        end
      end
      def task_structure_load(task,filename=nil)
        if filename.nil?
          filename = task_schema(task)
        end
        # restore the library
        begin
          cmd = "RSTLIB SAVLIB(#{filename}) DEV(*SAVF) SAVF(QGPL/#{filename}) MBROPT(*ALL) ALWOBJDIF(*ALL)"
          qcmdexc cmd
          task.log(cmd)
        rescue Exception => e
          puts e.message
          task.log("#{cmd} : #{e.message}")
        end
      end
end # rails_merge

http://youngiprofessionals.com/wiki/index.php/XMLSERVICE/RubySTRSQL

2.0.0-p247 :002 > "a".encode('UTF-16') + "a".encode('UTF-8')
Encoding::CompatibilityError: incompatible character encodings: UTF-16 and UTF-8
	from (irb):2
	from /Users/aaronbartell/.rvm/gems/ruby-2.0.0-p247/gems/rubysl-irb-2.0.4/bin/irb:12:in `<top (required)>'
	from /Users/aaronbartell/.rvm/gems/ruby-2.0.0-p247/bin/irb:23:in `load'
	from /Users/aaronbartell/.rvm/gems/ruby-2.0.0-p247/bin/irb:23:in `<main>'


  VALUE         return_value   =  Qnil;

return rb_external_str_new_with_enc((char *)str, len, utf8_enc);

rb_encoding *utf8_enc = rb_enc_find("UTF-8");
return rb_str_export_to_enc(string,utf8_enc);

-------------
SQLGetData (utf-8 non-wide)  
         20ef42b0 : 20efdbd0 00010011  20ef3a70 0000001a  >..........:p....<
         20ef42c0 : 2ff20f50                              >/..P<
     SQLGetData = 0
     nbr = 1 (1)
     type = SQL_WCHAR 17 (11)
     buf len = 26 (1a)
     buff  
         20ef3a70 : 0073006f 006d0065  00740068 0069006e  >.s.o.m.e.t.h.i.n<
         20ef3a80 : 0067                                  >.g<
-------------
SQLGetData (utf-8 non-wide)  
         20ef4a10 : 20efdbd0 00020011  20ef3a70 0000001a  >..........:p....<
         20ef4a20 : 2ff20f50                              >/..P<
     SQLGetData = 1
     nbr = 2 (2)
     type = SQL_WCHAR 17 (11)
     buf len = 26 (1a)
     buff  
         20ef3a70 : 0073006f 006d0065  00740068 0069006e  >.s.o.m.e.t.h.i.n<
         20ef3a80 : 00670020 00200020  002037c0 00000020  >.g........7.....<
         20ef3a90 : 00000000 00000000  00000000 00000000  >................<
         20ef3aa0 : 2ff20200                              >/...<





    stmt = IBM_DB::exec(@@conn,'CREATE TABLE VAR_GRAPHIC_TEST (COL1 VARGRAPHIC(25) CCSID 1200 DEFAULT NULL,'\
                                                              'COL2 GRAPHIC(25) CCSID 1200 DEFAULT NULL)')

/*
    This function sets PASE CCSID before any DB2 actions.
*/
int _ruby_ibm_db_SQLOverrideCCSID400_helper(int newCCSID) {
  int i = 0;

  _ruby_ibm_db_trace_output("SQLOverrideCCSID400", &newCCSID, sizeof(newCCSID));

  return (newCCSID > 0 ? SQLOverrideCCSID400(newCCSID) : SQLOverrideCCSID400(1208));
}

=================
strsql
select hex(col1),hex(col2) from db2/VAR_GRAPHIC_TEST 

 ....+....1....+....2....+....3....+..
 HEX ( COL1 )                         
 0073006F006D0065007400680069006E0067 
 ********  End of data  ********      

...+...11....+...12....+...13....+...14....+...15....+...16....+...17....+...18....+...19....+...20..
 HEX ( COL2 )                                                                                        
 0073006F006D0065007400680069006E00670020002000200020002000200020002000200020002000200020002000200020
*     
================
    while row = IBM_DB::fetch_array(stmt)
      all << row
      puts "\ncol1_before: |#{col1}|"
      puts " row0_after: |#{row[0]}|"
      puts " col1_class: #{col1.class.name}"
      puts " row0_class: #{row[0].class.name}"
      puts " col1_encode: #{col1.encoding}"
      puts " row0_encode: #{row[0].encoding}"
      puts " equal:#{col1==row[0]}"
      puts " col1_hex: #{col1.unpack('H*')}"
      puts " row0_hex: #{row[0].unpack('H*')}"
      puts "col2_before: |#{col2}|"
      puts " col2_after: |#{row[1]}|"
      puts " col2_class: #{col2.class.name}"
      puts " row1_class: #{row[1].class.name}"
      puts " col2_encode: #{col2.encoding}"
      puts " row1_encode: #{row[1].encoding}"
      puts " equal:#{col2==row[1]}"
      puts " col2_hex: #{col2.unpack('H*')}"
      puts " row1_hex: #{row[1].unpack('H*')}"
    end


[2/2] Test_01010_DriverVarGraphic#test_0001_create_table            
col1_before: |something|
 row0_after: |something|
 col1_class: String
 row0_class: String
 col1_encode: UTF-8
 row0_encode: UTF-8
 equal:false
 col1_hex: ["736f6d657468696e67"]
 row0_hex: ["0073006f006d0065007400680069006e0067"]
col2_before: |something|
 col2_after: |something         = {}
/&#65533;|
 col2_class: String
 row1_class: String
 col2_encode: UTF-8
 row1_encode: UTF-8
 equal:false
 col2_hex: ["736f6d657468696e67"]
 row1_hex: ["0073006f006d0065007400680069006e006700200020002000002020202020203d207b7d0a00000000000000000000002ff20ed0"]
 = 1.36 s
  1) Failure:
Test_01010_DriverVarGraphic#test_0001_create_table [test_01010_DriverVarGraphic.rb:57]:
COL1 sent/received not the same.
<"something"> expected but was
<"\u0000s\u0000o\u0000m\u0000e\u0000t\u0000h\u0000i\u0000n\u0000g">.

Finished tests in 1.475098s, 1.3558 tests/s, 2.0338 assertions/s.
2 tests, 3 assertions, 1 failures, 0 errors, 0 skips