diff --git a/conf/sqlite_serve.conf b/conf/sqlite_serve.conf new file mode 100644 index 0000000..c42bd2e --- /dev/null +++ b/conf/sqlite_serve.conf @@ -0,0 +1,114 @@ +# sqlite-serve - Unified Production Example +# Demonstrates all features: static queries, positional params, named params, templates + +load_module target/debug/libsqlite_serve.dylib; + +worker_processes auto; +events { + worker_connections 1024; +} + +error_log logs/error.log warn; + +http { + # Global templates for shared components + sqlite_global_templates "server_root/global_templates"; + + # MIME types + types { + text/html html htm; + text/css css; + application/javascript js; + } + default_type text/html; + + # Performance optimizations + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + gzip on; + + server { + listen 8080; + server_name localhost; + + root "server_root"; + charset utf-8; + + # Serve static CSS file + location /static/ { + add_header "Content-Type" "text/css; charset=utf-8"; + add_header "Cache-Control" "public, max-age=31536000"; + } + + # Homepage - Redirect to catalog + location = / { + return 302 /books; + } + + # Browse all books + location = /books { + add_header "Content-Type" "text/html; charset=utf-8"; + add_header "Cache-Control" "public, max-age=300"; + sqlite_db "book_catalog.db"; + sqlite_query "SELECT * FROM books ORDER BY rating DESC, title"; + sqlite_template "catalog.hbs"; + } + + # Book detail by ID (named parameter) + location = /book { + add_header "Content-Type" "text/html; charset=utf-8"; + add_header "Cache-Control" "public, max-age=300"; + sqlite_db "book_catalog.db"; + sqlite_query "SELECT * FROM books WHERE id = :book_id"; + sqlite_param :book_id $arg_id; + sqlite_template "detail.hbs"; + } + + # Filter by genre (named parameter) + location = /genre { + add_header "Content-Type" "text/html; charset=utf-8"; + add_header "Cache-Control" "public, max-age=300"; + sqlite_db "book_catalog.db"; + sqlite_query "SELECT * FROM books WHERE genre = :genre ORDER BY rating DESC, title"; + sqlite_param :genre $arg_genre; + sqlite_template "catalog.hbs"; + } + + # Search by title (named parameter with LIKE) + location = /search { + add_header "Content-Type" "text/html; charset=utf-8"; + sqlite_db "book_catalog.db"; + sqlite_query "SELECT * FROM books WHERE title LIKE '%' || :q || '%' ORDER BY rating DESC"; + sqlite_param :q $arg_q; + sqlite_template "catalog.hbs"; + } + + # Filter by minimum rating (named parameter) + location = /top { + add_header "Content-Type" "text/html; charset=utf-8"; + sqlite_db "book_catalog.db"; + sqlite_query "SELECT * FROM books WHERE rating >= :min_rating ORDER BY rating DESC, title"; + sqlite_param :min_rating $arg_min; + sqlite_template "catalog.hbs"; + } + + # Year range filter (multiple named parameters) + location = /era { + add_header "Content-Type" "text/html; charset=utf-8"; + sqlite_db "book_catalog.db"; + sqlite_query "SELECT * FROM books WHERE year >= :from AND year <= :to ORDER BY year DESC, title"; + sqlite_param :from $arg_from; + sqlite_param :to $arg_to; + sqlite_template "catalog.hbs"; + } + + # 404 handler + location @notfound { + add_header "Content-Type" "text/html; charset=utf-8"; + return 404 "

404 Not Found

Back to catalog

