<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mukhtar</title>
    <description>The latest articles on Forem by Mukhtar (@mukhtar_onif).</description>
    <link>https://forem.com/mukhtar_onif</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F595040%2F8151d7ee-efb8-44be-adbf-e2bb1bc1d460.JPG</url>
      <title>Forem: Mukhtar</title>
      <link>https://forem.com/mukhtar_onif</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mukhtar_onif"/>
    <language>en</language>
    <item>
      <title>Audit Your File System with Surveilr: A Practical Guide</title>
      <dc:creator>Mukhtar</dc:creator>
      <pubDate>Thu, 14 May 2026 20:57:43 +0000</pubDate>
      <link>https://forem.com/mukhtar_onif/audit-your-file-system-with-surveilr-a-practical-guide-140k</link>
      <guid>https://forem.com/mukhtar_onif/audit-your-file-system-with-surveilr-a-practical-guide-140k</guid>
      <description>&lt;p&gt;&lt;em&gt;How to scan your file system and query files using SQL&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; In this guide, you'll learn how to use surveilr to scan directories, capture file metadata in a SQLite database, and query for files using SQL—find PDFs, track document changes, and audit file system activity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt; &lt;a href="https://github.com/surveilr/packages#installation" rel="noopener noreferrer"&gt;surveilr installed&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Finding Files is Hard
&lt;/h2&gt;

&lt;p&gt;If you've ever needed to track files across your system for compliance audits or project management, you know the pain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scattered files&lt;/strong&gt; — Documents, spreadsheets, and PDFs across multiple directories&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual searches&lt;/strong&gt; — Using &lt;code&gt;find&lt;/code&gt; and Finder/Explorer is tedious and limited&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No audit trail&lt;/strong&gt; — No record of what existed when&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Point-in-time only&lt;/strong&gt; — No way to track file changes over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What if you could turn your entire file system into a &lt;strong&gt;queryable SQL database&lt;/strong&gt; where you can find any file with SQL queries?&lt;/p&gt;

&lt;p&gt;That's exactly what &lt;strong&gt;surveilr&lt;/strong&gt; does.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is surveilr?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://surveilr.com" rel="noopener noreferrer"&gt;surveilr&lt;/a&gt; is an &lt;strong&gt;edge-based, SQL-first surveillance platform&lt;/strong&gt; that turns your file system into a &lt;strong&gt;Resource Surveillance State Database (RSSD)&lt;/strong&gt;—a SQLite database containing all your file metadata.&lt;/p&gt;

&lt;p&gt;Think of it as "Git for your entire file system's metadata" that you can query with SQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📂 Scans directories and captures file metadata (size, timestamps, hashes)&lt;/li&gt;
&lt;li&gt;🔍 Query files with SQL (no custom DSL to learn)&lt;/li&gt;
&lt;li&gt;🔄 Watch mode for continuous monitoring&lt;/li&gt;
&lt;li&gt;🔒 Works offline (edge-based, no cloud required)&lt;/li&gt;
&lt;li&gt;📊 Perfect for compliance audits (HIPAA, GDPR, SOC 2)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see it in action.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Create Your First RSSD
&lt;/h2&gt;

&lt;p&gt;Initialize a new surveillance database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;surveilr admin init &lt;span class="nt"&gt;-d&lt;/span&gt; my-audit.db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What just happened?&lt;/strong&gt;&lt;br&gt;
surveilr created &lt;code&gt;my-audit.db&lt;/code&gt;—a SQLite database that will store all your file evidence. This is your &lt;strong&gt;Resource Surveillance State Database (RSSD)&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Pro tip:&lt;/strong&gt; The RSSD is a standard SQLite database. Once created, it's independent of surveilr and can be queried by any tool that supports SQLite.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Step 2: Ingest Files from a Directory
&lt;/h2&gt;

&lt;p&gt;Scan your Documents folder (or any directory):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Scan your Documents folder&lt;/span&gt;
surveilr ingest files &lt;span class="nt"&gt;-r&lt;/span&gt; ~/Documents &lt;span class="nt"&gt;-d&lt;/span&gt; my-audit.db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What's happening behind the scenes:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;surveilr walks the directory tree recursively&lt;/li&gt;
&lt;li&gt;Computes file hashes (SHA-256) for content tracking&lt;/li&gt;
&lt;li&gt;Captures metadata: size, timestamps, permissions, extensions&lt;/li&gt;
&lt;li&gt;Stores everything in SQLite tables&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 3: Find Sensitive Files with SQL
&lt;/h2&gt;

&lt;p&gt;Now comes the fun part. Open the interactive SQL shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;surveilr shell &lt;span class="nt"&gt;-d&lt;/span&gt; my-audit.db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; File metadata lives in two joined tables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;uniform_resource&lt;/code&gt; — Core resource metadata (hash, size, timestamps)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ur_ingest_session_fs_path_entry&lt;/code&gt; — File-specific metadata (path, name, extension)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Query 1: Find PDFs Modified Recently
&lt;/h3&gt;

&lt;p&gt;Find all PDF files modified in the last 30 days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_path_abs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_basename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size_bytes&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;size_kb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_modified_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;uniform_resource&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;ur_ingest_session_fs_path_entry&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniform_resource_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniform_resource_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_extn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'pdf'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_modified_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'now'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-30 days'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_modified_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/Users/you/Documents/report-2024.pdf    | report-2024.pdf    | 2048 | 2024-05-12
/Users/you/Projects/proposal.pdf        | proposal.pdf       | 3248 | 2024-05-10
/Users/you/Desktop/invoice-may.pdf      | invoice-may.pdf    | 512  | 2024-05-08
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query 2: Find All Excel Files
&lt;/h3&gt;

&lt;p&gt;Find all Excel spreadsheets across your system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_path_abs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_basename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size_bytes&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;size_kb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_modified_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;uniform_resource&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;ur_ingest_session_fs_path_entry&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniform_resource_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniform_resource_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_extn&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'xlsx'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'xls'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'csv'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_modified_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query 3: Find Word Documents by Name
&lt;/h3&gt;

&lt;p&gt;Search for documents by filename:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_path_abs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_basename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_modified_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;uniform_resource&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;ur_ingest_session_fs_path_entry&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniform_resource_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniform_resource_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_extn&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'docx'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'doc'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_basename&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%report%'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_modified_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Export Your Findings
&lt;/h2&gt;

&lt;p&gt;Export results as JSON for reports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;surveilr shell &lt;span class="nt"&gt;-d&lt;/span&gt; my-audit.db &lt;span class="nt"&gt;--cmd&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT e.file_path_abs, e.file_basename, u.size_bytes, u.last_modified_at
FROM uniform_resource u
JOIN ur_ingest_session_fs_path_entry e
  ON u.uniform_resource_id = e.uniform_resource_id
WHERE e.file_extn = 'pdf'
"&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; pdf-files-report.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Or save as a SQL file for reuse:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; find-pdfs.sql &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
SELECT e.file_path_abs, e.file_basename, u.size_bytes
FROM uniform_resource u
JOIN ur_ingest_session_fs_path_entry e
  ON u.uniform_resource_id = e.uniform_resource_id
WHERE e.file_extn = 'pdf'
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;surveilr shell &lt;span class="nt"&gt;-d&lt;/span&gt; my-audit.db find-pdfs.sql &lt;span class="nt"&gt;--output&lt;/span&gt; json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; pdfs.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Automate with Watch Mode
&lt;/h2&gt;

&lt;p&gt;Set up &lt;strong&gt;continuous monitoring&lt;/strong&gt; so surveilr automatically re-scans when files change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;surveilr ingest files &lt;span class="nt"&gt;-r&lt;/span&gt; ~/Documents &lt;span class="nt"&gt;-d&lt;/span&gt; my-audit.db &lt;span class="nt"&gt;--watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;surveilr monitors the directory for changes&lt;/li&gt;
&lt;li&gt;New or modified files are automatically ingested&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Ctrl+C&lt;/code&gt; to stop&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🏥 HIPAA Compliance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Track PHI locations&lt;/strong&gt; — Document where patient health information files are stored for GDPR/HIPAA audits.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌍 GDPR Data Governance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Map PII locations&lt;/strong&gt; — Track where personally identifiable information is stored across your organization.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚨 Incident Response
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Detect tampering&lt;/strong&gt; — Establish file baselines and detect unauthorized modifications during security incidents.&lt;/p&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; "Permission denied" errors when scanning&lt;br&gt;
&lt;strong&gt;Solution:&lt;/strong&gt; Run with appropriate permissions or scan a different directory&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; RSSD file getting too large&lt;br&gt;
&lt;strong&gt;Solution:&lt;/strong&gt; Use &lt;code&gt;--dry-run&lt;/code&gt; first to check file counts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;surveilr ingest files &lt;span class="nt"&gt;-r&lt;/span&gt; ~/Documents &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;You've just created your first compliance evidence database! Here's what to explore next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="//./02-email-compliance-tracking-medium.md"&gt;Email Compliance Tracking&lt;/a&gt;&lt;/strong&gt; — Track email communications via IMAP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="//./03-github-gitlab-jira-tracking-medium.md"&gt;GitHub/GitLab/Jira Tracking&lt;/a&gt;&lt;/strong&gt; — Project data with Singer taps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://surveilr.com/" rel="noopener noreferrer"&gt;surveilr.com&lt;/a&gt;&lt;/strong&gt; — Full documentation and advanced features&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://surveilr.com/" rel="noopener noreferrer"&gt;surveilr.com&lt;/a&gt;&lt;/strong&gt; — Official website and documentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/surveilr/packages#installation" rel="noopener noreferrer"&gt;Installation Guide&lt;/a&gt;&lt;/strong&gt; — Download and install surveilr&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;surveilr turns your file system into a queryable SQL database&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Standard SQLite = no vendor lock-in, works with any SQLite tool&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Perfect for compliance audits&lt;/strong&gt; (HIPAA, GDPR, SOC 2)&lt;br&gt;
✅ &lt;strong&gt;Continuous monitoring with watch mode&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;All data stays on your machine&lt;/strong&gt; (edge-based, no cloud required)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; A complete audit trail of your file system that you can query anytime&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found this helpful? Visit &lt;a href="https://surveilr.com/" rel="noopener noreferrer"&gt;surveilr.com&lt;/a&gt; to learn more! Have questions? Open an &lt;a href="https://github.com/surveilr/packages/issues" rel="noopener noreferrer"&gt;issue&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>database</category>
      <category>community</category>
      <category>developer</category>
    </item>
    <item>
      <title>Query Everything with SQL: The Ultimate Compliance and Security Toolkit</title>
      <dc:creator>Mukhtar</dc:creator>
      <pubDate>Wed, 13 May 2026 16:47:24 +0000</pubDate>
      <link>https://forem.com/mukhtar_onif/query-everything-with-sql-the-ultimate-compliance-and-security-toolkit-2ij0</link>
      <guid>https://forem.com/mukhtar_onif/query-everything-with-sql-the-ultimate-compliance-and-security-toolkit-2ij0</guid>
      <description>&lt;p&gt;&lt;em&gt;Three practical guides to turn your files, emails, and project data into queryable SQLite databases&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you've ever struggled with compliance audits (HIPAA, SOX, GDPR, SOC 2), security investigations, or e-discovery requests, you know the pain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data is everywhere&lt;/strong&gt; — Files on disks, emails in inboxes, issues in GitHub/Jira&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No unified view&lt;/strong&gt; — Each system has its own limited search interface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual exports&lt;/strong&gt; — Hours spent copying data into spreadsheets for auditors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No audit trail&lt;/strong&gt; — Can't prove what data existed at a specific time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Point-in-time only&lt;/strong&gt; — No historical tracking of changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What if you could &lt;strong&gt;turn all of this into queryable SQL databases&lt;/strong&gt; and ask questions like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Find all PDFs modified in the last 30 days&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'pdf'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;modified&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'now'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-30 days'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Show emails from vendors about invoices&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emails&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%vendor%'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%invoice%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Track all code changes for SOC 2 audit&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;commits&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'2024-01-01'&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's what &lt;a href="https://surveilr.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;surveilr&lt;/strong&gt;&lt;/a&gt; enables.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is surveilr?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://surveilr.com/" rel="noopener noreferrer"&gt;surveilr&lt;/a&gt; is an &lt;strong&gt;edge-based, SQL-first surveillance platform&lt;/strong&gt; that turns your files, emails, and external APIs into &lt;strong&gt;Resource Surveillance State Databases (RSSDs)&lt;/strong&gt;—SQLite databases you can query with standard SQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📂 &lt;strong&gt;File system scanning&lt;/strong&gt; — Turn directories into queryable metadata&lt;/li&gt;
