|
|
@@ -1,186 +0,0 @@
|
|
|
--- ---------------------------------------------------------
|
|
|
--- Initial Database and User Setup (Run as MySQL Root)
|
|
|
--- ---------------------------------------------------------
|
|
|
-CREATE DATABASE IF NOT EXISTS food_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
|
-
|
|
|
--- 1. Create the Owner User
|
|
|
--- Has full rights and can grant privileges to others.
|
|
|
-CREATE USER IF NOT EXISTS 'db_owner'@'%' IDENTIFIED BY 'owner_pass';
|
|
|
-GRANT ALL PRIVILEGES ON food_db.* TO 'db_owner'@'%' WITH GRANT OPTION;
|
|
|
-
|
|
|
--- 2. Create the Reader User
|
|
|
--- Has only connect and read permissions.
|
|
|
-CREATE USER IF NOT EXISTS 'db_reader'@'%' IDENTIFIED BY 'reader_pass';
|
|
|
-GRANT USAGE ON *.* TO 'db_reader'@'%';
|
|
|
-
|
|
|
--- 3. Create the Loader User
|
|
|
--- Has connect and data manipulation permissions to load files.
|
|
|
-CREATE USER IF NOT EXISTS 'db_loader'@'%' IDENTIFIED BY 'loader_pass';
|
|
|
-GRANT USAGE ON *.* TO 'db_loader'@'%';
|
|
|
-GRANT FILE ON *.* TO 'db_loader'@'%'; -- Essential for LOAD DATA INFILE from any directory
|
|
|
-
|
|
|
--- 4. Create the App Auth User
|
|
|
--- Segregation of Duties: Handles only users table for web application routing.
|
|
|
-CREATE USER IF NOT EXISTS 'db_app_auth'@'%' IDENTIFIED BY 'app_auth_placeholder_pass';
|
|
|
--- Note: Replace 'app_auth_placeholder_pass' later outside this script.
|
|
|
-GRANT USAGE ON *.* TO 'db_app_auth'@'%';
|
|
|
-
|
|
|
-FLUSH PRIVILEGES;
|
|
|
-
|
|
|
-
|
|
|
--- ---------------------------------------------------------
|
|
|
--- Table Creation & Grants (Logically executed by db_owner)
|
|
|
--- ---------------------------------------------------------
|
|
|
-USE food_db;
|
|
|
-
|
|
|
--- NOTE: The syntax you provided (`read_csv_auto`) is specific to DuckDB!
|
|
|
--- MySQL does NOT support `read_csv_auto()` to dynamically create tables from CSV.
|
|
|
--- In MySQL, you MUST define the table schema first, and then use LOAD DATA INFILE.
|
|
|
--- Here is the MySQL equivalent process:
|
|
|
-
|
|
|
--- Step A.1: Create Web Users Table
|
|
|
-CREATE TABLE IF NOT EXISTS users (
|
|
|
- id INT AUTO_INCREMENT PRIMARY KEY,
|
|
|
- username VARCHAR(100) UNIQUE NOT NULL,
|
|
|
- password_hash VARCHAR(255) NOT NULL,
|
|
|
- email VARCHAR(255),
|
|
|
- search_limit VARCHAR(50) DEFAULT '50',
|
|
|
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-GRANT SELECT, INSERT, UPDATE ON food_db.users TO 'db_app_auth'@'%';
|
|
|
-
|
|
|
--- Step A.2: Create Health Profiles Table
|
|
|
-CREATE TABLE IF NOT EXISTS user_health_profiles (
|
|
|
- id INT AUTO_INCREMENT PRIMARY KEY,
|
|
|
- user_id INT NOT NULL,
|
|
|
- illness_health_condition_diet_dislikes_name VARCHAR(100),
|
|
|
- illness_health_condition_diet_dislikes_value VARCHAR(255),
|
|
|
- FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-GRANT SELECT, INSERT, UPDATE, DELETE ON food_db.user_health_profiles TO 'db_app_auth'@'%';
|
|
|
-
|
|
|
--- Step A.3: Create Plate Builder Tables
|
|
|
-CREATE TABLE IF NOT EXISTS plates (
|
|
|
- id INT AUTO_INCREMENT PRIMARY KEY,
|
|
|
- user_id INT NOT NULL,
|
|
|
- plate_name VARCHAR(255) NOT NULL,
|
|
|
- FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-CREATE TABLE IF NOT EXISTS plate_items (
|
|
|
- id INT AUTO_INCREMENT PRIMARY KEY,
|
|
|
- plate_id INT NOT NULL,
|
|
|
- product_code VARCHAR(50) NOT NULL,
|
|
|
- quantity_grams FLOAT NOT NULL,
|
|
|
- FOREIGN KEY (plate_id) REFERENCES plates(id) ON DELETE CASCADE
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-GRANT SELECT, INSERT, UPDATE, DELETE ON food_db.plates TO 'db_app_auth'@'%';
|
|
|
-GRANT SELECT, INSERT, UPDATE, DELETE ON food_db.plate_items TO 'db_app_auth'@'%';
|
|
|
-FLUSH PRIVILEGES;
|
|
|
-
|
|
|
--- Step A.2: Create the table with known columns (Example structure for OpenFoodFacts)
|
|
|
-CREATE TABLE IF NOT EXISTS products (
|
|
|
- code VARCHAR(50) PRIMARY KEY,
|
|
|
- url TEXT,
|
|
|
- creator VARCHAR(255),
|
|
|
- created_t VARCHAR(50),
|
|
|
- created_datetime VARCHAR(50),
|
|
|
- last_modified_t VARCHAR(50),
|
|
|
- last_modified_datetime VARCHAR(50),
|
|
|
- product_name TEXT,
|
|
|
- generic_name TEXT,
|
|
|
- quantity VARCHAR(255),
|
|
|
- packaging TEXT,
|
|
|
- brands TEXT,
|
|
|
- categories TEXT,
|
|
|
- origins TEXT,
|
|
|
- labels TEXT,
|
|
|
- stores TEXT,
|
|
|
- countries TEXT,
|
|
|
- ingredients_text TEXT,
|
|
|
- allergens TEXT,
|
|
|
- traces TEXT,
|
|
|
-
|
|
|
- -- Add FULLTEXT index for context search on ingredients and products
|
|
|
- FULLTEXT INDEX ft_idx_search (product_name, ingredients_text)
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-CREATE TABLE IF NOT EXISTS products_core (
|
|
|
- code VARCHAR(50) PRIMARY KEY,
|
|
|
- product_name TEXT,
|
|
|
- generic_name TEXT,
|
|
|
- brands TEXT,
|
|
|
- ingredients_text TEXT,
|
|
|
- FULLTEXT INDEX ft_idx_search (product_name, ingredients_text),
|
|
|
- FULLTEXT INDEX ft_idx_pn (product_name),
|
|
|
- FULLTEXT INDEX ft_idx_it (ingredients_text)
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-CREATE TABLE IF NOT EXISTS products_macros (
|
|
|
- code VARCHAR(50) PRIMARY KEY,
|
|
|
- `energy-kcal_100g` DOUBLE,
|
|
|
- proteins_100g DOUBLE,
|
|
|
- fat_100g DOUBLE,
|
|
|
- carbohydrates_100g DOUBLE,
|
|
|
- sugars_100g DOUBLE,
|
|
|
- fiber_100g DOUBLE,
|
|
|
- sodium_100g DOUBLE,
|
|
|
- salt_100g DOUBLE,
|
|
|
- cholesterol_100g DOUBLE
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-CREATE TABLE IF NOT EXISTS products_vitamins (
|
|
|
- code VARCHAR(50) PRIMARY KEY,
|
|
|
- `vitamin-a_100g` DOUBLE,
|
|
|
- `vitamin-b1_100g` DOUBLE,
|
|
|
- `vitamin-b2_100g` DOUBLE,
|
|
|
- `vitamin-pp_100g` DOUBLE,
|
|
|
- `vitamin-b6_100g` DOUBLE,
|
|
|
- `vitamin-b9_100g` DOUBLE,
|
|
|
- `vitamin-b12_100g` DOUBLE,
|
|
|
- `vitamin-c_100g` DOUBLE,
|
|
|
- `vitamin-d_100g` DOUBLE,
|
|
|
- `vitamin-e_100g` DOUBLE,
|
|
|
- `vitamin-k_100g` DOUBLE
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-CREATE TABLE IF NOT EXISTS products_minerals (
|
|
|
- code VARCHAR(50) PRIMARY KEY,
|
|
|
- calcium_100g DOUBLE,
|
|
|
- iron_100g DOUBLE,
|
|
|
- magnesium_100g DOUBLE,
|
|
|
- potassium_100g DOUBLE,
|
|
|
- zinc_100g DOUBLE
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
-CREATE TABLE IF NOT EXISTS products_allergens (
|
|
|
- code VARCHAR(50) PRIMARY KEY,
|
|
|
- allergens TEXT,
|
|
|
- traces TEXT
|
|
|
-) ENGINE=InnoDB;
|
|
|
-
|
|
|
--- Step B: The Owner grants explicit privileges to the Reader and Loader
|
|
|
--- Grant explicit privileges to the Reader
|
|
|
-GRANT SELECT ON food_db.products TO 'db_reader'@'%';
|
|
|
-GRANT SELECT ON food_db.products_core TO 'db_reader'@'%';
|
|
|
-GRANT SELECT ON food_db.products_allergens TO 'db_reader'@'%';
|
|
|
-GRANT SELECT ON food_db.products_macros TO 'db_reader'@'%';
|
|
|
-GRANT SELECT ON food_db.products_vitamins TO 'db_reader'@'%';
|
|
|
-GRANT SELECT ON food_db.products_minerals TO 'db_reader'@'%';
|
|
|
-
|
|
|
--- Grant broad privileges to the Loader on food_db to allow temp tables and UPSERT modifications
|
|
|
-GRANT SELECT, INSERT, UPDATE, DELETE, DROP, CREATE, ALTER, INDEX ON food_db.* TO 'db_loader'@'%';
|
|
|
-FLUSH PRIVILEGES;
|
|
|
-
|
|
|
--- Step C: The Loader user would then run this MySQL command to import:
|
|
|
-/*
|
|
|
-LOAD DATA INFILE '/path/to/en.openfoodfacts.org.products.converted.csv'
|
|
|
-INTO TABLE products
|
|
|
-FIELDS TERMINATED BY '\t'
|
|
|
-ENCLOSED BY ''
|
|
|
-LINES TERMINATED BY '\n'
|
|
|
-IGNORE 1 ROWS;
|
|
|
-*/
|