{"id":21731633,"url":"https://github.com/mattboyer/sqbrite","last_synced_at":"2025-04-13T00:30:23.932Z","repository":{"id":20452959,"uuid":"88426247","full_name":"mattboyer/sqbrite","owner":"mattboyer","description":"SQBrite is a data recovery tool for SQLite databases","archived":false,"fork":false,"pushed_at":"2022-03-20T10:54:50.000Z","size":83,"stargazers_count":39,"open_issues_count":4,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-04-29T04:04:23.144Z","etag":null,"topics":["databases","forensics","ios","recovery","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Python","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/mattboyer.png","metadata":{"files":{"readme":"README.rst","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}},"created_at":"2017-04-16T16:03:39.000Z","updated_at":"2024-04-12T09:16:34.000Z","dependencies_parsed_at":"2022-07-26T06:47:03.728Z","dependency_job_id":null,"html_url":"https://github.com/mattboyer/sqbrite","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattboyer%2Fsqbrite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattboyer%2Fsqbrite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattboyer%2Fsqbrite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattboyer%2Fsqbrite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattboyer","download_url":"https://codeload.github.com/mattboyer/sqbrite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650591,"owners_count":21139670,"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":["databases","forensics","ios","recovery","sqlite"],"created_at":"2024-11-26T04:26:53.711Z","updated_at":"2025-04-13T00:30:23.911Z","avatar_url":"https://github.com/mattboyer.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Bring the shine back into your database with SQBrite!\n=====================================================\n\n.. image:: https://app.travis-ci.com/mattboyer/sqbrite.svg?branch=master\n    :target: https://app.travis-ci.com/mattboyer/sqbrite\n    :alt: Continuous Integration status\n\n.. image:: https://scrutinizer-ci.com/g/mattboyer/sqbrite/badges/quality-score.png?b=master\n    :target: https://scrutinizer-ci.com/g/mattboyer/sqbrite/?branch=master\n    :alt: Scrutinizer Code Quality\n\n.. image:: https://img.shields.io/pypi/v/sqbrite.svg\n    :target: https://pypi.python.org/pypi/sqbrite/\n    :alt: Latest Version\n\n.. image:: https://img.shields.io/pypi/format/sqbrite.svg\n    :target: https://pypi.python.org/pypi/sqbrite/\n    :alt: Download format\n\n.. image:: https://img.shields.io/pypi/pyversions/sqbrite.svg\n    :target: https://pypi.python.org/pypi/sqbrite/\n    :alt: Supported Python versions\n\nSQBrite is a data recovery/forensics tool for `SQLite \u003chttps://www.sqlite.org/\u003e`_ databases. It uses a Python 3 implementation of the `SQLite on-disk file format \u003chttps://www.sqlite.org/fileformat2.html\u003e`_ to recover deleted table rows.\n\nSQBrite's name is inspired by `PL Daniels' \u003chttps://github.com/inflex\u003e`_ `undark \u003chttp://pldaniels.com/undark/\u003e`_, but is a completely separate implementation.\n\n.. image:: https://asciinema.org/a/118939.png\n    :target: https://asciinema.org/a/118939\n    :alt: SQBrite demo terminal recording\n\nInstalling SQBrite\n------------------\n\nSQBrite requires Python 3. To install, simply run:\n\n.. code-block:: bash\n\n    $ pip3 install --user sqbrite\n    $ sqbrite --help\n\nBackground\n----------\n\nSQLite uses a paginated data model in which each database is a collection of same-size *pages*. There are several kinds of pages, of which one type (B-Tree Table Leaf pages) contains the starting point for actual data belonging to individual table rows.\n\nWhen a row is deleted by means of a ``DELETE FROM table (...)`` statement, the space occupied by that row's data (a *record*) within the relevant B-Tree Table Leaf page is marked as free and may subsequently be used to store new records or update existing records. However, it is common to see freed space within a page (a *freeblock*, in SQLite parlance) left alone after rows are deleted. In that case, it ***may*** be possible to retrieve deleted row data from within the freeblock.\n\nHeuristics\n++++++++++\n\nThe SQLite file format doesn't keep track of where deleted records start and end within a leaf page's freeblocks. This means that SQBrite needs a mechanism to find out where record headers start. This is achieved through the use of byte-wise regular expressions specific to tables in known databases. These regular expressions and the offset that separates matches from the first byte in a well-formed header are stored in a user-editable YAML file.\n\nSQBrite aims to ship with heuristics for popular SQLite databases, so **do** send pull requests if you've got good results with your heuristics.\n\nFeatures\n--------\n\n- Export all records to CSV or reinject \"undeleted\" records into a copy of the database\n- Extensible heuristics - just add entries to ``~/.local/share/sqbrite/sqbrite.yaml``!\n- SQBrite can recover records from within active B-tree table leaf pages or from former table-leaf Freelist pages.\n- Heuristics for iOS and Firefox databases\n\nLimitations\n-----------\n\n- SQBrite works better when ``ptrmap`` pages are present\n- The ``undelete`` subcommand may fail when re-inserting deleted rows into a table causes a constraint violation\n- SQBrite cannot recover records deleted with the `SQLite secure_delete pragma \u003chttps://www.sqlite.org/pragma.html#pragma_secure_delete\u003e`_ enabled\n- Recovering data from overflow pages that have become Freelist leaf pages is not currently supported\n\n\nAcknowledgments\n---------------\n\nBig thanks to `@tobraha \u003chttps://github.com/tobraha\u003e`_ for contributing bugfixes in 2022.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattboyer%2Fsqbrite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattboyer%2Fsqbrite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattboyer%2Fsqbrite/lists"}