&lt;li&gt;📧 &lt;strong&gt;Email ingestion&lt;/strong&gt; — Connect to Gmail/Outlook via IMAP&lt;/li&gt;
&lt;li&gt;🔌 &lt;strong&gt;Singer tap integration&lt;/strong&gt; — Extract data from 600+ sources (GitHub, Jira, Salesforce, etc.)&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Standard SQL&lt;/strong&gt; — No custom query language to learn&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Edge-based&lt;/strong&gt; — All data stays on your machine (no cloud required)&lt;/li&gt;
&lt;li&gt;⚖️ &lt;strong&gt;Compliance-ready&lt;/strong&gt; — Perfect for HIPAA, SOX, GDPR, SOC 2&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why SQLite?
&lt;/h3&gt;

&lt;p&gt;surveilr uses SQLite—the world's most deployed database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Zero dependencies&lt;/strong&gt; — No servers, no installation, no configuration&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;One file&lt;/strong&gt; — Your entire database is a single &lt;code&gt;.db&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Portable&lt;/strong&gt; — Works everywhere (macOS, Linux, Windows, mobile)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;No vendor lock-in&lt;/strong&gt; — Standard SQLite works with 1000s of tools&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Three Practical Guides
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Guide 1: Audit Your File System
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/mukhtar_onif/audit-your-file-system-with-surveilr-a-practical-guide-140k"&gt;Read the full guide →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learn how to scan your file system and query files with SQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perfect for:&lt;/strong&gt; Compliance audits, file tracking, document management&lt;/p&gt;




&lt;h3&gt;
  
  
  Guide 2: Email Compliance Tracking
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="//./02-email-compliance-tracking-medium.md"&gt;Read the full guide →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learn how to ingest Gmail/Outlook emails via IMAP and query them for compliance reporting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perfect for:&lt;/strong&gt; HIPAA compliance, SOX compliance, e-discovery, communication audits&lt;/p&gt;




&lt;h3&gt;
  
  
  Guide 3: GitHub/GitLab/Jira Tracking
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="//./03-github-gitlab-jira-tracking-medium.md"&gt;Read the full guide →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learn how to use Singer taps to extract project data and query it for SOC 2 and change management audits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perfect for:&lt;/strong&gt; SOC 2 audits, DevOps metrics, security tracking, audit trails&lt;/p&gt;




&lt;h2&gt;
  
  
  Which Guide Should You Start With?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security Professionals&lt;/strong&gt; → Start with &lt;a href="//./01-audit-sensitive-files-medium.md"&gt;Guide 1 - File Auditing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance Officers&lt;/strong&gt; → Start with &lt;a href="//./02-email-compliance-tracking-medium.md"&gt;Guide 2 - Email Tracking&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DevOps Teams&lt;/strong&gt; → Start with &lt;a href="//./03-github-gitlab-jira-tracking-medium.md"&gt;Guide 3 - Project Tracking&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why surveilr vs. Other Tools?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  vs. Commercial Compliance Platforms (Vanta, Drata, Secureframe)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;surveilr&lt;/th&gt;
&lt;th&gt;Commercial Tools&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Available&lt;/td&gt;
&lt;td&gt;$10,000-$50,000/year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data location&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your machine (edge)&lt;/td&gt;
&lt;td&gt;Their cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Query language&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Standard SQL&lt;/td&gt;
&lt;td&gt;Proprietary UIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unlimited (SQLite + Singer)&lt;/td&gt;
&lt;td&gt;Limited integrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vendor lock-in&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None (standard SQLite)&lt;/td&gt;
&lt;td&gt;Complete lock-in&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  vs. Custom Scripts
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;surveilr&lt;/th&gt;
&lt;th&gt;Custom Scripts&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Minutes&lt;/td&gt;
&lt;td&gt;Days/weeks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Maintenance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;td&gt;Constant fixes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audit trail&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;td&gt;You build it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Query language&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SQL&lt;/td&gt;
&lt;td&gt;grep/awk/jq&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Historical tracking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;td&gt;You build it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  macOS / Linux
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap surveilr/tap &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;surveilr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;surveilr &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;Pick one of the three guides above and start querying your data with SQL.&lt;/p&gt;

&lt;p&gt;Each guide is self-contained and works independently—start with whichever solves your biggest problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Community &amp;amp; Support
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://surveilr.com/" rel="noopener noreferrer"&gt;surveilr.com&lt;/a&gt;&lt;/strong&gt; — Official website and documentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/surveilr/packages#installation" rel="noopener noreferrer"&gt;Installation Guide&lt;/a&gt;&lt;/strong&gt; — Download and install surveilr&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/surveilr/packages/issues" rel="noopener noreferrer"&gt;Report Issues&lt;/a&gt;&lt;/strong&gt; — Bug reports and feature requests&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Turn files, emails, and APIs into queryable SQL databases&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Perfect for HIPAA, SOX, GDPR, SOC 2 compliance&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Standard SQLite = no vendor lock-in&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Edge-based = your data never leaves your machine&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found this helpful? Visit &lt;a href="https://surveilr.com/" rel="noopener noreferrer"&gt;surveilr.com&lt;/a&gt; to learn more and share with your team!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>discuss</category>
      <category>database</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>Implementing OpenDAL with Filesystem (FS) In Rust</title>
      <dc:creator>Mukhtar</dc:creator>
      <pubDate>Sat, 19 Jul 2025 18:55:47 +0000</pubDate>
      <link>https://forem.com/mukhtar_onif/implementing-opendal-with-filesystem-fs-in-rust-2ha8</link>
      <guid>https://forem.com/mukhtar_onif/implementing-opendal-with-filesystem-fs-in-rust-2ha8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to OpenDAL with SQLite Virtual Tables
&lt;/h2&gt;

&lt;p&gt;OpenDAL is a powerful and unified data access layer that provides an abstraction for different storage backends such as local filesystems, cloud storage, and object stores. It simplifies file and metadata operations by offering a unified API, allowing seamless interaction with different storage solutions.&lt;/p&gt;

&lt;p&gt;This guide explains the &lt;strong&gt;concepts&lt;/strong&gt; behind integrating OpenDAL with SQLite virtual tables, allowing you to query filesystem metadata using SQL. The code examples demonstrate key concepts rather than complete implementations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Concepts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. OpenDAL Operator
&lt;/h3&gt;

&lt;p&gt;The foundation of any OpenDAL integration is the &lt;strong&gt;Operator&lt;/strong&gt; - your interface to the storage backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concept&lt;/strong&gt;: Create a configured operator for your storage type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Conceptual example - actual implementation needs error handling&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;fs_builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.root&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Operator&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fs_builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nf"&gt;.finish&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Ideas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The operator abstracts away storage-specific details&lt;/li&gt;
&lt;li&gt;Different services (Fs, S3, Azure, etc.) use the same Operator interface&lt;/li&gt;
&lt;li&gt;Configuration happens through service-specific builders&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. SQLite Virtual Table Architecture
&lt;/h3&gt;

&lt;p&gt;Virtual tables in SQLite allow you to present non-SQL data as queryable tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concept&lt;/strong&gt;: Bridge between OpenDAL and SQLite&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Conceptual structure - real implementation much more complex&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;FileSystemTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sqlite3_vtab&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// Required SQLite base&lt;/span&gt;
    &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Rc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Operator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// Your OpenDAL operator&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Ideas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Virtual tables implement a specific SQLite interface&lt;/li&gt;
&lt;li&gt;They translate SQL queries into storage operations&lt;/li&gt;
&lt;li&gt;The table schema defines what data is queryable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Schema Design
&lt;/h3&gt;

