Skip to main content
Glama

DevDb MCP Server

boot.sh29.4 kB
#!/bin/bash set -e # Cleanup function to run on exit cleanup() { if [[ -d "$TODO_APP_DIR" ]]; then print_info "Cleaning up ephemeral Rails application..." cd "$TODO_APP_DIR" # Remove everything except .gitignore find . -mindepth 1 -not -name '.gitignore' -exec rm -rf {} + 2>/dev/null || true print_success "Cleanup completed. Only .gitignore remains." fi } # Set trap to run cleanup on script exit trap cleanup EXIT # Default database type DB_TYPE="${1:-sqlite}" # Color codes for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_info() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Validate database type if [[ ! "$DB_TYPE" =~ ^(mysql|postgres|sqlite)$ ]]; then print_error "Invalid database type: $DB_TYPE" print_info "Supported types: mysql, postgres, sqlite" exit 1 fi print_info "Setting up Rails application with $DB_TYPE database..." # Get script directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TODO_APP_DIR="$SCRIPT_DIR/todo-app" # Check if database containers are running (skip for SQLite) if [[ "$DB_TYPE" != "sqlite" ]]; then case "$DB_TYPE" in "mysql") if ! docker ps --format "table {{.Names}}" | grep -q "mysql-devdb-triage"; then print_error "MySQL database container 'mysql-devdb-triage' is not running!" print_info "Please start the MySQL database container first:" print_info " docker run -d --name mysql-devdb-triage -p 2222:3306 -e MYSQL_ROOT_PASSWORD=mysecretpassword mysql:8.0" exit 1 fi print_success "MySQL database container is running" ;; "postgres") if ! docker ps --format "table {{.Names}}" | grep -q "postgres-devdb-triage"; then print_error "PostgreSQL database container 'postgres-devdb-triage' is not running!" print_info "Please start the PostgreSQL database container first:" print_info " docker run -d --name postgres-devdb-triage -p 3333:5432 -e POSTGRES_PASSWORD=mysecretpassword postgres:16" exit 1 fi print_success "PostgreSQL database container is running" ;; esac fi # Check if Rails and Ruby are available if ! command -v rails &> /dev/null; then print_error "Rails is not installed. Please install Rails first:" print_info " gem install rails" exit 1 fi if ! command -v ruby &> /dev/null; then print_error "Ruby is not installed. Please install Ruby first." exit 1 fi # Clear the todo-app directory print_info "Clearing existing Rails application..." rm -rf "$TODO_APP_DIR" mkdir -p "$TODO_APP_DIR" # Create a new Rails application in todo-app directory print_info "Creating a new Rails application in todo-app..." case "$DB_TYPE" in "mysql") rails new "$TODO_APP_DIR" --database=mysql --skip-bundle --force ;; "postgres") rails new "$TODO_APP_DIR" --database=postgresql --skip-bundle --force ;; "sqlite") rails new "$TODO_APP_DIR" --database=sqlite3 --skip-bundle --force ;; esac # Change to the todo-app directory cd "$TODO_APP_DIR" # Remove git-related files and setup gitignore for ephemeral application print_info "Removing git repository and configuring gitignore for ephemeral app..." rm -rf .git .github rm -f .gitattributes # Overwrite .gitignore to ignore everything except itself cat > .gitignore << 'EOF' # Ignore everything in this ephemeral Rails application directory * # But don't ignore this .gitignore file itself !.gitignore EOF # Update database configuration print_info "Configuring database connection..." case "$DB_TYPE" in "mysql") cat > config/database.yml << 'EOF' default: &default adapter: mysql2 encoding: utf8mb4 host: 127.0.0.1 port: 2222 username: root password: mysecretpassword pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: *default database: sample_db test: <<: *default database: sample_db_test production: <<: *default database: sample_db_production username: sample_db password: <%= ENV["SAMPLE_DB_DATABASE_PASSWORD"] %> EOF ;; "postgres") cat > config/database.yml << 'EOF' default: &default adapter: postgresql encoding: unicode host: 127.0.0.1 port: 3333 username: postgres password: mysecretpassword pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: *default database: sample_db test: <<: *default database: sample_db_test production: primary: <<: *default database: sample_db_production cache: <<: *default database: sample_db_production_cache migrations_paths: db/cache_migrate queue: <<: *default database: sample_db_production_queue migrations_paths: db/queue_migrate cable: <<: *default database: sample_db_production_cable migrations_paths: db/cable_migrate EOF ;; "sqlite") # SQLite config is fine as generated by Rails ;; esac # Install gems print_info "Installing gems..." bundle install # Create controllers print_info "Creating controllers..." cat > app/controllers/home_controller.rb << 'EOF' class HomeController < ApplicationController def index @products = execute_query("SELECT * FROM products LIMIT 10") @users = execute_query("SELECT * FROM users LIMIT 5") @categories = execute_query("SELECT * FROM categories") end private def execute_query(sql) result = ActiveRecord::Base.connection.execute(sql) case ActiveRecord::Base.connection.adapter_name.downcase when 'mysql2' result.map { |row| row.is_a?(Hash) ? row : Hash[result.fields.zip(row)] } when 'postgresql' result.map { |row| row } when 'sqlite' result.map { |row| row } else result.map { |row| row } end rescue => e Rails.logger.error "Query failed: #{e.message}" [] end end EOF cat > app/controllers/todos_controller.rb << 'EOF' class TodosController < ApplicationController protect_from_forgery with: :null_session def index @todos = execute_query("SELECT * FROM todos ORDER BY created_at DESC") end def create title = params[:title]&.strip if title.present? case ActiveRecord::Base.connection.adapter_name.downcase when 'mysql2' id = SecureRandom.uuid execute_query("INSERT INTO todos (id, title) VALUES ('#{id}', '#{ActiveRecord::Base.connection.quote_string(title)}')") when 'postgresql' execute_query("INSERT INTO todos (title) VALUES ('#{ActiveRecord::Base.connection.quote_string(title)}')") when 'sqlite' id = SecureRandom.uuid execute_query("INSERT INTO todos (id, title) VALUES ('#{id}', '#{ActiveRecord::Base.connection.quote_string(title)}')") end end redirect_to todos_path end def toggle id = params[:id] todo = execute_query("SELECT * FROM todos WHERE id = '#{id}' LIMIT 1").first if todo case ActiveRecord::Base.connection.adapter_name.downcase when 'mysql2' new_status = todo['completed'] ? 0 : 1 when 'postgresql' new_status = !todo['completed'] when 'sqlite' new_status = todo['completed'] == 1 ? 0 : 1 end execute_query("UPDATE todos SET completed = #{new_status} WHERE id = '#{id}'") end redirect_to todos_path end def destroy id = params[:id] execute_query("DELETE FROM todos WHERE id = '#{id}'") redirect_to todos_path end private def execute_query(sql) result = ActiveRecord::Base.connection.execute(sql) case ActiveRecord::Base.connection.adapter_name.downcase when 'mysql2' result.map { |row| row.is_a?(Hash) ? row : Hash[result.fields.zip(row)] } when 'postgresql' result.map { |row| row } when 'sqlite' result.map { |row| row } else result.map { |row| row } end rescue => e Rails.logger.error "Query failed: #{e.message}" [] end end EOF # Create views print_info "Creating views..." mkdir -p app/views/home # Create a capitalized version of DB_TYPE DB_TYPE_CAPITALIZED=$(echo "${DB_TYPE}" | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}') cat > app/views/home/index.html.erb << EOF <div style="font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px;"> <h1 style="color: #333; text-align: center;">Rails ${DB_TYPE_CAPITALIZED} Demo Application</h1> <div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px;"> <h2 style="color: #28a745;">🎉 Success! Rails is connected to ${DB_TYPE_CAPITALIZED}</h2> <p>This application is running Rails with a ${DB_TYPE_CAPITALIZED} database backend.</p> EOF case "$DB_TYPE" in "mysql") cat >> app/views/home/index.html.erb << 'EOF' <p><strong>Database:</strong> MySQL via Docker container</p> <p><strong>Connection:</strong> 127.0.0.1:2222</p> EOF ;; "postgres") cat >> app/views/home/index.html.erb << 'EOF' <p><strong>Database:</strong> PostgreSQL via Docker container</p> <p><strong>Connection:</strong> 127.0.0.1:3333</p> EOF ;; "sqlite") cat >> app/views/home/index.html.erb << 'EOF' <p><strong>Database:</strong> SQLite (file-based)</p> <p><strong>File:</strong> storage/development.sqlite3</p> EOF ;; esac cat >> app/views/home/index.html.erb << 'EOF' <p style="margin-top: 15px;"><a href="/todos" style="background: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px;">📝 Try the Todo App</a></p> </div> <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px;"> <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <h3 style="color: #007bff; margin-top: 0;">📦 Products (<%= @products.length %>)</h3> <% @products.each do |product| %> <div style="border-bottom: 1px solid #eee; padding: 10px 0;"> <strong><%= product['name'] %></strong><br> <small style="color: #666;"><%= product['description'] %></small><br> <span style="color: #28a745; font-weight: bold;">$<%= product['price'] %></span> </div> <% end %> </div> <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <h3 style="color: #28a745; margin-top: 0;">👥 Users (<%= @users.length %>)</h3> <% @users.each do |user| %> <div style="border-bottom: 1px solid #eee; padding: 10px 0;"> <strong><%= user['name'] %></strong><br> <small style="color: #666;"><%= user['email'] %></small> </div> <% end %> </div> <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <h3 style="color: #ffc107; margin-top: 0;">🏷️ Categories (<%= @categories.length %>)</h3> <% @categories.each do |category| %> <div style="border-bottom: 1px solid #eee; padding: 10px 0;"> <strong><%= category['name'] %></strong><br> <small style="color: #666;"><%= category['description'] %></small> </div> <% end %> </div> </div> </div> EOF mkdir -p app/views/todos cat > app/views/todos/index.html.erb << EOF <div style="font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px;"> <h1 style="color: #333; text-align: center;">📝 Todo App - ${DB_TYPE_CAPITALIZED} Backend</h1> <div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px;"> <h3>Add New Todo</h3> <form action="/todos" method="post" style="display: flex; gap: 10px;"> <input type="text" name="title" placeholder="Enter todo item..." style="flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px;" required> <button type="submit" style="background: #28a745; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer;">Add Todo</button> </form> </div> <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <h3 style="margin-top: 0;">Your Todos (<%= @todos.length %>)</h3> <% if @todos.empty? %> <p style="color: #666; text-align: center; padding: 40px;">No todos yet. Add one above to get started!</p> <% else %> <% @todos.each do |todo| %> EOF case "$DB_TYPE" in "sqlite") cat >> app/views/todos/index.html.erb << 'EOF' <div style="display: flex; align-items: center; justify-content: space-between; padding: 15px; border-bottom: 1px solid #eee; <%= 'background: #f8f9fa;' if todo['completed'] == 1 %>"> <div style="flex: 1;"> <span style="<%= 'text-decoration: line-through; color: #666;' if todo['completed'] == 1 %>"> <%= todo['title'] %> </span> <% if todo['completed'] == 1 %> <span style="color: #28a745; font-size: 12px; margin-left: 10px;">✓ Completed</span> <% end %> </div> <div style="display: flex; gap: 10px;"> <form action="/todos/<%= todo['id'] %>/toggle" method="post" style="display: inline;"> <button type="submit" style="background: <%= todo['completed'] == 1 ? '#ffc107' : '#28a745' %>; color: white; padding: 5px 10px; border: none; border-radius: 3px; cursor: pointer; font-size: 12px;"> <%= todo['completed'] == 1 ? 'Undo' : 'Done' %> </button> </form> <form action="/todos/<%= todo['id'] %>" method="post" style="display: inline;"> <input type="hidden" name="_method" value="delete"> <button type="submit" style="background: #dc3545; color: white; padding: 5px 10px; border: none; border-radius: 3px; cursor: pointer; font-size: 12px;" onclick="return confirm('Are you sure you want to delete this todo?')"> Delete </button> </form> </div> </div> EOF ;; *) cat >> app/views/todos/index.html.erb << 'EOF' <div style="display: flex; align-items: center; justify-content: space-between; padding: 15px; border-bottom: 1px solid #eee; <%= 'background: #f8f9fa;' if todo['completed'] %>"> <div style="flex: 1;"> <span style="<%= 'text-decoration: line-through; color: #666;' if todo['completed'] %>"> <%= todo['title'] %> </span> <% if todo['completed'] %> <span style="color: #28a745; font-size: 12px; margin-left: 10px;">✓ Completed</span> <% end %> </div> <div style="display: flex; gap: 10px;"> <form action="/todos/<%= todo['id'] %>/toggle" method="post" style="display: inline;"> <button type="submit" style="background: <%= todo['completed'] ? '#ffc107' : '#28a745' %>; color: white; padding: 5px 10px; border: none; border-radius: 3px; cursor: pointer; font-size: 12px;"> <%= todo['completed'] ? 'Undo' : 'Done' %> </button> </form> <form action="/todos/<%= todo['id'] %>" method="post" style="display: inline;"> <input type="hidden" name="_method" value="delete"> <button type="submit" style="background: #dc3545; color: white; padding: 5px 10px; border: none; border-radius: 3px; cursor: pointer; font-size: 12px;" onclick="return confirm('Are you sure you want to delete this todo?')"> Delete </button> </form> </div> </div> EOF ;; esac cat >> app/views/todos/index.html.erb << 'EOF' <% end %> <% end %> </div> <div style="text-align: center; margin-top: 30px;"> <a href="/" style="color: #007bff; text-decoration: none;">← Back to Home</a> </div> </div> EOF # Add routes print_info "Adding routes..." sed -i.bak '3i\ root "home#index"\ resources :todos, only: [:index, :create, :destroy] do\ member do\ post :toggle\ end\ end ' config/routes.rb # Create database setup script print_info "Creating database setup script..." cat > setup_database.rb << 'EOF' require_relative 'config/environment' def setup_database adapter = ActiveRecord::Base.connection.adapter_name.downcase case adapter when 'mysql2' setup_mysql when 'postgresql' setup_postgresql when 'sqlite' setup_sqlite end end def setup_mysql print "Waiting for MySQL connection..." max_attempts = 30 attempts = 0 begin ActiveRecord::Base.connection.execute("SELECT 1") puts " Connected!" rescue => e attempts += 1 if attempts < max_attempts print "." sleep 1 retry else puts " Failed to connect after #{max_attempts} attempts" puts "Error: #{e.message}" exit 1 end end # Create database if it doesn't exist ActiveRecord::Base.connection.execute("CREATE DATABASE IF NOT EXISTS sample_db") ActiveRecord::Base.connection.execute("USE sample_db") create_mysql_tables insert_mysql_data end def setup_postgresql print "Waiting for PostgreSQL connection..." max_attempts = 30 attempts = 0 begin ActiveRecord::Base.connection.execute("SELECT 1") puts " Connected!" rescue => e attempts += 1 if attempts < max_attempts print "." sleep 1 retry else puts " Failed to connect after #{max_attempts} attempts" puts "Error: #{e.message}" exit 1 end end # Create database if it doesn't exist begin ActiveRecord::Base.connection.execute("CREATE DATABASE sample_db") rescue ActiveRecord::StatementInvalid => e if e.message.include?("already exists") puts "Database already exists, continuing..." else raise e end end # Reconnect to sample_db config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first.configuration_hash.dup config[:database] = 'sample_db' ActiveRecord::Base.establish_connection(config) # Enable extensions ActiveRecord::Base.connection.execute("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"") ActiveRecord::Base.connection.execute("CREATE EXTENSION IF NOT EXISTS \"pgcrypto\"") create_postgresql_tables insert_postgresql_data end def setup_sqlite print "Setting up SQLite database..." create_sqlite_tables insert_sqlite_data end def create_mysql_tables print "Creating MySQL tables..." ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS todos ( id VARCHAR(36) PRIMARY KEY, title VARCHAR(255) NOT NULL, completed BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS products ( id VARCHAR(36) PRIMARY KEY, name VARCHAR(255) NOT NULL, description TEXT, price DECIMAL(10,2) NOT NULL, stock_quantity INT NOT NULL DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS categories ( id VARCHAR(36) PRIMARY KEY, name VARCHAR(255) NOT NULL, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS users ( id VARCHAR(36) PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) SQL puts " Done!" end def create_postgresql_tables print "Creating PostgreSQL tables..." ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS todos ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title VARCHAR(255) NOT NULL, completed BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, description TEXT, price DECIMAL(10,2) NOT NULL, stock_quantity INT NOT NULL DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS categories ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) SQL puts " Done!" end def create_sqlite_tables print "Creating SQLite tables..." ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS todos ( id TEXT PRIMARY KEY, title TEXT NOT NULL, completed INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS products ( id TEXT PRIMARY KEY, name TEXT NOT NULL, description TEXT, price REAL NOT NULL, stock_quantity INTEGER NOT NULL DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS categories ( id TEXT PRIMARY KEY, name TEXT NOT NULL, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) SQL ActiveRecord::Base.connection.execute(<<~SQL) CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, email TEXT NOT NULL UNIQUE, name TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) SQL puts " Done!" end def insert_mysql_data print "Inserting MySQL sample data..." categories = [ { id: SecureRandom.uuid, name: 'Electronics', description: 'Electronic devices and gadgets' }, { id: SecureRandom.uuid, name: 'Clothing', description: 'Apparel and fashion items' }, { id: SecureRandom.uuid, name: 'Books', description: 'Books and publications' } ] categories.each do |category| ActiveRecord::Base.connection.execute(<<~SQL) INSERT IGNORE INTO categories (id, name, description) VALUES ('#{category[:id]}', '#{category[:name]}', '#{category[:description]}') SQL end products = [ { id: SecureRandom.uuid, name: 'Smartphone X', description: 'Latest smartphone with advanced features', price: 899.99, stock_quantity: 50 }, { id: SecureRandom.uuid, name: 'Laptop Pro', description: 'High-performance laptop for professionals', price: 1299.99, stock_quantity: 25 }, { id: SecureRandom.uuid, name: 'Cotton T-shirt', description: 'Comfortable cotton t-shirt', price: 19.99, stock_quantity: 200 } ] products.each do |product| ActiveRecord::Base.connection.execute(<<~SQL) INSERT IGNORE INTO products (id, name, description, price, stock_quantity) VALUES ('#{product[:id]}', '#{product[:name]}', '#{product[:description]}', #{product[:price]}, #{product[:stock_quantity]}) SQL end users = [ { id: SecureRandom.uuid, email: 'john.doe@example.com', name: 'John Doe' }, { id: SecureRandom.uuid, email: 'jane.smith@example.com', name: 'Jane Smith' } ] users.each do |user| ActiveRecord::Base.connection.execute(<<~SQL) INSERT IGNORE INTO users (id, email, name) VALUES ('#{user[:id]}', '#{user[:email]}', '#{user[:name]}') SQL end puts " Done!" end def insert_postgresql_data print "Inserting PostgreSQL sample data..." categories = [ { name: 'Electronics', description: 'Electronic devices and gadgets' }, { name: 'Clothing', description: 'Apparel and fashion items' }, { name: 'Books', description: 'Books and publications' } ] categories.each do |category| begin ActiveRecord::Base.connection.execute(<<~SQL) INSERT INTO categories (name, description) VALUES ('#{category[:name]}', '#{category[:description]}') SQL rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation # Category already exists, skip end end products = [ { name: 'Smartphone X', description: 'Latest smartphone with advanced features', price: 899.99, stock_quantity: 50 }, { name: 'Laptop Pro', description: 'High-performance laptop for professionals', price: 1299.99, stock_quantity: 25 }, { name: 'Cotton T-shirt', description: 'Comfortable cotton t-shirt', price: 19.99, stock_quantity: 200 } ] products.each do |product| begin ActiveRecord::Base.connection.execute(<<~SQL) INSERT INTO products (name, description, price, stock_quantity) VALUES ('#{product[:name]}', '#{product[:description]}', #{product[:price]}, #{product[:stock_quantity]}) SQL rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation # Product already exists, skip end end users = [ { email: 'john.doe@example.com', name: 'John Doe' }, { email: 'jane.smith@example.com', name: 'Jane Smith' } ] users.each do |user| begin ActiveRecord::Base.connection.execute(<<~SQL) INSERT INTO users (email, name) VALUES ('#{user[:email]}', '#{user[:name]}') SQL rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation # User already exists, skip end end puts " Done!" end def insert_sqlite_data print "Inserting SQLite sample data..." categories = [ { id: SecureRandom.uuid, name: 'Electronics', description: 'Electronic devices and gadgets' }, { id: SecureRandom.uuid, name: 'Clothing', description: 'Apparel and fashion items' }, { id: SecureRandom.uuid, name: 'Books', description: 'Books and publications' } ] categories.each do |category| ActiveRecord::Base.connection.execute(<<~SQL) INSERT OR IGNORE INTO categories (id, name, description) VALUES ('#{category[:id]}', '#{category[:name]}', '#{category[:description]}') SQL end products = [ { id: SecureRandom.uuid, name: 'Smartphone X', description: 'Latest smartphone with advanced features', price: 899.99, stock_quantity: 50 }, { id: SecureRandom.uuid, name: 'Laptop Pro', description: 'High-performance laptop for professionals', price: 1299.99, stock_quantity: 25 }, { id: SecureRandom.uuid, name: 'Cotton T-shirt', description: 'Comfortable cotton t-shirt', price: 19.99, stock_quantity: 200 } ] products.each do |product| ActiveRecord::Base.connection.execute(<<~SQL) INSERT OR IGNORE INTO products (id, name, description, price, stock_quantity) VALUES ('#{product[:id]}', '#{product[:name]}', '#{product[:description]}', #{product[:price]}, #{product[:stock_quantity]}) SQL end users = [ { id: SecureRandom.uuid, email: 'john.doe@example.com', name: 'John Doe' }, { id: SecureRandom.uuid, email: 'jane.smith@example.com', name: 'Jane Smith' } ] users.each do |user| ActiveRecord::Base.connection.execute(<<~SQL) INSERT OR IGNORE INTO users (id, email, name) VALUES ('#{user[:id]}', '#{user[:email]}', '#{user[:name]}') SQL end puts " Done!" end # Run the setup setup_database puts "Database setup completed successfully!" EOF # Setup database and sample data print_info "Setting up database and sample data..." ruby setup_database.rb # Find an available port print_info "Finding available port..." PORT=3000 while lsof -i :$PORT > /dev/null 2>&1; do PORT=$((PORT + 1)) done print_success "Using port: $PORT" # Start the Rails server print_info "Starting Rails server on port $PORT..." print_success "Rails application is now running!" print_success "🚀 Open your browser and go to: http://localhost:$PORT" print_info "Application location: $TODO_APP_DIR" print_info "To stop the server: Press Ctrl+C" print_info "" print_info "Starting server..." # Start the server rails server -b 0.0.0.0 -p $PORT

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/damms005/devdb-vscode'

If you have feedback or need assistance with the MCP directory API, please join our Discord server