---
title: "Introduction to Rparadox"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Introduction to Rparadox}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(Rparadox)
```

## Introduction

**Rparadox** provides a simple and efficient way to read data from Paradox
database files (`.db`) directly into R as modern `tibble` data frames. It uses
the underlying `pxlib` C library to handle the low-level file format details and
provides a clean, user-friendly R interface.

This package is designed to "just work" for the most common use case:
extracting the full dataset from a Paradox table, including its associated
BLOB/memo file (`.mb`).

### Features

- **Direct Reading:** Reads Paradox `.db` files without needing database
  drivers or external software.
- **Tibble Output:** Returns data in the `tibble` format, fully compatible with
  the Tidyverse ecosystem.
- **Automatic BLOB Handling:** Automatically detects, attaches, and reads data
  from associated memo/BLOB (`.mb`) files.
- **Encryption Support:** Supports reading password-protected Paradox files.
- **Character Encoding Control:** Automatically handles character encoding
  conversion to UTF-8 and allows manual override of the source encoding for
  files with incorrect headers.
- **Type Conversion:** Correctly maps Paradox data types to their corresponding
  R types, including `Date`, `Time` (`hms`), `Timestamp` (`POSIXct`),
  `Logical`, `Integer`, `Numeric`, and binary `blob` objects.

## Installation

```{r, eval=FALSE}
# stable version from CRAN
install.packages("Rparadox")
```

You can install the development version from GitHub:

```{r, eval=FALSE}
# install.packages("devtools")
devtools::install_github("celebithil/Rparadox")
```

## Basic Usage: `read_paradox()`

The easiest way to read a Paradox file is with the high-level
`read_paradox()` function. It handles opening the file, reading the data,
and closing the connection in a single step.

```{r basic-example}
# Get the path to an example database included with the package
db_path <- system.file("extdata", "biolife.db", package = "Rparadox")

# Read the data directly into a tibble
# This automatically finds 'biolife.mb' and handles data types.
biolife_data <- read_paradox(db_path)

# View the data
print(biolife_data)
```

```{r magick-plot, eval = requireNamespace("magick", quietly = TRUE)}
# Plot raw image data
library(magick)

as.raw(biolife_data$Graphic[[1]]) |> image_read() |> plot()
```

## Reading Encrypted Files

If your Paradox file is password-protected, provide the password using the
`password` argument:

```{r, eval=FALSE}
library(Rparadox)
# Read a password-protected file
secure_data <- read_paradox("path/to/encrypted.db", password = "secret_password")
```

If the file is encrypted and no password (or an incorrect one) is provided,
the function will stop with an error message.

## Handling Character Encodings

For legacy files with incorrect encoding information in the header, you can
specify the correct encoding manually with the `encoding` parameter:

```{r, eval=FALSE}
library(Rparadox)
# This tells the package to interpret the source data as CP866
data <- read_paradox("path/to/your/file.db", encoding = "cp866")
```

This ensures that all text fields are correctly converted to UTF-8 in the
final `tibble`.

## Advanced Usage: Metadata and Manual Control

If you need more control — for instance, to inspect metadata before committing
to reading a large dataset — you can use the lower-level functions.

The workflow is:

1. `pxlib_open_file()` to get a file handle.
2. `pxlib_metadata()` to inspect metadata (optional).
3. `pxlib_get_data()` to read the data.
4. `pxlib_close_file()` to release the connection.

```{r advanced-example}
db_path <- system.file("extdata", "biolife.db", package = "Rparadox")

# Open the file and get a handle
pxdoc <- pxlib_open_file(db_path)

if (!is.null(pxdoc)) {
  # Get metadata without reading all the data
  metadata <- pxlib_metadata(pxdoc)

  # Metadata includes human-readable field types and detected encoding
  cat("Encoding:", metadata$encoding, "\n")
  cat("Number of records:", metadata$num_records, "\n")
  print(head(metadata$fields))

  # Read the actual data
  data_table <- pxlib_get_data(pxdoc)

  # Always close the file when you're done
  pxlib_close_file(pxdoc)

  print(data_table)
}
```

## Links

- pxlib C library: <https://github.com/steinm/pxlib>
- CRAN page: <https://cran.r-project.org/package=Rparadox>
- Bug reports: <https://github.com/celebithil/Rparadox/issues>
