Have a simple test-installation with ruby-2.1.3 rails-3.213 and activerecord-advantage-adapter-0.11. Simple read of simple emps.dbf table bumps ruby with BigDecimal conversion error:

Loading development environment (Rails 3.2.13)
   irb(main):001:0> e = Emp.all
(43.2ms)  EXECUTE PROCEDURE sp_GetTables( NULL, NULL, NULL, 'TABLE' );
Emp Load (0.8ms)  SELECT "emps".* FROM "emps"
ArgumentError: string contains null byte
    from /opt/ruby2/lib/ruby/2.1.0/bigdecimal/util.rb:60:in `BigDecimal'
    from /opt/ruby2/lib/ruby/2.1.0/bigdecimal/util.rb:60:in `to_d'
    from opt/rails3/gems/activerecord-3.2.13/lib/active_record/
         connection_adapters/column.rb:190:in `value_to_decimal'
    from /opt/rails3/gems/activerecord-3.2.13/lib/active_record/attribute_methods/read.rb:
         84:in `__temp__'
    from /opt/rails3/gems/activerecord-3.2.13/lib/active_record/attribute_methods/read.rb:
         46:in `type_cast_attribute'
    from /opt/rails3/gems/activerecord-3.2.13/lib/active_record/attribute_methods/read.rb:
         127:in `read_attribute'
    from /opt/rails3/gems/activerecord-3.2.13/lib/active_record/attribute_methods.rb:
         203:in `attribute_for_inspect'
    from /opt/rails3/gems/activerecord-3.2.13/lib/active_record/base.rb:642:in `block in inspect'
    from /opt/rails3/gems/activerecord-3.2.13/lib/active_record/base.rb:640:in `collect'
    from /opt/rails3/gems/activerecord-3.2.13/lib/active_record/base.rb:640:in `inspect'
    from /opt/rails3/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
    from /opt/rails3/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
    from /opt/rails3/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
    from /opt/ruby2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `require'
    from /opt/ruby2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
    from /opt/ruby2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:144:in `require'
    from script/rails:6:in `<main>'irb(main):002:0>

Other operation run fine:

 Emp.all.each {|e| puts "#{e.EMPNO.to_s.sub(/\.0/,'')} #{e.ENAME.rstrip}"}

7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER

The table is simple:

dbase version     dBASE3
update year         2014
update month          10
update day            20
number of recs        14
header length        290
record length         68

Fno     Field Name      Type    Length  Decimal
  1     EMPNO           N         4       0
  2     ENAME           C        15       0
  3     JOB             C        12       0
  4     MGR             N         4       0
  5     HIREDATE        D         8       0
  6     SAL             N        10       2
  7     COMM            N        10       2
  8     DEPTNO          N         4       0

EMPNO       ENAME   JOB              MGR    HIREDATE            SAL    COMM DEPTNO
-----       ------  ---------       ----    --------        ------- ------- ------
 7369       SMITH   CLERK           7902    19801217         800.00             20
 7499       ALLEN   SALESMAN        7698    19810220        1600.00  300.00     30
 7521       WARD    SALESMAN        7698    19810222        1250.00  500.00     30
 7566       JONES   MANAGER         7839    19810402        2975.00             20
 7654       MARTIN  SALESMAN        7698    19810928        1250.00 1400.00     30
 7698       BLAKE   MANAGER         7839    19810501        2850.00             30
 7782       CLARK   MANAGER         7839    19810609        2450.00             10
 7788       SCOTT   ANALYST         7566    19870419        3000.00             20
 7839       KING    PRESIDENT               19811117        5000.00             10
 7844       TURNER  SALESMAN        7698    19810908        1500.00    0.00     30
 7876       ADAMS   CLERK           7788    19870523        1100.00             20
 7900       JAMES   CLERK           7698    19811203         950.00             30
 7902       FORD    ANALYST         7566    19811203        3000.00             20
 7934       MILLER  CLERK           7782    19820123        1300.00             10

asked 23 Oct '14, 23:36

freakout's gravatar image

freakout
11446
accept rate: 0%


I suspect that your particular use case, while simple, may not have been caught during testing.

Thank you for providing the table / data. Would you also be able to edit your question and provide a bit of information regarding the code?

I'll take a look and see if I can find a workaround and then pass the info to the engineering team.

(If you do edit the question, please drop a comment so it notifies me - thanks)

Edgar

link

answered 24 Oct '14, 09:08

Edgar%20Sherman's gravatar image

Edgar Sherman
5.4k13185
accept rate: 25%

edited 24 Oct '14, 09:08

Hello Edgar, thanks for your answer. We are evaluating ADS for the purpose of migrating an old Clipper-App to Rails. The code is really just a one-liner - here is the code together with the output. I could not manage to attach a binary file - so here is a link to the dbf file http://www.freakout.de/fkselb/emps.dbf - good luck - by the way - we discovered more problems - ruby complains when 8-bit OEM-charset data is assigned to - when we have a documented testcase we will ask the next question.

#!/opt/ruby/bin/ruby
ENV['GEM_PATH'] = '/opt/rubygem/gems:/opt/rails'
require 'active_record'

ActiveRecord::Base.establish_connection(  
    :adapter  => 'advantage',
    :database => '/home/axel/p/axbase/data',
    :username => '',
    :password => '',
    :options  => 'ServerType=ADS_LOCAL_SERVER; TableType=ADS_CDX;'
)

class Emp < ActiveRecord::Base  
  self.table_name = "emps"
  self.primary_key = "empno"
end

puts Emp.first.to_yaml
Emp.all.each {|e| puts e.to_yaml}

Output:

--- !ruby/object:Emp
attributes:
  EMPNO: 7369.0
  ENAME: 'SMITH          '
  JOB: 'CLERK       '
  MGR: 7902.0
  HIREDATE: 1980-12-17
  SAL: 800.0
  COMM: 0.0
  DEPTNO: 20.0
/opt/rails/gems/activerecord-advantage-adapter-0.1.1
/opt/ruby/lib/ruby/2.1.0/bigdecimal/util.rb:60:in `BigDecimal': string contains null byte (ArgumentError)
    from /opt/ruby/lib/ruby/2.1.0/bigdecimal/util.rb:60:in `to_d'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/connection_adapters/column.rb:190:in `value_to_decimal'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/attribute_methods/read.rb:84:in `__temp__'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/attribute_methods/read.rb:46:in `type_cast_attribute'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/attribute_methods/read.rb:127:in `read_attribute'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/attribute_methods.rb:185:in `block in attributes'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/attribute_methods.rb:185:in `each'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/attribute_methods.rb:185:in `attributes'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/base.rb:581:in `encode_with'
    from /opt/ruby/lib/ruby/2.1.0/psych/visitors/yaml_tree.rb:485:in `dump_coder'
    from /opt/ruby/lib/ruby/2.1.0/psych/visitors/yaml_tree.rb:146:in `accept'
    from /opt/ruby/lib/ruby/2.1.0/psych/visitors/yaml_tree.rb:112:in `push'
    from /opt/ruby/lib/ruby/2.1.0/psych.rb:409:in `dump'
    from /opt/ruby/lib/ruby/2.1.0/psych/core_ext.rb:14:in `psych_to_yaml'
    from /opt/rails/gems/activerecord-3.2.13/lib/active_record/base.rb:654:in `to_yaml'
    from ./test_dbs_rby_ard_ads.run:21:in `block in <main>'
    from ./test_dbs_rby_ard_ads.run:21:in `each'
    from ./test_dbs_rby_ard_ads.run:21:in `<main>'
link

answered 24 Oct '14, 11:10

freakout's gravatar image

freakout
11446
accept rate: 0%

I've not had a chance to test on a Linux Box but I did have a chance to test on Windows. What I see is that the driver was written for Ruby 1.9.3 with Active Record 3.2. One I had these in place (with arel 3.0.3) it seemed to work well.

I suspect that there may be some changes to the more recent versions of Ruby / Active Record (originally it downloaded 4 I think) that may be causing your issues. Perhaps try with these and see if it resolves your two problems.

(24 Oct '14, 14:46) Edgar Sherman

Dear Edgar, ruby 1.9.x/rails 3.0.x is not an option for us. Way too old. The whole adapter is not compatible with Rails4. Is there any chance that this wonderful piece of software will be maintained to support current versions? Cheers Axel

link

answered 25 Oct '14, 13:49

freakout's gravatar image

freakout
11446
accept rate: 0%

Hi Akel, Unfortunately I'm not in a position to answer if it will be. I would recommend posting a suggestion on the feedback site to request support of these newer versions. http://feedback.advantagedatabase.com/

(27 Oct '14, 09:27) Edgar Sherman

Since the ruby/activerecord interface is a feature of the product mentioned in the release notes it should be maintained to support current versions - rails-3.0 is more than 3 years old. i have managed to use it with rails-3.2.13/ruby-2.1.3 (last rails3 version no chance with rails4) with this patch:

--- gems/activerecord-advantage-adapter-%{railsadvantage}/lib/active_record/connection_adapters/advantage_adapter.rb        Mon Oct 27 14:13:47 2014
+++ gems/activerecord-advantage-adapter-%{railsadvantage}/lib/active_record/connection_adapters/advantage_adapter.rb        Mon Oct 27 14:27:48 2014
@@ -381,6 +381,8 @@
     WHEN type_name = 'VARCHAR' or type_name = 'CHAR' or type_name = 'CICHAR' or
          type_name = 'NVARCHAR' or type_name = 'NCHAR' or type_name = 'VARBINARY'
          THEN CAST(TRIM(type_name) + '(' + TRIM(CAST(column_size AS SQL_CHAR)) + ')' AS SQL_CHAR)
+    WHEN type_name = 'NUMERIC' and decimal_digits = 0
+         THEN CAST('INTEGER(' + TRIM(CAST(column_size AS SQL_CHAR)) + ')' AS SQL_CHAR)
     WHEN type_name = 'NUMERIC' or type_name = 'DOUBLE' or type_name = 'CURDOUBLE'
          THEN CAST(TRIM(type_name) + '(' + TRIM(CAST(column_size AS SQL_CHAR)) + ',' + TRIM(CAST(decimal_digits AS SQL_CHAR)) + ')' AS SQL_CHAR)
     ELSE
@@ -448,7 +450,7 @@
         # Nullability is returned as 0 (no nulls allowed) or 1 (nulls allowed)
         # Alos, ActiveRecord expects an autoincrement column to have default value of NULL
         def table_structure(table_name)
-          sql = "SELECT COLUMN_NAME, IIF(COLUMN_DEF = 'NULL', null, COLUMN_DEF) as COLUMN_DEF, TYPE_NAME, NULLABLE from (EXECUTE PROCEDURE sp_GetColumns( NULL, NULL, '#{table_name}', NULL )) spgc where table_cat <> 'system';"
+          sql = "SELECT COLUMN_NAME, IIF(COLUMN_DEF = 'NULL', null, COLUMN_DEF) as COLUMN_DEF, IIF(TYPE_NAME = 'NUMERIC' and DECIMAL_DIGITS = 0, 'INTEGER', TYPE_NAME) as TYPE_NAME, NULLABLE from (EXECUTE PROCEDURE sp_GetColumns( NULL, NULL, '#{table_name}', NULL )) spgc where table_cat <> 'system';"
           structure = execute(sql, :skip_logging)
           raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure == false
           structure
@@ -514,7 +516,11 @@
               max_cols = ADS.instance.api.ads_num_cols(rs)
               result = Hash.new()
               max_cols.times do |cols|
-                result[ADS.instance.api.ads_get_column_info(rs, cols)[2]] = ADS.instance.api.ads_get_column(rs, cols)[1]
+                cinfo = ADS.instance.api.ads_get_column_info(rs, cols)
+                cvalu = ADS.instance.api.ads_get_column(rs, cols)[1]
+                cvalu = '0.0' if cinfo[3] == 13 and cvalu.rstrip == ''
+                cvalu.rstrip! if cinfo[3] == 2 and cvalu
+                result[cinfo[2]] = cvalu
               end
               record << result
             end
link

answered 28 Oct '14, 02:42

freakout's gravatar image

freakout
11446
accept rate: 0%

Your answer to the original question.
If responding to a request for additional information, please edit the question or use the comment functionality.
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "Title")
  • image?![alt text](/path/img.jpg "Title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×172
×79

Asked: 23 Oct '14, 23:36

Seen: 7,879 times

Last updated: 28 Oct '14, 02:42

Advantage Developer Zone Contact Us Privacy Policy Copyright Info


Powered by Advantage Database Server and OSQA
Disclaimer: Opinions expressed here are those of the poster and do not necessarily reflect the views of the company.