&lt;p&gt;Design your virtual table schema to expose useful file metadata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concept&lt;/strong&gt;: Map file attributes to SQL columns&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;filesystem_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                    &lt;span class="c1"&gt;-- File name&lt;/span&gt;
    &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                    &lt;span class="c1"&gt;-- Full path&lt;/span&gt;
    &lt;span class="n"&gt;last_modified&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;-- When file was changed&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="nb"&gt;BLOB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                 &lt;span class="c1"&gt;-- File contents (lazy-loaded)&lt;/span&gt;
    &lt;span class="k"&gt;size&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                 &lt;span class="c1"&gt;-- File size in bytes&lt;/span&gt;
    &lt;span class="n"&gt;content_type&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="c1"&gt;-- MIME type&lt;/span&gt;
    &lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                  &lt;span class="c1"&gt;-- File hash/checksum&lt;/span&gt;
    &lt;span class="n"&gt;arg_path&lt;/span&gt; &lt;span class="n"&gt;HIDDEN&lt;/span&gt;              &lt;span class="c1"&gt;-- Query parameter (hidden column)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Ideas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hidden columns can accept query parameters&lt;/li&gt;
&lt;li&gt;BLOB columns can hold binary data&lt;/li&gt;
&lt;li&gt;Schema should balance utility with performance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Query Translation Flow
&lt;/h3&gt;

&lt;p&gt;The magic happens in translating SQL queries into OpenDAL operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concept&lt;/strong&gt;: SQL WHERE clause becomes OpenDAL list operations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Conceptual flow - real implementation involves cursor management&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle_query_with_path_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FileMetadata&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Use OpenDAL to list files in the specified path&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;lister&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="nf"&gt;.lister_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.metakey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Metakey&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ContentLength&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Metakey&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LastModified&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Convert OpenDAL entries to your table format&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lister&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="nf"&gt;.metadata&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.mode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nn"&gt;EntryMode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;FILE&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;convert_to_table_row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;results&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Ideas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL filters become OpenDAL query parameters&lt;/li&gt;
&lt;li&gt;Metadata is fetched on-demand to avoid performance issues&lt;/li&gt;
&lt;li&gt;Results are converted to SQLite-compatible format&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Lazy Loading Strategy
&lt;/h3&gt;

&lt;p&gt;For performance, expensive operations (like reading file contents) should be lazy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concept&lt;/strong&gt;: Only load data when specifically requested&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Conceptual approach to lazy loading&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_column_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SqliteValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;SqliteValue&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.file_name&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;SqliteValue&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.file_path&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;SqliteValue&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.file_size&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Expensive operation - only do when column is requested&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.operator&lt;/span&gt;&lt;span class="nf"&gt;.read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nn"&gt;SqliteValue&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;SqliteValue&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Ideas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate metadata operations from content operations&lt;/li&gt;
&lt;li&gt;Use OpenDAL's &lt;code&gt;stat()&lt;/code&gt; for metadata, &lt;code&gt;read()&lt;/code&gt; for content&lt;/li&gt;
&lt;li&gt;Only perform expensive operations when columns are actually selected&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Error Handling Patterns
&lt;/h3&gt;

&lt;p&gt;Bridge OpenDAL errors to SQLite errors appropriately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concept&lt;/strong&gt;: Convert storage errors to SQL errors&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Conceptual error mapping&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;map_opendal_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OpenDalError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SqliteError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="nf"&gt;.kind&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;ErrorKind&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NotFound&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;SqliteError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nn"&gt;ErrorKind&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PermissionDenied&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;SqliteError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nn"&gt;ErrorKind&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Unexpected&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;SqliteError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Internal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;SqliteError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Internal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Ideas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenDAL errors need translation to SQLite error codes&lt;/li&gt;
&lt;li&gt;Some errors should be handled gracefully (missing files)&lt;/li&gt;
&lt;li&gt;Others should propagate up to the SQL layer&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Usage Patterns
&lt;/h2&gt;

&lt;p&gt;Once implemented, your virtual table enables powerful queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- List all files in a directory&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;size&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;filesystem_view&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;arg_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/documents'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Find large files&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;size&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;filesystem_view&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;arg_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/media'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Search by file type (if you implement content_type detection)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;filesystem_view&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;arg_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/projects'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'text/%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Benefits of This Approach
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why combine OpenDAL with SQLite virtual tables?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unified Query Interface&lt;/strong&gt;: Use SQL to query any storage backend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Same queries work across local files, S3, Azure, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration&lt;/strong&gt;: Easy to embed in existing SQLite-based applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: SQLite's query optimization benefits your file operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ecosystem&lt;/strong&gt;: Leverage SQLite's rich ecosystem of tools and extensions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;To implement this approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Study SQLite's virtual table interface documentation&lt;/li&gt;
&lt;li&gt;Explore OpenDAL's service implementations for your storage needs&lt;/li&gt;
&lt;li&gt;Design your schema based on your specific use cases&lt;/li&gt;
&lt;li&gt;Implement the virtual table interface with proper error handling&lt;/li&gt;
&lt;li&gt;Add performance optimizations like caching and pagination&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This pattern opens up powerful possibilities for unified data access across different storage systems while maintaining the familiar SQL interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide demonstrated how to use OpenDAL for filesystem operations in Rust and integrate it with SQLite virtual tables. By leveraging OpenDAL, you can seamlessly interact with local storage while maintaining a structured query interface via SQLite.&lt;/p&gt;

&lt;p&gt;For more details, check out &lt;a href="https://github.com/apache/opendal" rel="noopener noreferrer"&gt;OpenDAL's documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>opendal</category>
      <category>sqlite</category>
    </item>
    <item>
      <title>Getting Started with Rust in 2025: Why Now Is a Great Time to Learn Rust 🦀</title>
      <dc:creator>Mukhtar</dc:creator>
      <pubDate>Sun, 13 Jul 2025 20:48:12 +0000</pubDate>
      <link>https://forem.com/mukhtar_onif/getting-started-with-rust-in-2025-why-now-is-a-great-time-to-learn-rust-1d89</link>
      <guid>https://forem.com/mukhtar_onif/getting-started-with-rust-in-2025-why-now-is-a-great-time-to-learn-rust-1d89</guid>
      <description>&lt;h2&gt;
  
  
  Getting Started with Rust in 2025 🦀
&lt;/h2&gt;

&lt;p&gt;Rust has been growing steadily over the years, and in 2025, it's more relevant than ever. If you've been on the fence about learning it, now's the perfect time to jump in.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Why Learn Rust?
&lt;/h2&gt;

&lt;p&gt;Rust is a modern systems programming language focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; (like C/C++)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety&lt;/strong&gt; (no nulls, no data races)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern developer experience&lt;/strong&gt; (great tooling, compiler messages)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Companies like Microsoft, Amazon, Cloudflare, and Dropbox use Rust in production. It's built to help you write &lt;strong&gt;fast, reliable, and maintainable&lt;/strong&gt; software.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌟 What Makes Rust Special?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Memory safety without garbage collection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fearless concurrency&lt;/strong&gt; – build multi-threaded apps without race conditions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Helpful compiler&lt;/strong&gt; – the compiler actually teaches you!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Powerful tooling&lt;/strong&gt; – &lt;code&gt;cargo&lt;/code&gt;, &lt;code&gt;clippy&lt;/code&gt;, &lt;code&gt;rustfmt&lt;/code&gt;, and more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-cost abstractions&lt;/strong&gt; – safety and performance, no tradeoffs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've dealt with C/C++ bugs or hit performance walls in Python or JavaScript, Rust is the best of both worlds.&lt;/p&gt;




&lt;h2&gt;
  
  
  🆚 Rust vs Other Languages
&lt;/h2&gt;

&lt;p&gt;Rust sits in a unique position compared to other programming languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; – As fast as C/C++ but much safer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory Management&lt;/strong&gt; – Manual control without the crashes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type Safety&lt;/strong&gt; – Catches bugs at compile time, not runtime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency&lt;/strong&gt; – Built-in support for safe multi-threading&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning Curve&lt;/strong&gt; – Steeper initially, but pays off long-term&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike garbage-collected languages, Rust gives you control. Unlike manual memory management languages, Rust prevents common bugs.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Code Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hello World
&lt;/h3&gt;

&lt;p&gt;Every Rust program starts with a main() function. This is your entry point!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is the main function - where your program starts&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// println! is a macro that prints to the console&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Variables and Types
&lt;/h3&gt;

&lt;p&gt;Rust is statically typed but can often infer types. Variables are immutable by default - you need mut to change them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Variables are immutable by default&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// string slice (&amp;amp;str)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// unsigned 32-bit integer&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// 'mut' makes it mutable (changeable)&lt;/span&gt;

    &lt;span class="c1"&gt;// We can change mutable variables&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// {} are placeholders for variables in println!&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{} is {} years old with a score of {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Functions
&lt;/h3&gt;

&lt;p&gt;Functions in Rust are defined with fn. The last expression (without semicolon) is the return value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Function that takes two i32 parameters and returns an i32&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;  &lt;span class="c1"&gt;// no semicolon = this is the return value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Call the function and store the result&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"5 + 3 = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ownership (Rust's Superpower)
&lt;/h3&gt;

&lt;p&gt;Ownership is Rust's way of managing memory safely. Each value has one owner, and when the owner goes out of scope, the value is dropped.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a String on the heap&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// This MOVES s1 to s2. s1 is no longer valid!&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// This would cause a compile error because s1 was moved&lt;/span&gt;
    &lt;span class="c1"&gt;// println!("{}", s1); &lt;/span&gt;

    &lt;span class="c1"&gt;// Only s2 is valid now&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Borrowing
&lt;/h3&gt;

&lt;p&gt;Borrowing lets you use a value without taking ownership. Think of it like borrowing a book - you can read it, but you have to give it back!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This function borrows a String reference (&amp;amp;String)&lt;/span&gt;
&lt;span class="c1"&gt;// It doesn't take ownership, just looks at the data&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;print_length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Length: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;my_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Pass a reference (&amp;amp;) to the function&lt;/span&gt;
    &lt;span class="nf"&gt;print_length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;my_string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// We can still use my_string because we only borrowed it&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;my_string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Structs &amp;amp; Methods
&lt;/h3&gt;

&lt;p&gt;Structs are like classes in other languages - they group related data together. You can add methods to them using impl blocks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define a struct (like a class in other languages)&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Implementation block - where we define methods&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Associated function (like a constructor)&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;// shorthand for name: name, age: age&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Method that takes &amp;amp;self (borrows the instance)&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hi, I'm {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a new Person instance&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Call the method&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="nf"&gt;.greet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error Handling
&lt;/h3&gt;

&lt;p&gt;Rust doesn't have exceptions. Instead, it uses Result to handle errors explicitly. This forces you to deal with potential failures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Function returns Result&amp;lt;T, E&amp;gt; - either Ok(value) or Err(error)&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return an error&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cannot divide by zero"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return the successful result&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Use match to handle both success and error cases&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Rust&lt;/strong&gt;: &lt;code&gt;curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create new project&lt;/strong&gt;: &lt;code&gt;cargo new my_project&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build and run&lt;/strong&gt;: &lt;code&gt;cargo run&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read "The Rust Book"&lt;/strong&gt; online for free&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🔥 What You Can Build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web servers&lt;/strong&gt; (Actix, Rocket frameworks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command-line tools&lt;/strong&gt; (ripgrep, bat)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Game engines&lt;/strong&gt; (Bevy)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blockchain projects&lt;/strong&gt; (Solana, Polkadot)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebAssembly applications&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operating systems&lt;/strong&gt; (Redox OS)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Why 2025 is Perfect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mature ecosystem&lt;/strong&gt; – tons of quality crates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Industry adoption&lt;/strong&gt; – major companies using it in production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Great learning resources&lt;/strong&gt; – excellent documentation and community&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Job market&lt;/strong&gt; – high demand, good salaries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future-proof&lt;/strong&gt; – language designed for next-generation computing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust's combination of performance, safety, and growing ecosystem makes it an excellent choice for modern development in 2025!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>c</category>
      <category>community</category>
    </item>
  </channel>
</rss>
