{"id":26600763,"url":"https://github.com/bontavlad/nimdrake","last_synced_at":"2025-06-11T00:34:53.125Z","repository":{"id":267787584,"uuid":"902343962","full_name":"BontaVlad/NimDrake","owner":"BontaVlad","description":"Nim wrapper for the DuckDB high-performance analytical database system","archived":false,"fork":false,"pushed_at":"2025-03-30T12:50:59.000Z","size":17542,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T16:44:18.978Z","etag":null,"topics":["data-visualization","database","duckdb","nim-lang"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BontaVlad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-12T11:38:47.000Z","updated_at":"2025-03-30T13:02:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"d0a07e37-d116-4573-a455-31afc8addee6","html_url":"https://github.com/BontaVlad/NimDrake","commit_stats":null,"previous_names":["bontavlad/nimdrake"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BontaVlad%2FNimDrake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BontaVlad%2FNimDrake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BontaVlad%2FNimDrake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BontaVlad%2FNimDrake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BontaVlad","download_url":"https://codeload.github.com/BontaVlad/NimDrake/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BontaVlad%2FNimDrake/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259176283,"owners_count":22817158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-visualization","database","duckdb","nim-lang"],"created_at":"2025-03-23T18:34:54.556Z","updated_at":"2025-06-11T00:34:53.108Z","avatar_url":"https://github.com/BontaVlad.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"drake-svg-light-theme.svg\"\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"drake-svg-dark-theme.svg\"\u003e\n    \u003cimg alt=\"NimDrake logo\" src=\"drake-svg-light-theme.svg\" height=\"200\"\u003e\n  \u003c/picture\u003e\n  \u003cbr\u003e\n  \u003cimg src=\"https://github.com/BontaVlad/NimDrake/actions/workflows/tests.yml/badge.svg\" alt=\"MainBranch\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/unstable-pre_alpha-blue\" alt=\"Status\"\u003e\n\u003c/div\u003e\n\u003cbr\u003e\n\n## NimDrake\n\nNimDrake is a [Nim](https://nim-lang.org/) language package designed to integrate with [DuckDB](https://duckdb.org/), an in-process SQL OLAP database management system. It simplifies database interactions while maintaining flexibility for advanced use cases. NimDrake is built with two ideas in mind, the high-level interface offers quick and easy database operations, ideal for rapid development and simplicity,\nand a lower-level interface that directly interacts with DuckDB's core functionalities, enabling complex or high-performance implementations when necessary.\nThis dual-layer approach ensures that NimDrake caters to both beginners and advanced users.\n\n**Please note:** NimDrake is currently in a pre-alpha stage and is considered experimental. It contains bugs and lacks some intended features. Use with caution and report any issues you encounter.\n\n---\n\n## Installation\n\nHere should be the nimble installtion when this code is ok to be published, but \nit should contain also the manual way\n\n1. Clone this repository to your local machine:\n   ```bash\n   git clone https://github.com/foo/bar\n   ```\n\n2. Navigate to the repository folder:\n   ```bash\n   nimble install NimDrake\n   ```\n\n\n## Full Documentation\nFor a full documentation and API index go [here](http://bontavlad.com/NimDrake/)\n\n## Code Examples\n\nHere are a few simple examples of how to use this repository:\n\n### Example 1: Simple query\n```nim\nimport nimdrake\n\nlet duck = newDatabase().connect()\n\necho duck.execute(\"SELECT * FROM range(100) AS example;\")\n\n# Environment Variables for Controlling Dataframe Display Options\n# - **display_show_index** (True/False): Determines whether to show or hide row index columns. Set `True` to display indexes, `False` to hide them.  \n# - **display_max_rows**: Specifies the maximum number of rows displayed in a dataframe output.\n# - **display_max_columns** (Default 100): Restricts the maximum number of columns to be shown at once to prevent overwhelming displays; set to `100` as default.\n# - **display_clip_column_name**: Limits the length of column names displayed, which can help in keeping outputs clean when dealing with long-named columns. Set it to `20`.\n\n# output:\n# ┌───────┬───────────────┐\n# │  #    │     range     │\n# ├───────┼───────────────┤\n# │  0    │     0         │\n# │  1    │     1         │\n# │  2    │     2         │\n# │  3    │     3         │\n# │  4    │     4         │\n# │  ...  │     ...       │\n# │  95   │     95        │\n# │  96   │     96        │\n# │  97   │     97        │\n# │  98   │     98        │\n# │  99   │     99        │\n# └───────┴───────────────┘\n\n```\n\n### Example 2: Access query results using the Vector Interface.\n```nim\nlet duck = newDatabase().connect()\n\nlet outcome = duck.execute(\"\"\" SELECT seq AS int_col, 'Value_' || seq::VARCHAR AS varchar_col FROM generate_series(1,3) AS t(seq) \"\"\").fetchAll()\necho outcome[0].valueBigint # -\u003e @[1, 2, 3]\necho outcome[1].valueVarchar # -\u003e @[\"Value_1\", \"Value_2\", \"Value_3\"]\n\n# we can also access by column name\n\nlet outcome = duck.execute(\"\"\" SELECT seq AS int_col, 'Value_' || seq::VARCHAR AS varchar_col FROM generate_series(1,3) AS t(seq) \"\"\").fetchAllNamed()\necho outcome[\"int_col\"].valueBigint # -\u003e @[1, 2, 3]\necho outcome[\"varchar_col\"].valueVarchar # -\u003e @[\"Value_1\", \"Value_2\", \"Value_3\"]\n\n```\n\n### Example 3: Using the row iterator interface\n```nim\nlet duck = newDatabase().connect()\n\nlet task = duck.execute(\"\"\" SELECT seq AS int_col, 'Value_' || seq::VARCHAR AS varchar_col FROM generate_series(1,3) AS t(seq) \"\"\")\nfor i, row in enumerate(task.rows):\n  echo fmt\"row {i}: ({row[0]}, {row[1]})\"\n  \n#output:\n# row 0: (1, Value_1)\n# row 1: (2, Value_2)\n# row 2: (3, Value_3)\n```\n\n### Example 4: Using the dataframe\n```nim\nlet \n  # we can also start a session with custom config flags\n  config = newConfig({\"threads\": \"3\"}.toTable)\n  duck = newDatabase().connect(config)\n\nlet df = newDataFrame(\n  {\n    \"foo\": newVector(@[10, 30, 20]),\n    \"bar\": newVector(@[\"a\", \"b\", \"c\"])\n  }.toTable)\nduck.register(\"df\", df)\necho duck.execute(\"SELECT * FROM df ORDER BY foo;\")\n  \n#output:\n# ┌─────┬─────────────┬─────────────┐\n# │  #  │     bar     │     foo     │\n# ├─────┼─────────────┼─────────────┤\n# │  0  │     a       │     10      │\n# │  1  │     c       │     20      │\n# │  2  │     b       │     30      │\n# └─────┴─────────────┴─────────────┘\n```\n\n### Example 5: Insert with prepared statement\n\n```nim\nlet duck = newDatabase().connect()\nduck.execute(\n    \"\"\"\n    CREATE TABLE prepared_table (\n        bool_val BOOLEAN,\n        int32_val INTEGER,\n        float64_val DOUBLE,\n        string_val VARCHAR,\n    );\n    \"\"\"\n)\n\nlet prepared = duck.newStatement(\"INSERT INTO prepared_table VALUES (?, ?, ?, ?);\")\nduck.execute(prepared, (true, -2147483648'i32, 3.14159265359'f64, \"hello\"))\necho duck.execute(\"SELECT * FROM prepared_table;\")\n\n# output:\n# ┌─────┬──────────────────┬────────────────────┬─────────────────────┬───────────────────────┐\n# │  #  │     bool_val     │     string_val     │     int32_val       │     float64_val       │\n# ├─────┼──────────────────┼────────────────────┼─────────────────────┼───────────────────────┤\n# │  0  │     true         │     hello          │     -2147483648     │     3.14159265359     │\n# └─────┴──────────────────┴────────────────────┴─────────────────────┴───────────────────────┘\n\n```\n\n### Example 6: Using UDF(user defined functions)\n\n```nim\nlet duck = newDatabase().connect()\n\ntemplate powerTo(val, bar: int64): int64 {.scalar.} =\n  result = val * bar\n\nduck.register(powerTo)\n\nduck.execute(\"CREATE TABLE test_table AS SELECT i FROM range(3, 9) t(i);\")\necho duck.execute(\"SELECT i, powerTo(i, i) as powerTo FROM test_table\")\n\n# output:\n# ┌─────┬─────────────────┬───────────┐\n# │  #  │     powerTo     │     i     │\n# ├─────┼─────────────────┼───────────┤\n# │  0  │     9           │     3     │\n# │  1  │     16          │     4     │\n# │  2  │     25          │     5     │\n# │  3  │     36          │     6     │\n# │  4  │     49          │     7     │\n# │  5  │     64          │     8     │\n# └─────┴─────────────────┴───────────┘\n```\n\n### Example 7: Using UDF as table generators\n\n```nim\n\nlet duck = newDatabase().connect()\n\niterator countToN(count: int): int {.producer, closure.} =\n    for i in 0 ..\u003c count:\n      yield i\n\niterator progress(count: int, sigil: string): string {.producer, closure.} =\n    var output = \"\"\n    for _ in 0 ..\u003c count:\n      output \u0026= sigil\n      yield output\n\niterator floatCounter(): float {.producer, closure.} =\n    var counter = 0.0\n    while true:\n      yield counter\n      counter += 1.0\n\nduck.register(floatCounter)\n\nduck.register(progress)\n\nduck.register(countToN)\n\necho duck.execute(\"SELECT * FROM countToN(3)\")\necho duck.execute(\"SELECT * FROM progress(5, '#')\")\necho duck.execute(\"SELECT * FROM floatCounter() LIMIT 5;\")\n\n# output:\n# ┌─────┬──────────────────┐\n# │  #  │     countToN     │\n# ├─────┼──────────────────┤\n# │  0  │     0            │\n# │  1  │     1            │\n# │  2  │     2            │\n# └─────┴──────────────────┘\n# \n# ┌─────┬──────────────────┐\n# │  #  │     progress     │\n# ├─────┼──────────────────┤\n# │  0  │     #            │\n# │  1  │     ##           │\n# │  2  │     ###          │\n# │  3  │     ####         │\n# │  4  │     #####        │\n# └─────┴──────────────────┘\n# \n# ┌─────┬──────────────────────┐\n# │  #  │     floatCounter     │\n# ├─────┼──────────────────────┤\n# │  0  │     0.0              │\n# │  1  │     1.0              │\n# │  2  │     2.0              │\n# │  3  │     3.0              │\n# │  4  │     4.0              │\n# └─────┴──────────────────────┘\n```\n## DuckDB to Nim Type Mapping\n\n| **DuckType**         | **Nim Equivalent**           |\n|-----------------------|------------------------------|\n| `Invalid`            | `uint8`                     |\n| `ANY`                | `uint8`                     |\n| `VARINT`             | `uint8`                     |\n| `SQLNULL`            | `uint8`                     |\n| `Boolean`            | `bool`                      |\n| `TinyInt`            | `int8`                      |\n| `SmallInt`           | `int16`                     |\n| `Integer`            | `int32`                     |\n| `BigInt`             | `int64`                     |\n| `UTinyInt`           | `uint8`                     |\n| `USmallInt`          | `uint16`                    |\n| `UInteger`           | `uint32`                    |\n| `UBigInt`            | `uint64`                    |\n| `Float`              | `float32`                   |\n| `Double`             | `float64`                   |\n| `Timestamp`          | `DateTime`                  |\n| `Date`               | `DateTime`                  |\n| `Time`               | `Time`                      |\n| `Interval`           | `TimeInterval`              |\n| `HugeInt`            | `Int128`                    |\n| `Varchar`            | `string`                    |\n| `Blob`               | `seq[byte]`                 |\n| `Decimal`            | `DecimalType`               |\n| `TimestampS`         | `DateTime`                  |\n| `TimestampMs`        | `DateTime`                  |\n| `TimestampNs`        | `DateTime`                  |\n| `Enum`               | `uint`                      |\n| `List`               | `seq[Value]`                |\n| `Struct`             | `Table[string, Value]`      |\n| `Map`                | `Table[string, Value]`      |\n| `UUID`               | `Uuid`                      |\n| `Union`              | `Table[string, Value]`      |\n| `Bit`                | `string`                    |\n| `TimeTz`             | `ZonedTime`                 |\n\n---\n\n## Contribution\n\nTalk about justfiles and the commands\n\n---\n\n## Acknowledgments\n\n# Acknowledgements\n\nThis project relies on several Nim packages:\n\n- [Nim](https://nim-lang.org/) (version 2.0.0 or higher)\n- [futhark](https://github.com/arnetheduck/nim-futhark)\n- [nint128](https://github.com/cheatfate/nim-nint128)\n- [decimal](https://github.com/ba0f3/decimal) (version 0.0.2 or higher)\n- [terminaltables](https://github.com/ThomasTJdev/nim-terminaltables) (version 0.1.1 or higher)\n- [uuid4](https://github.com/krux02/uuid4) (version 0.9.3 or higher)\n\nA special thanks to:\n\n- A lot of code ported from [Duckdb Julia](https://duckdb.org/docs/api/julia.html)\n- Futhark was a life saver\n\nFeel free to fork, contribute, and share this repository. \n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbontavlad%2Fnimdrake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbontavlad%2Fnimdrake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbontavlad%2Fnimdrake/lists"}