# Introduction to Rparadox

## Introduction

The Rparadox package provides tools to read data from Paradox database files (`.db`) directly into R. This vignette will walk you through the basic and advanced usage of the package, including handling encrypted files and legacy encodings.

## Installation

    # stable version from CRAN
    install.packages("Rparadox")

You can install the development version from GitHub:

    # install.packages("devtools")
    devtools::install_github("celebithil/Rparadox")

## Basic Usage with `read_paradox()`

The simplest way to read a Paradox file is with the `read_paradox()` wrapper function. It handles the entire workflow of opening the file, reading the data, and closing the connection for you.

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

    # Read the data in a single step
    biolife_data <- read_paradox(db_path)

    # Display the first few rows of the resulting tibble
    head(biolife_data)
    #> # A tibble: 6 × 8
    #>   `Species No` Category Common_Name `Species Name` `Length (cm)` Length_In Notes
    #>          <dbl> <chr>    <chr>       <chr>                  <dbl>     <dbl> <chr>
    #> 1        90020 Trigger… Clown Trig… Ballistoides …            50      19.7 "Als…
    #> 2        90030 Snapper  Red Emperor Lutjanus sebae            60      23.6 "Cal…
    #> 3        90050 Wrasse   Giant Maor… Cheilinus und…           229      90.2 "Thi…
    #> 4        90070 Angelfi… Blue Angel… Pomacanthus n…            30      11.8 "Hab…
    #> 5        90080 Cod      Lunartail … Variola louti             80      31.5 "Als…
    #> 6        90090 Scorpio… Firefish    Pterois volit…            38      15.0 "Als…
    #> # ℹ 1 more variable: Graphic <blob>

## Reading Encrypted Files

Rparadox supports reading password-protected `.db` files. To read such a file, provide the `password` argument to `read_paradox()`.

    # Example for an encrypted file
    db_path <- "path/to/encrypted_file.db"
    my_data <- read_paradox(db_path, password = "my_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` argument.

    # Example for a file known to be in the CP866 encoding
    my_data <- read_paradox("path/to/your/file.db", encoding = "cp866")

This ensures that text is correctly converted to UTF-8 using the `stringi` library.

## Advanced Usage: Metadata and Manual Control

If you need more control, for instance, to check a file’s 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.

    # This chunk uses the db_path defined in the previous chunk
    # Open the file handle
    pxdoc <- pxlib_open_file(db_path)

    if (!is.null(pxdoc)) {
      # Get and print metadata
      # This is fast and doesn't read the full table content
      metadata <- pxlib_metadata(pxdoc)

      cat("Records:", metadata$num_records, "\n")
      cat("Encoding:", metadata$encoding, "\n")

      # Inspect field definitions (names, types, sizes)
      print(head(metadata$fields))

      # Read the data
      # Note: If using pxlib_get_data directly with encrypted files,
      # ensure you have set the password via appropriate C-calls or use read_paradox() wrapper.
      data <- pxlib_get_data(pxdoc)

      # Close the file handle
      pxlib_close_file(pxdoc)

      head(data)
    }
    #> Records: 28
    #> Encoding: CP437
    #>           name   type size
    #> 1   Species No Number    8
    #> 2     Category  Alpha   15
    #> 3  Common_Name  Alpha   30
    #> 4 Species Name  Alpha   40
    #> 5  Length (cm) Number    8
    #> 6    Length_In Number    8
    #> # A tibble: 6 × 8
    #>   `Species No` Category Common_Name `Species Name` `Length (cm)` Length_In Notes
    #>          <dbl> <chr>    <chr>       <chr>                  <dbl>     <dbl> <chr>
    #> 1        90020 Trigger… Clown Trig… Ballistoides …            50      19.7 "Als…
    #> 2        90030 Snapper  Red Emperor Lutjanus sebae            60      23.6 "Cal…
    #> 3        90050 Wrasse   Giant Maor… Cheilinus und…           229      90.2 "Thi…
    #> 4        90070 Angelfi… Blue Angel… Pomacanthus n…            30      11.8 "Hab…
    #> 5        90080 Cod      Lunartail … Variola louti             80      31.5 "Als…
    #> 6        90090 Scorpio… Firefish    Pterois volit…            38      15.0 "Als…
    #> # ℹ 1 more variable: Graphic <blob>