"; + } + } +} + diff --git a/server_root/book/detail.hbs b/server_root/book/detail.hbs index 7c20686..291939e 100644 --- a/server_root/book/detail.hbs +++ b/server_root/book/detail.hbs @@ -1,140 +1,50 @@ -{{> header}} +{{> zenburn_header}} - +
+ -{{#if results.[0]}} - {{#with results.[0]}} -
-
- 📖 -
- -

{{title}}

-

by {{author}}

- -
-
-
Rating
-
- - {{rating}} / 5.0 + {{#if results.[0]}} + {{#with results.[0]}} +
+

{{title}}

+

by {{author}}

+ +
+
+
Rating
+
⭐ {{rating}}
+
+
+
Published
+
{{year}}
+
+
+
Genre
+
{{genre}}
+
+
+
ISBN
+
{{isbn}}
-
-
Published
-
{{year}}
-
-
-
Genre
-
{{genre}}
-
-
-
ISBN
-
{{isbn}}
-
- -
- About this book:

- {{description}} + +
+

About This Book

+

{{description}}

- - ← Back to Catalog -
- {{/with}} -{{else}} -
-

Book Not Found

-

The requested book could not be found in our catalog.

- ← Back to Catalog -
-{{/if}} -{{> footer}} + ← Back to Catalog + {{/with}} + {{else}} +
+

Book Not Found

+

The requested book could not be found in our catalog.

+ ← Back to Catalog +
+ {{/if}} +
+{{> zenburn_footer}} diff --git a/server_root/books/catalog.hbs b/server_root/books/catalog.hbs new file mode 100644 index 0000000..e9c0976 --- /dev/null +++ b/server_root/books/catalog.hbs @@ -0,0 +1,37 @@ +{{> zenburn_header}} + + + +{{#if results}} +
+
+ {{#each results}}{{#if @last}}{{@index}}{{/if}}{{/each}} + Books Found +
+
+ 📚 + Categories +
+
+ + Curated +
+
+ +
+ {{#each results}} + {{> zenburn_card}} + {{/each}} +
+{{else}} +
+

No Books Found

+

Try adjusting your search or browse all books

+
+{{/if}} + +{{> zenburn_footer}} + diff --git a/server_root/era/catalog.hbs b/server_root/era/catalog.hbs new file mode 100644 index 0000000..e9c0976 --- /dev/null +++ b/server_root/era/catalog.hbs @@ -0,0 +1,37 @@ +{{> zenburn_header}} + + + +{{#if results}} +
+
+ {{#each results}}{{#if @last}}{{@index}}{{/if}}{{/each}} + Books Found +
+
+ 📚 + Categories +
+
+ + Curated +
+
+ +
+ {{#each results}} + {{> zenburn_card}} + {{/each}} +
+{{else}} +
+

No Books Found

+

Try adjusting your search or browse all books

+
+{{/if}} + +{{> zenburn_footer}} + diff --git a/server_root/genre/catalog.hbs b/server_root/genre/catalog.hbs new file mode 100644 index 0000000..e9c0976 --- /dev/null +++ b/server_root/genre/catalog.hbs @@ -0,0 +1,37 @@ +{{> zenburn_header}} + + + +{{#if results}} +
+
+ {{#each results}}{{#if @last}}{{@index}}{{/if}}{{/each}} + Books Found +
+
+ 📚 + Categories +
+
+ + Curated +
+
+ +
+ {{#each results}} + {{> zenburn_card}} + {{/each}} +
+{{else}} +
+

No Books Found

+

Try adjusting your search or browse all books

+
+{{/if}} + +{{> zenburn_footer}} + diff --git a/server_root/global_templates/zenburn_card.hbs b/server_root/global_templates/zenburn_card.hbs new file mode 100644 index 0000000..a567398 --- /dev/null +++ b/server_root/global_templates/zenburn_card.hbs @@ -0,0 +1,15 @@ +
+
+

{{title}}

+
⭐ {{rating}}
+
+

{{author}}

+

{{description}}

+
+ {{genre}} + {{year}} + {{#if isbn}}{{isbn}}{{/if}} +
+ View Details → +
+ diff --git a/server_root/global_templates/zenburn_footer.hbs b/server_root/global_templates/zenburn_footer.hbs new file mode 100644 index 0000000..643a0a7 --- /dev/null +++ b/server_root/global_templates/zenburn_footer.hbs @@ -0,0 +1,9 @@ + +
+

sqlite-serve v0.1.0

+

Rust + NGINX + SQLite + Handlebars

+

45 tests | Type-safe | Read-only

+
+ + + diff --git a/server_root/global_templates/zenburn_header.hbs b/server_root/global_templates/zenburn_header.hbs new file mode 100644 index 0000000..d78618c --- /dev/null +++ b/server_root/global_templates/zenburn_header.hbs @@ -0,0 +1,31 @@ + + + + + + sqlite-serve | Book Catalog + + + +
+
+

📚 sqlite-serve

+

Dynamic content from SQLite via NGINX

+
+
+ +
+ diff --git a/server_root/search/catalog.hbs b/server_root/search/catalog.hbs new file mode 100644 index 0000000..e9c0976 --- /dev/null +++ b/server_root/search/catalog.hbs @@ -0,0 +1,37 @@ +{{> zenburn_header}} + + + +{{#if results}} +
+
+ {{#each results}}{{#if @last}}{{@index}}{{/if}}{{/each}} + Books Found +
+
+ 📚 + Categories +
+
+ + Curated +
+
+ +
+ {{#each results}} + {{> zenburn_card}} + {{/each}} +
+{{else}} +
+

No Books Found

+

Try adjusting your search or browse all books

+
+{{/if}} + +{{> zenburn_footer}} + diff --git a/server_root/static/zenburn.css b/server_root/static/zenburn.css new file mode 100644 index 0000000..29a7835 --- /dev/null +++ b/server_root/static/zenburn.css @@ -0,0 +1,509 @@ +/* Zenburn theme for sqlite-serve */ +/* Generated palette via: zenburn -j -e oklab */ + +:root { + --fg-plus-2: #FFFFEF; + --fg-plus-1: #F5F5D6; + --fg: #DCDCCC; + --fg-1: #A6A689; + --fg-2: #656555; + --black: #000000; + --bg-2: #000000; + --bg-1: #111112; + --bg-05: #383838; + --bg: #2A2B2E; + --bg-plus-05: #494949; + --bg-plus-1: #4F4F4F; + --bg-plus-2: #5F5F5F; + --bg-plus-3: #6F6F6F; + --red-plus-2: #ECB3B3; + --red-plus-1: #DCA3A3; + --red: #CC9393; + --red-1: #BC8383; + --red-2: #AC7373; + --red-3: #9C6363; + --red-4: #8C5353; + --red-5: #7C4343; + --red-6: #6C3333; + --orange: #DFAF8F; + --yellow: #F0DFAF; + --yellow-1: #E0CF9F; + --yellow-2: #D0BF8F; + --green-5: #2F4F2F; + --green-4: #3F5F3F; + --green-3: #4F6F4F; + --green-2: #5F7F5F; + --green-1: #6F8F6F; + --green: #7F9F7F; + --green-plus-1: #8FB28F; + --green-plus-2: #9FC59F; + --green-plus-3: #AFD8AF; + --green-plus-4: #BFEBBF; + --cyan: #93E0E3; + --blue-plus-3: #BDE0F3; + --blue-plus-2: #ACE0E3; + --blue-plus-1: #94BFF3; + --blue: #8CD0D3; + --blue-1: #7CB8BB; + --blue-2: #6CA0A3; + --blue-3: #5C888B; + --blue-4: #4C7073; + --blue-5: #366060; + --magenta: #DC8CC3; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Monaco', 'Menlo', 'Consolas', monospace; + line-height: 1.6; + color: var(--fg); + background: var(--bg); + min-height: 100vh; +} + +.container { + max-width: 1400px; + margin: 0 auto; +} + +/* Header */ +header { + background: var(--bg-1); + border-bottom: 2px solid var(--blue-1); + padding: 1.5rem 2rem; + box-shadow: 0 2px 8px oklab(0.000% 0.000 0.000 / 0.5); +} + +.header-content { + max-width: 1400px; + margin: 0 auto; +} + +header h1 { + color: var(--yellow); + font-size: 1.8rem; + margin-bottom: 0.5rem; + font-weight: 600; +} + +header p { + color: var(--fg-1); + font-size: 0.95rem; +} + +/* Navigation */ +nav { + background: var(--bg-plus-1); + padding: 0.75rem 2rem; + border-bottom: 1px solid var(--bg-1); + position: sticky; + top: 0; + z-index: 100; + box-shadow: 0 2px 4px oklab(0.000% 0.000 0.000 / 0.3); +} + +.nav-content { + max-width: 1400px; + margin: 0 auto; + display: flex; + flex-wrap: wrap; + gap: 1.5rem; + align-items: center; +} + +nav a { + color: var(--blue-1); + text-decoration: none; + font-weight: 500; + transition: color 0.2s; + font-size: 0.95rem; +} + +nav a:hover { + color: var(--green-plus-1); +} + +nav a.active { + color: var(--yellow); +} + +.search-form { + margin-left: auto; + display: flex; + gap: 0.5rem; +} + +.search-form input { + background: var(--bg); + border: 1px solid var(--fg-2); + color: var(--fg); + padding: 0.4rem 0.8rem; + border-radius: 4px; + font-family: inherit; + font-size: 0.9rem; +} + +.search-form input:focus { + outline: none; + border-color: var(--blue-1); +} + +.search-form button { + background: var(--blue-1); + color: var(--bg-1); + border: none; + padding: 0.4rem 1rem; + border-radius: 4px; + cursor: pointer; + font-weight: 600; + font-size: 0.9rem; + transition: background 0.2s; +} + +.search-form button:hover { + background: var(--green-plus-1); +} + +/* Main content */ +main { + padding: 2rem; + max-width: 1400px; + margin: 0 auto; +} + +/* Footer */ +footer { + background: var(--bg-1); + padding: 2rem; + text-align: center; + border-top: 2px solid var(--blue-1); + margin-top: 3rem; +} + +footer p { + margin-top: 0.5rem; +} + +footer p:first-child { + color: var(--yellow); + font-weight: 600; + margin-top: 0; +} + +footer p:not(:first-child) { + color: var(--fg-1); + font-size: 0.9rem; +} + +/* Page header */ +.page-header { + background: var(--bg-plus-1); + border: 1px solid var(--bg-1); + border-left: 3px solid var(--green-plus-1); + border-radius: 6px; + padding: 2rem; + margin-bottom: 2rem; +} + +.page-header h2 { + color: var(--yellow); + font-size: 2rem; + margin-bottom: 0.5rem; +} + +.page-header p { + color: var(--fg-1); + font-size: 1.05rem; +} + +/* Stats grid */ +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1rem; + margin-bottom: 2rem; +} + +.stat-card { + background: var(--bg-plus-1); + border: 1px solid var(--bg-1); + border-radius: 6px; + padding: 1.5rem; + text-align: center; +} + +.stat-value { + color: var(--orange); + font-size: 2.5rem; + font-weight: 700; + display: block; + margin-bottom: 0.5rem; +} + +.stat-label { + color: var(--fg-1); + font-size: 0.9rem; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +/* Book grid and cards */ +.book-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); + gap: 1.5rem; +} + +.book-card { + background: var(--bg-plus-1); + border: 1px solid var(--bg-1); + border-left: 3px solid var(--blue-1); + border-radius: 6px; + padding: 1.5rem; + transition: all 0.3s ease; + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.book-card:hover { + border-left-color: var(--green-plus-1); + box-shadow: 0 4px 12px oklab(0.000% 0.000 0.000 / 0.5); + transform: translateY(-2px); +} + +.book-header { + display: flex; + justify-content: space-between; + align-items: start; + gap: 1rem; +} + +.book-title { + color: var(--yellow); + font-size: 1.15rem; + font-weight: 600; + line-height: 1.3; +} + +.book-rating { + background: var(--bg-1); + color: var(--orange); + padding: 0.25rem 0.75rem; + border-radius: 12px; + font-size: 0.85rem; + font-weight: 700; + white-space: nowrap; + flex-shrink: 0; +} + +.book-author { + color: var(--blue-1); + font-weight: 500; + font-size: 0.95rem; +} + +.book-description { + color: var(--fg-1); + line-height: 1.5; + font-size: 0.9rem; +} + +.book-meta { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + font-size: 0.85rem; +} + +.genre-badge { + background: var(--green); + color: var(--bg-1); + padding: 0.25rem 0.75rem; + border-radius: 4px; + font-weight: 600; +} + +.year-badge { + background: var(--bg-1); + color: var(--fg-1); + padding: 0.25rem 0.75rem; + border-radius: 4px; +} + +.isbn { + color: var(--fg-1); + font-family: monospace; + font-size: 0.8rem; +} + +.detail-link { + color: var(--blue-1); + text-decoration: none; + font-weight: 500; + font-size: 0.9rem; + margin-top: 0.5rem; + align-self: flex-start; + transition: color 0.2s; +} + +.detail-link:hover { + color: var(--green-plus-1); +} + +/* Empty state */ +.empty-state { + text-align: center; + padding: 4rem 2rem; + color: var(--fg-1); +} + +.empty-state h3 { + color: var(--orange); + font-size: 1.5rem; + margin-bottom: 1rem; +} + +.empty-state a { + color: var(--blue-1); + text-decoration: none; + font-weight: 600; +} + +.empty-state a:hover { + color: var(--green-plus-1); +} + +/* Book detail page */ +.detail-container { + max-width: 900px; + margin: 0 auto; +} + +.breadcrumb { + color: var(--fg-1); + margin-bottom: 1.5rem; + font-size: 0.9rem; +} + +.breadcrumb a { + color: var(--blue-1); + text-decoration: none; +} + +.breadcrumb a:hover { + color: var(--green-plus-1); +} + +.book-hero { + background: var(--bg-plus-1); + border: 1px solid var(--bg-1); + border-left: 4px solid var(--orange); + border-radius: 6px; + padding: 2rem; + margin-bottom: 2rem; +} + +.book-hero-title { + color: var(--yellow); + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 0.75rem; + line-height: 1.2; +} + +.book-hero-author { + color: var(--blue-1); + font-size: 1.3rem; + font-weight: 500; + margin-bottom: 1.5rem; +} + +.meta-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1.5rem; + margin-bottom: 2rem; +} + +.meta-item { + background: var(--bg-1); + padding: 1.25rem; + border-radius: 6px; + border-left: 3px solid var(--blue-1); +} + +.meta-label { + color: var(--fg-1); + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.05em; + margin-bottom: 0.5rem; +} + +.meta-value { + color: var(--yellow); + font-size: 1.4rem; + font-weight: 700; +} + +.meta-value.rating { + color: var(--orange); +} + +.description-section { + background: var(--bg-plus-1); + border: 1px solid var(--bg-1); + border-radius: 6px; + padding: 2rem; + margin-bottom: 2rem; +} + +.description-section h3 { + color: var(--green-plus-1); + font-size: 1.3rem; + margin-bottom: 1rem; +} + +.description-text { + color: var(--fg); + line-height: 1.8; + font-size: 1.05rem; +} + +.back-button { + display: inline-block; + background: var(--blue-1); + color: var(--bg-1); + padding: 0.75rem 1.5rem; + border-radius: 6px; + text-decoration: none; + font-weight: 600; + transition: all 0.2s; +} + +.back-button:hover { + background: var(--green-plus-1); + transform: translateX(-4px); +} + +.not-found { + text-align: center; + padding: 4rem 2rem; +} + +.not-found h2 { + color: var(--red); + font-size: 2rem; + margin-bottom: 1rem; +} + +.not-found p { + color: var(--fg-1); + margin-bottom: 2rem; +} diff --git a/server_root/top/catalog.hbs b/server_root/top/catalog.hbs new file mode 100644 index 0000000..e9c0976 --- /dev/null +++ b/server_root/top/catalog.hbs @@ -0,0 +1,37 @@ +{{> zenburn_header}} + + + +{{#if results}} +
+
+ {{#each results}}{{#if @last}}{{@index}}{{/if}}{{/each}} + Books Found +
+
+ 📚 + Categories +
+
+ + Curated +
+
+ +
+ {{#each results}} + {{> zenburn_card}} + {{/each}} +
+{{else}} +
+

No Books Found

+

Try adjusting your search or browse all books

+
+{{/if}} + +{{> zenburn_footer}} + diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..4899912 --- /dev/null +++ b/start.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# Production start script for sqlite-serve + +set -e + +echo "🚀 Starting sqlite-serve..." +echo "" + +# Check if database exists +if [ ! -f "book_catalog.db" ]; then + echo "📊 Database not found. Running setup..." + ./setup_book_catalog.sh + echo "" +fi + +# Build if needed +if [ ! -f "target/debug/libsqlite_serve.dylib" ]; then + echo "🔨 Building module..." + direnv exec "$PWD" cargo build + echo "" +fi + +# Stop any existing instance +./ngx_src/nginx-1.28.0/objs/nginx -s stop -c conf/sqlite_serve.conf -p . 2>/dev/null || true +sleep 1 + +# Start nginx +echo "▶️ Starting NGINX on http://localhost:8080" +./ngx_src/nginx-1.28.0/objs/nginx -c conf/sqlite_serve.conf -p . + +echo "" +echo "✅ sqlite-serve is running!" +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo " Endpoints:" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo " 📚 Browse" +echo " http://localhost:8080/books" +echo " → All books in catalog" +echo "" +echo " 🔍 Search" +echo " http://localhost:8080/search?q=Rust" +echo " → Search by title" +echo "" +echo " 📖 Book Detail" +echo " http://localhost:8080/book?id=1" +echo " → View individual book" +echo "" +echo " 🏷️ Filter by Genre" +echo " http://localhost:8080/genre?genre=Programming" +echo " → Programming books" +echo "" +echo " ⭐ Top Rated" +echo " http://localhost:8080/top?min=4.7" +echo " → Books rated 4.7 or higher" +echo "" +echo " 📅 By Era" +echo " http://localhost:8080/era?from=2015&to=2024" +echo " → Books from 2015-2024" +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "Features Demonstrated:" +echo " ✓ SQLite integration with parameterized queries" +echo " ✓ Named & positional SQL parameters" +echo " ✓ Handlebars templates with inheritance" +echo " ✓ Global & local template overrides" +echo " ✓ Type-safe configuration (Parse, Don't Validate)" +echo " ✓ Dependency injection architecture" +echo " ✓ 45 unit tests" +echo "" +echo "To stop: ./ngx_src/nginx-1.28.0/objs/nginx -s stop -c conf/sqlite_serve.conf -p ." +echo "" + diff --git a/start_book_catalog.sh b/start_book_catalog.sh deleted file mode 100755 index c54c490..0000000 --- a/start_book_catalog.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash -# Quick start script for the book catalog example - -set -e - -echo "📚 Starting Book Catalog..." -echo "" - -# Check if database exists -if [ ! -f "book_catalog.db" ]; then - echo "Database not found. Running setup..." - ./setup_book_catalog.sh - echo "" -fi - -# Check if module is built -if [ ! -f "target/debug/libsqlite_serve.dylib" ]; then - echo "Module not built. Building..." - direnv exec "$PWD" cargo build - echo "" -fi - -# Start nginx -echo "Starting nginx on http://localhost:8080" -./ngx_src/nginx-1.28.0/objs/nginx -c conf/book_catalog.conf -p . - -echo "" -echo "✅ Book Catalog is running!" -echo "" -echo "Visit:" -echo " • http://localhost:8080/books/all - All books" -echo " • http://localhost:8080/books/programming - Programming books" -echo " • http://localhost:8080/books/databases - Database books" -echo " • http://localhost:8080/books/computer-science - CS books" -echo "" -echo "To stop: ./ngx_src/nginx-1.28.0/objs/nginx -s stop -c conf/book_catalog.conf -p ." - diff --git a/start_book_detail.sh b/start_book_detail.sh deleted file mode 100755 index f909f74..0000000 --- a/start_book_detail.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -# Start script for the book detail example with path parameters - -set -e - -echo "📚 Starting Book Detail Example with Path Parameters..." -echo "" - -# Check if database exists -if [ ! -f "book_catalog.db" ]; then - echo "Database not found. Running setup..." - ./setup_book_catalog.sh - echo "" -fi - -# Check if module is built -if [ ! -f "target/debug/libsqlite_serve.dylib" ]; then - echo "Module not built. Building..." - direnv exec "$PWD" cargo build - echo "" -fi - -# Start nginx -echo "Starting nginx on http://localhost:8081" -./ngx_src/nginx-1.28.0/objs/nginx -c conf/book_detail.conf -p . - -echo "" -echo "✅ Book Detail Example is running!" -echo "" -echo "Try these URLs:" -echo " • http://localhost:8081/book?id=1 - View book #1" -echo " • http://localhost:8081/book?id=5 - View book #5" -echo " • http://localhost:8081/genre?genre=Programming - Programming books" -echo " • http://localhost:8081/genre?genre=Databases - Database books" -echo " • http://localhost:8081/years?min=2000&max=2010 - Books from 2000-2010" -echo " • http://localhost:8081/years?min=2015&max=2024 - Books from 2015-2024" -echo "" -echo "To stop: ./ngx_src/nginx-1.28.0/objs/nginx -s stop -c conf/book_detail.conf -p ." - diff --git a/start_named_params.sh b/start_named_params.sh deleted file mode 100755 index 8169cdd..0000000 --- a/start_named_params.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# Start script for named parameters example - -set -e - -echo "📚 Starting Named Parameters Example..." -echo "" - -# Check if database exists -if [ ! -f "book_catalog.db" ]; then - echo "Database not found. Running setup..." - ./setup_book_catalog.sh - echo "" -fi - -# Check if module is built -if [ ! -f "target/debug/libsqlite_serve.dylib" ]; then - echo "Module not built. Building..." - direnv exec "$PWD" cargo build - echo "" -fi - -# Start nginx -echo "Starting nginx on http://localhost:8082" -./ngx_src/nginx-1.28.0/objs/nginx -c conf/book_named_params.conf -p . - -echo "" -echo "✅ Named Parameters Example is running!" -echo "" -echo "Named Parameter Examples:" -echo " • http://localhost:8082/book?id=1" -echo " Query: SELECT * FROM books WHERE id = :book_id" -echo " Param: :book_id = \$arg_id" -echo "" -echo " • http://localhost:8082/genre?genre=Programming" -echo " Query: ... WHERE genre = :genre_name" -echo " Param: :genre_name = \$arg_genre" -echo "" -echo " • http://localhost:8082/years?min=2015&max=2024" -echo " Query: ... WHERE year >= :min_year AND year <= :max_year" -echo " Params: :min_year = \$arg_min, :max_year = \$arg_max" -echo "" -echo " • http://localhost:8082/search?q=Rust" -echo " Search by title with named parameter" -echo "" -echo " • http://localhost:8082/top-rated?rating=4.7" -echo " Filter by minimum rating" -echo "" -echo "To stop: ./ngx_src/nginx-1.28.0/objs/nginx -s stop -c conf/book_named_params.conf -p ." -