Skip to content

Repository files navigation

DBF

VersionBuild StatusTotal DownloadsLicense

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

Compatibility

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

  • Ruby 3.3.x, 3.4.x, 4.0.x

Older Rubies are supported by older DBF release lines:

DBF versionRuby support
5.2+3.3+
4.3 – 5.13.1+
4.0 – 4.22.4+
3.x (3_stable)2.0 – 2.3
2.x (2_stable)1.8 – 1.9

DBF is Ractor-friendly: all library constants are deeply frozen, so tables can be opened, enumerated, and exported inside non-main Ractors.

Installation

Install the gem manually:

geminstalldbf

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','rb')widgets=DBF::Table.new(data)

All errors raised by the library inherit from DBF::Error, so you can rescue the library as a unit:

beginwidgets=DBF::Table.new("widgets.dbf")rescueDBF::Error=>eputs"Unable to read DBF file: #{e.message}"end

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

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

Use the block form to close the table automatically, like File.open:

DBF::Table.open('widgets.dbf')do |table|
table.each{ |record| putsrecord.name}end

Enumerate all records

widgets.eachdo |record|
putsrecord.nameputsrecord.emailend

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 methodwidget["SlotNumber"]# original field name in dbf filewidget['slot_number']# underscored field name stringwidget[: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 s42widgets.find(:all,slot_number: 's42')do |widget|
# the record will be nil if deleted, but not yet pruned from the databaseifwidgetputswidget.serial_numberendend# find the first record with slot_number equal to s42widgets.find:first,slot_number: 's42'# find record number 10widgets.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
04macRomanStandard Macintosh
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
68cp895Kamenický (Czech) MS–DOS
69cp620Mazovia (Polish) 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
7dcp1255Hebrew Windows
7ecp1256Arabic Windows
86cp737Greek OEM
87cp852Slovenian OEM
88cp857Turkish OEM
96macCyrillicRussian Macintosh
97macCentEuroMacintosh EE
98macGreekGreek Macintosh
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'classBook < ActiveRecord::Base;endclassCreateBooks < ActiveRecord::Migrationdefself.uptable=DBF::Table.new('db/dbf/books.dbf')eval(table.schema)Book.reset_column_informationtable.eachdo |record|
Book.create(title: record.title,author: record.author)endenddefself.downdrop_table:booksendend

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'classBook < Sequel::Model;endSequel.migrationdoupdotable=DBF::Table.new('db/dbf/books.dbf')eval(table.schema(:sequel,table_only: true))# limit output to create_table() onlyBook.reset_column_informationtable.eachdo |record|
Book.create(title: record.title,author: record.author)endenddowndodrop_table(:books)endend

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|-c|-r|-j|-J] filename
-h = print this message
-v = print the DBF gem version
-s = print summary information
-a = create an ActiveRecord::Schema
-r = create a Sequel migration
-c = export as CSV
-j = export as a JSON array
-J = export as JSON Lines (one record per line)

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

Dump all records as JSON or JSON Lines:

dbf -j books.dbf > books.json
dbf -J books.dbf > books.jsonl

JSON Lines output is streamed record by record, so it works well for very large files and pipelines (for example dbf -J books.dbf | jq or importing into DuckDB).

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').contactsmy_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 FoxProYYYYYYYYNYYYNNNN-
31Visual FoxPro with AutoIncrementYYYYYYYYNYYYNNNNN
32Visual FoxPro with field type Varchar or VarbinaryYYYYYYYYNYYYNNNNN
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 fileYYYYYYYYNYYYNNNNN
fbFoxPro without memo fileYYYY-YYYNYYYNNNNN

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-2026 Keith Morrison <keithm@infused.org>

Released under the MIT License. See LICENSE for the full text.

About

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

Topics

Resources

Contributing

Security policy

Stars

281 stars

Watchers

16 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages