All Projects → majkel89 → dbase

majkel89 / dbase

Licence: MIT License
Library for processing dbase / xbase / dbf database files

Programming Languages

PHP
23972 projects - #3 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to dbase

dbf-to-sqlite
CLI tool for converting DBF files (dBase, FoxPro etc) to SQLite
Stars: ✭ 31 (+6.9%)
Mutual labels:  foxpro, dbf, dbase
dbf2sql
DBF 2 SQL is small command line tool for converting DBF files to MySQL dump format.
Stars: ✭ 12 (-58.62%)
Mutual labels:  foxpro, dbf
NDbfReader
A fully managed reader of DBF files. Fast and lightweight with async support.
Stars: ✭ 37 (+27.59%)
Mutual labels:  dbf, dbase
go-foxpro-dbf
Golang package for reading XBase FoxPro DBF/FPT files
Stars: ✭ 59 (+103.45%)
Mutual labels:  foxpro, dbf
hearthstone-card-images
(Archived, see below) Hearthstone card image repository
Stars: ✭ 63 (+117.24%)
Mutual labels:  dbf
CodeBase-for-DBF
CodeBase is a C-based library to read, write and manage DBF type tables and indexes.
Stars: ✭ 38 (+31.03%)
Mutual labels:  dbf
nfJson
Provides a set of fast performance, reliable and easy to use Json functions using pure VFP
Stars: ✭ 40 (+37.93%)
Mutual labels:  foxpro
js-harb
❌ Host of Archaic Representations of Books (now merged in http://github.com/sheetjs/js-xlsx )
Stars: ✭ 55 (+89.66%)
Mutual labels:  dbf
foxpages
Visual FoxPro Multithread Web Server
Stars: ✭ 22 (-24.14%)
Mutual labels:  foxpro
Sheetjs
📗 SheetJS Community Edition -- Spreadsheet Data Toolkit
Stars: ✭ 28,479 (+98103.45%)
Mutual labels:  dbf
Pgloader
Migrate to PostgreSQL in a single command!
Stars: ✭ 3,754 (+12844.83%)
Mutual labels:  dbase

dbase

Build Status SensioLabsInsight Latest Stable Version Total Downloads Latest Unstable Version PHP Version License

Library for processing dbase tables.

Table of Contents

  1. Supported formats
    1. Supported memo formats
  2. Installation
  3. Documentation
    1. Reading tables
    2. Inserting rows
    3. Automatic type conversion
    4. Record object
      1. Reading data from record
      2. Writing data to record
    5. Record object
    6. Updating tables
    7. Deleting records
    8. Transactions
    9. Defining tables
      1. Creating table from another table
    10. Filters
      1. Using filters
      2. Writing custom filter

Supported formats

  • dBASE III
  • dBASE III PLUS
Supported memo formats
  • DBT
  • FPT

Installation

Composer

Using composer to install this library is strongly recommended.

composer require org.majkel/dbase

Then in your script use this line of code

require_once 'vendor/autoload.php'

Old-fashion style

Download library and place it somewhere on disk.

Then in your script use this line of code

require_once 'DBASE/LIB/DIR/autoloader.php';

Documentation

Reading tables

Table object is both array accessible and traversable. You can loop over it as collection or read specific record by it's index.

require_once 'vendor/autoload.php'

use org\majkel\dbase\Table;

$totalSum = 0;

$dbf = Table::fromFile('some/table.dbf');

foreach ($dbf as $record) {
    // returns all records includeing deleted ones
    if (!$record->isDeleted()) {
        $totalSum += $record->int_val;
    }
}

echo "Total sum is $totalSum, 5th description: {$record[4]['description']}\n";

Inserting rows

You can insert records as record object or as an associative array.

Note that insert operation is not atomic. Use transactions to achieve integrity safety.

require_once 'vendor/autoload.php'

use org\majkel\dbase\Table;
use org\majkel\dbase\Record;

$dbf = Table::fromFile('some/table.dbf');

$record = new Record();
$record->fieldBool = true;
$record->fieldInt  = 123;
$record->fieldChar = 'some text 1';
$record->fieldMemo = 'some long text';

$dbf->insert($record);

$dbf->insert([
    'fieldBool' => false,
    'fieldInt'  => 321,
    'fieldChar' => 'some text 2',
]);

Automatic type conversion

Dbase and PHP types are automatically converted during fetching and storing of rows.

Dbase type Type name Possible values PHP type
C Character any string string
D Date DDMMYY DateTime
L Logical [YTNF?] boolean
M Memo any string string
N Numeric [-0-9.] int / float

Record object

Record is basically ArrayObject. Object that can be treated as array.

Reading data from record

require_once 'vendor/autoload.php'

use org\majkel\dbase\Table;

$dbf = Table::fromFile('some/table.dbf');

// fetch first record
$record = $dbf[0];

echo "int  field: {$record->number}\n"; // returns integer
echo "bool field: {$record->boolean}\n"; // returns boolean
echo "date field: {$record->date->format('Y-m-d')}\n"; // return DateTime object
echo "text field: {$record->text}\n"; // returns string
echo "memo field: {$record->memo}\n"; // returns string (not entity id)
echo "memo field id: {$record->getMemoEntryId('memo')}\n"; // returns entity id for memo field `memo`
echo "is record deleted: {$record->isDeleted('memo')}\n"; // returns whether record is deleted

// ... or ...

echo "int  field: {$record['number']}\n"; // returns integer
echo "bool field: {$record['boolean']}\n"; // returns boolean
echo "date field: {$record['date']->format('Y-m-d')}\n"; // return DateTime object
echo "text field: {$record['text']}\n"; // returns string
echo "memo field: {$record['memo']}\n"; // returns string (not entity id)
echo "memo field id: {$record->getMemoEntryId('memo')}\n"; // returns entity id for memo field `memo`
echo "is record deleted: {$record->isDeleted('memo')}\n"; // returns whether record is deleted

// you can loop over fields in the record
foreach ($record as $fieldName => $fieldValue) {
    echo "$fieldName = $fieldValue\n";
}

Writing data to record

require_once 'vendor/autoload.php'

use org\majkel\dbase\Table;

$dbf = Table::fromFile('some/table.dbf');

// fetch first record
$record = $dbf[0];

$record->number  = 123;
$record->boolean = true;
$record->date    = new DateTime();
$record->text    = 'some text';
$record->memo    = 'some longer text';

// ... or ...

$record['number']  = 123;
$record['boolean'] = true;
$record['date']    = new DateTime();
$record['text']    = 'some text';
$record['memo']    = 'some longer text';

Updating tables

Note that update operation is not atomic. Use transactions to achieve integrity safety.

require_once 'vendor/autoload.php'

use org\majkel\dbase\Table;

$dbf = Table::fromFile('some/table.dbf');

foreach ($dbf as $record) {
    $record->int_val += 10;
    $dbf->update($record); // header is updated everytime
}

Deleting records

Do not use Record::setDeleted to delete records

require_once 'vendor/autoload.php'

use org\majkel\dbase\Table;

$dbf = Table::fromFile('some/table.dbf');

// delete 7th record
$dbf->delete(6);

// undelete 6th record
$dbf->markDelete(5, false);

Transactions

Transactions can prevent two processes from updating the same file.

When some process cannot acquire lock on the table exception is being thrown.

Transactions can also save you from unnecessary header updates. Header is updated at the end of transaction.

require_once 'vendor/autoload.php'

use org\majkel\dbase\Table;

$dbf = Table::fromFile('some/table.dbf');

// header is updated. Transaction flag is set
$dbf->beginTransaction();

foreach ($dbf as $record) {
    $record->int_val += 10;
    $dbf->update($record);  // header is not written
}

// duplicate last row
$dbf->insert($record); // header is not written

// header is written, transaction flag is cleared, recond count is updated
$dbf->endTransaction();

Defining tables

To construct new table use builder object.

require_once 'vendor/autoload.php'

use org\majkel\dbase\Builder;
use org\majkel\dbase\Format;
use org\majkel\dbase\Field;

$table = Builder::create()
    ->setFormatType(Format::DBASE3)
    ->addField(Field::create(Field::TYPE_CHARACTER)->setName('str')->setLength(15))
    ->addField(Field::create(Field::TYPE_LOGICAL)->setName('bool'))
    ->addField(Field::create(Field::TYPE_NUMERIC)->setName('num'))
    ->build('destination.dbf');

for ($i = 1; $i <= 3; ++$i) {
    $table->insert([
        'str' => "Str $i",
        'bool' => false,
        'num' => $i,
    ]);
}

Creating table from another table

You can create new table form existing table definition.

require_once 'vendor/autoload.php'

use org\majkel\dbase\Builder;
use org\majkel\dbase\Format;
use org\majkel\dbase\Field;

$table = Builder::fromFile('source.dbf')
    ->setFormatType(Format::DBASE3)
    ->addField(Field::create(Field::TYPE_NUMERIC)->setName('newField1'))
    ->build('destination.dbf');

for ($i = 1; $i <= 3; ++$i) {
    $table->insert([
        'oldField1' => "Str $i",
        'oldField2' => false,
        'newField1' => $i,
    ]);
}

Filters

Although values are automatically converted based on column type sometimes it is necessary to perform additional processing. To achieve that you can add filters on columns.

Using filters

require_once 'vendor/autoload.php'

use org\majkel\dbase\Builder;
use org\majkel\dbase\filter\TrimFilter;
use your\CurrencyFilter;

$dbf = Table::fromFile('some/table.dbf');
$dbf->getHeader()->getField('price')
    ->addFilter(new TrimFilter())
    ->addFilter(new CurrencyFilter(',', '.'));

foreach ($dbf as $record) {
    // ...
}

Filters are applied during loading in the order they are defined. During serialization filters are applied in reversed order.

Writing custom filter

require_once 'vendor/autoload.php'

use org\majkel\dbase\FilterInterface;
use org\majkel\dbase\Field;

class CurrencyFilter extends FilterInterface
{
    /** @var string */
    private $inputDot;
    /** @var string */
    private $outputDot;

    /**
     * @param string $inputDot
     * @param string $outputDot
     */
    public function __construct($inputDot, $outputDot)
    {
        $this->inputDot = $inputDot;
        $this->outputDot = $outputDot;
    }

    /**
     * From table value to PHP value
     *
     * @param mixed $value
     * @return mixed
     */
    public function toValue($value)
    {
        return str_replace($this->inputDot, $this->outputDot, $value);
    }

    /**
     * From PHP value to table value
     *
     * @param mixed $value
     * @return mixed
     */
    public function fromValue($value)
    {
        return str_replace($this->outputDot, $this->inputDot, $value);
    }

    /**
     * Filter can be applied on string like columns
     *
     * @param integer $type
     * @return boolean
     */
    public function supportsType($type)
    {
        return in_aray($type, [Field::TYPE_CHARACTER, Field::TYPE_MEMO]);
    }
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].