Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dbf

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dbf

  • 5.0.1
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

DBF

Version Build Status Code Quality Code Coverage Total Downloads License

DBF is a small, fast Ruby library for reading dBase, xBase, Clipper, and FoxPro database files.

NOTE: Beginning with version 4.3 we have dropped support for Ruby 3.0 and earlier.

NOTE: Beginning with version 4 we have dropped support for Ruby 2.0, 2.1, 2.2, and 2.3. If you need support for these older Rubies, please use 3.0.x (https://github.com/infused.org/dbf/tree/3_stable)

NOTE: Beginning with version 3 we have dropped support for Ruby 1.8 and 1.9. If you need support for older Rubies, please use 2.0.x (https://github.com/infused/dbf/tree/2_stable)

Compatibility

DBF is tested to work with the following versions of Ruby:

  • Ruby 3.1.x, 3.2.x, 3.3.x

Installation

Install the gem manually:

gem install dbf

Or add to your Gemfile:

gem 'dbf'

Basic Usage

Open a DBF file using a path:

require 'dbf'
widgets = DBF::Table.new("widgets.dbf")

Open a DBF file using an IO object:

data = File.open('widgets.dbf')
widgets = DBF::Table.new(data)

Open a DBF by passing in raw data (wrap the raw data with StringIO):

widgets = DBF::Table.new(StringIO.new('raw binary data'))

Enumerate all records

widgets.each do |record|
  puts record.name
  puts record.email
end

Find a single record

widget = widgets.find(6)

Note that find() will return nil if the requested record has been deleted and not yet pruned from the database.

The value for an attribute can be accessed via element reference in several ways.

widget.slot_number     # underscored field name as method

widget["SlotNumber"]   # original field name in dbf file
widget['slot_number']  # underscored field name string
widget[:slot_number]   # underscored field name symbol

Get a hash of all attributes. The keys are the original column names.

widget.attributes
# => {"Name" => "Thing1 | SlotNumber" => 1}

Search for records using a simple hash format. Multiple search criteria are ANDed. Use the block form if the resulting record set is too big. Otherwise, all records are loaded into memory.

# find all records with slot_number equal to s42
widgets.find(:all, slot_number: 's42') do |widget|
  # the record will be nil if deleted, but not yet pruned from the database
  if widget
    puts widget.serial_number
  end
end

# find the first record with slot_number equal to s42
widgets.find :first, slot_number: 's42'

# find record number 10
widgets.find(10)

Enumeration

DBF::Table is a Ruby Enumerable, so you get several traversal, search, and sort methods for free. For example, let's get only records created before January 1st, 2015:

widgets.select { |w| w.created_date < Date.new(2015, 1, 1) }

Or custom sorting:

widgets.sort_by { |w| w.created_date }

Encodings (Code Pages)

dBase supports encoding non-english characters with different character sets. Unfortunately, the character set used may not be set explicitly. In that case, you will have to specify it manually. For example, if you know the dbf file is encoded with 'Russian OEM':

table = DBF::Table.new('dbf/books.dbf', nil, 'cp866')
Code PageEncodingDescription
01cp437U.S. MS–DOS
02cp850International MS–DOS
03cp1252Windows ANSI
08cp865Danish OEM
09cp437Dutch OEM
0acp850Dutch OEM*
0bcp437Finnish OEM
0dcp437French OEM
0ecp850French OEM*
0fcp437German OEM
10cp850German OEM*
11cp437Italian OEM
12cp850Italian OEM*
13cp932Japanese Shift-JIS
14cp850Spanish OEM*
15cp437Swedish OEM
16cp850Swedish OEM*
17cp865Norwegian OEM
18cp437Spanish OEM
19cp437English OEM (Britain)
1acp850English OEM (Britain)*
1bcp437English OEM (U.S.)
1ccp863French OEM (Canada)
1dcp850French OEM*
1fcp852Czech OEM
22cp852Hungarian OEM
23cp852Polish OEM
24cp860Portuguese OEM
25cp850Portuguese OEM*
26cp866Russian OEM
37cp850English OEM (U.S.)*
40cp852Romanian OEM
4dcp936Chinese GBK (PRC)
4ecp949Korean (ANSI/OEM)
4fcp950Chinese Big5 (Taiwan)
50cp874Thai (ANSI/OEM)
57cp1252ANSI
58cp1252Western European ANSI
59cp1252Spanish ANSI
64cp852Eastern European MS–DOS
65cp866Russian MS–DOS
66cp865Nordic MS–DOS
67cp861Icelandic MS–DOS
6acp737Greek MS–DOS (437G)
6bcp857Turkish MS–DOS
6ccp863French–Canadian MS–DOS
78cp950Taiwan Big 5
79cp949Hangul (Wansung)
7acp936PRC GBK
7bcp932Japanese Shift-JIS
7ccp874Thai Windows/MS–DOS
86cp737Greek OEM
87cp852Slovenian OEM
88cp857Turkish OEM
c8cp1250Eastern European Windows
c9cp1251Russian Windows
cacp1254Turkish Windows
cbcp1253Greek Windows
cccp1257Baltic Windows

Migrating to ActiveRecord

An example of migrating a DBF book table to ActiveRecord using a migration:

require 'dbf'

class Book < ActiveRecord::Base; end

class CreateBooks < ActiveRecord::Migration
  def self.up
    table = DBF::Table.new('db/dbf/books.dbf')
    eval(table.schema)

    Book.reset_column_information
    table.each do |record|
      Book.create(title: record.title, author: record.author)
    end
  end

  def self.down
    drop_table :books
  end
end

If you have initialized the DBF::Table with raw data, you will need to set the exported table name manually:

table.name = 'my_table_name'

Migrating to Sequel

An example of migrating a DBF book table to Sequel using a migration:

require 'dbf'

class Book < Sequel::Model; end

Sequel.migration do
  up do
    table = DBF::Table.new('db/dbf/books.dbf')
    eval(table.schema(:sequel, true)) # passing true to limit output to create_table() only

    Book.reset_column_information
    table.each do |record|
      Book.create(title: record.title, author: record.author)
    end
  end

  down do
    drop_table(:books)
  end
end

If you have initialized the DBF::Table with raw data, you will need to set the exported table name manually:

table.name = 'my_table_name'

Command-line utility

A small command-line utility called dbf is installed with the gem.

$ dbf -h
usage: dbf [-h|-s|-a] filename
  -h = print this message
  -v = print the version number
  -s = print summary information
  -a = create an ActiveRecord::Schema
  -r = create a Sequel Migration
  -c = export as CSV

Create an executable ActiveRecord schema:

dbf -a books.dbf > books_schema.rb

Create an executable Sequel schema:

dbf -r books.dbf > migrate/001_create_books.rb

Dump all records to a CSV file:

dbf -c books.dbf > books.csv

Reading a Visual Foxpro database (v8, v9)

A special Database::Foxpro class is available to read Visual Foxpro container files (file with .dbc extension). When using this class, long field names are supported, and tables can be referenced without using names.

require 'dbf'

contacts = DBF::Database::Foxpro.new('contact_database.dbc').contacts
my_contact = contacts.record(1).spouses_interests

dBase version compatibility

The basic dBase data types are generally supported well. Support for the advanced data types in dBase V and FoxPro are still experimental or not supported. If you have insight into how any of the unsupported data types are implemented, please open an issue on Github. FoxBase/dBase II files are not supported at this time.

Supported data types by dBase version

VersionDescriptionCNLDMFBGPYTIVX@O+
02FoxBaseYYYY-------------
03dBase III without memo fileYYYY-------------
04dBase IV without memo fileYYYY-------------
05dBase V without memo fileYYYY-------------
07Visual Objects 1.xYYYY-------------
30Visual FoxProYYYYYYYYNYNYNNNN-
31Visual FoxPro with AutoIncrementYYYYYYYYNYNYNNNNN
32Visual FoxPro with field type Varchar or VarbinaryYYYYYYYYNYNYNNNNN
7bdBase IV with memo fileYYYYYY-----------
83dBase III with memo fileYYYYY------------
87Visual Objects 1.x with memo fileYYYYY------------
8bdBase IV with memo fileYYYYY--------N---
8edBase IV with SQL tableYYYYY--------N---
f5FoxPro with memo fileYYYYYYYYNYNYNNNNN
fbFoxPro without memo fileYYYY-YYYNYNYNNNNN

Data type descriptions

  • C = Character
  • N = Number
  • L = Logical
  • D = Date
  • M = Memo
  • F = Float
  • B = Binary
  • G = General
  • P = Picture
  • Y = Currency
  • T = DateTime
  • I = Integer
  • V = VariField
  • X = SQL compat
  • @ = Timestamp
  • O = Double
    • = Autoincrement

Limitations

  • DBF is read-only
  • Index files are not utilized

License

Copyright (c) 2006-2024 Keith Morrison <keithm@infused.org>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

FAQs

Package last updated on 25 Apr 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc