diff --git a/.run/comp353.run.xml b/.run/comp353.run.xml new file mode 100644 index 0000000..44177f3 --- /dev/null +++ b/.run/comp353.run.xml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.run/comp353_postgres.run.xml b/.run/comp353_postgres.run.xml new file mode 100644 index 0000000..44177f3 --- /dev/null +++ b/.run/comp353_postgres.run.xml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9289c63..25474c7 100644 --- a/pom.xml +++ b/pom.xml @@ -14,4 +14,11 @@ UTF-8 + + + mysql + mysql-connector-java + 8.0.33 + + \ No newline at end of file diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index e8f2b39..3357606 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -1,7 +1,144 @@ package org.example; +import java.sql.*; +import java.util.Random; +import java.util.Calendar; + public class Main { + // change the DB_URL accordingly + static final String HOST = "localhost"; + static final String PORT = "32776"; + static final String DATABASE_NAME = "assignment1"; + + static final String DB_URL = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DATABASE_NAME; + static final String USER = "root"; + static final String PASSWORD = "secret"; + + static final String[] PROVINCES = {"AB", "BC", "MB", "NB", "NL", "NS", "NT", "NU", "ON", "PE", "QC", "SK", "YT"}; + static final String[] CITIES = {"Montreal", "Laval", "Brossard"}; + static final String[] GENDERS = {"M", "F", "U"}; + + private static final String[] STREET_NAMES = { + "Pine", "Oak", "Lakeview", "Sunset", "Forest", "River", "Spring", + "Main", "First", "Wind", "Park", "Maple", "Elm", "Cerulean" + }; + private static final String[] HOBBIES = { + "Hiking", "Skiing", "Swiming", "Bird watching", "Racing", "Walking", "Gaming", + }; + + private static final Random RANDOM = new Random(); + public static void main(String[] args) { - System.out.printf("Hello and welcome!"); + try { + int numOfDonors = 5000; + + Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD); + insertDonors(conn, numOfDonors); + conn.close(); + + System.out.println("Insertions to Donors were successful"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + private static void insertDonors(Connection conn, int count) throws SQLException { + String sql = "INSERT INTO Donors (donorID, firstName, lastName, middleInitial, dateOfBirth, address, city, postalCode, province, gender, SSN, hobby, phone, email) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + PreparedStatement pstmt = conn.prepareStatement(sql); + + for (int i = 1; i <= count; i++) { + pstmt.setInt(1, i); // donorID + pstmt.setString(2, randomString(5)); + pstmt.setString(3, randomString(7)); + pstmt.setString(4, randomInitial()); + pstmt.setDate(5, randomDateOfBirth()); + pstmt.setString(6, randomAddress()); + pstmt.setString(7, randomCities()); // city (static data for simplicity) + pstmt.setString(8, randomPostalCode()); // postalCode (static data for simplicity) + pstmt.setString(9, randomProvince()); // province + pstmt.setString(10, randomGender()); // gender + pstmt.setString(11, randomSSN()); // SSN + pstmt.setString(12, randomHobbies()); // hobby (static data for simplicity) + pstmt.setString(13, "1234567890"); // phone (static data for simplicity) + pstmt.setString(14, "email" + i + "@example.com"); // email (static data for simplicity) + + pstmt.addBatch(); + } + + pstmt.executeBatch(); // Execute all inserts as a batch + pstmt.close(); + } + + private static String randomString(int length) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < length; i++) { + char c = (char) (RANDOM.nextInt(26) + 'a'); + sb.append(c); + } + return sb.toString(); + } + + private static String randomInitial() { + return RANDOM.nextBoolean() ? String.valueOf((char) (RANDOM.nextInt(26) + 'a')) : null; + } + + private static java.sql.Date randomDateOfBirth() { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, 1950 + RANDOM.nextInt(50)); // Random year between 1950 and 1999 + calendar.set(Calendar.MONTH, RANDOM.nextInt(12)); // Random month + calendar.set(Calendar.DAY_OF_MONTH, RANDOM.nextInt(28) + 1); // Random day (considering 28 days in a month) + return new java.sql.Date(calendar.getTimeInMillis()); + } + + public static String randomAddress() { + int civicNumber = RANDOM.nextInt(1000) + 1; // Random number between 1 and 1000 + String streetName = STREET_NAMES[RANDOM.nextInt(STREET_NAMES.length)]; // Random street name + + return civicNumber + " " + streetName + " Street"; + } + + private static String randomProvince() { + return PROVINCES[RANDOM.nextInt(PROVINCES.length)]; + } + + private static String randomGender() { + return GENDERS[RANDOM.nextInt(GENDERS.length)]; + } + + private static String randomCities() { + return CITIES[RANDOM.nextInt(CITIES.length)]; + } + + private static String randomHobbies() { + return HOBBIES[RANDOM.nextInt(HOBBIES.length)]; + } + + private static String randomSSN() { + StringBuilder sb = new StringBuilder(); + sb.append(RANDOM.nextInt(999) + 1).append("-"); + sb.append(RANDOM.nextInt(99) + 1).append("-"); + sb.append(RANDOM.nextInt(9999) + 1); + return sb.toString(); + } + + public static String randomPostalCode() { + StringBuilder postalCode = new StringBuilder(); + + // Generate first segment (letter digit letter) + postalCode.append((char) (RANDOM.nextInt(26) + 'A')); // First letter (A-Z) + postalCode.append(RANDOM.nextInt(10)); // First digit (0-9) + postalCode.append((char) (RANDOM.nextInt(26) + 'A')); // Second letter (A-Z) + + // Space separator (optional, in the Canadian postal code format) + postalCode.append(" "); + + // Generate second segment (digit letter digit) + postalCode.append(RANDOM.nextInt(10)); // First digit (0-9) + postalCode.append((char) (RANDOM.nextInt(26) + 'A')); // First letter (A-Z) + postalCode.append(RANDOM.nextInt(10)); // Second digit (0-9) + + return postalCode.toString(); } } \ No newline at end of file diff --git a/src/main/sql/0.sql b/src/main/sql/0.sql new file mode 100644 index 0000000..acbbe48 --- /dev/null +++ b/src/main/sql/0.sql @@ -0,0 +1,78 @@ +CREATE DATABASE assignment1; + +USE assignment1; + +CREATE TABLE Donors +( + donorID INT NOT NULL, + firstName VARCHAR(50) NOT NULL, + lastName VARCHAR(50) NOT NULL, + middleInitial CHAR(1), + dateOfBirth DATE, + address VARCHAR(100), -- might need to change to civic code only + city VARCHAR(50), + postalCode VARCHAR(7), + province ENUM ( + 'AB', -- Alberta + 'BC', -- British Columbia + 'MB', -- Manitoba + 'NB', -- New Brunswick + 'NL', -- Newfoundland and Labrador + 'NS', -- Nova Scotia + 'NT', -- Northwest Territories + 'NU', -- Nunavut + 'ON', -- Ontario + 'PE', -- Prince Edward Island + 'QC', -- Quebec + 'SK', -- Saskatchewan + 'YT' -- Yukon + ), + gender ENUM ('M', 'F', 'U'), + SSN VARCHAR(11), + hobby VARCHAR(100), + phone VARCHAR(15), + email VARCHAR(100), + CONSTRAINT donors_pk PRIMARY KEY (donorID) +); + +CREATE TABLE Donations +( + dID INT NOT NULL, + donorID INT NOT NULL, + date DATE NOT NULL, + type VARCHAR(7) NOT NULL, + amount DECIMAL(10, 2) NOT NULL, + CONSTRAINT donations_pk PRIMARY KEY (dID), + CONSTRAINT donations_donorID_fk FOREIGN KEY (donorID) REFERENCES Donors (donorID), + CONSTRAINT valid_donation_type CHECK (type IN ('money', 'product')) +); + +create table Products +( + pID INT NOT NULL, + description varchar(100), + date DATE NOT NULL, + price DECIMAL(10, 2) NOT NULL, + weight DECIMAL(5, 2) NOT NULL, + CONSTRAINT products_pk PRIMARY KEY (pID) +); + +CREATE TABLE Sales +( + sID INT NOT NULL, + date DATE NOT NULL, + amount DECIMAL(10, 2) NOT NULL, + totalWeight DECIMAL(10, 2) NOT NULL, + deliveryFee DECIMAL(10, 2) DEFAULT 0 NOT NULL, + CONSTRAINT sales_pk primary key (sID), + CONSTRAINT valid_delivery_fee CHECK (deliveryFee >= 0) +); + +CREATE TABLE SalesItems +( + sID INT NOT NULL, + pID INT NOT NULL, + PRIMARY KEY (sID, pID), + FOREIGN KEY (sID) REFERENCES Sales (sID), + FOREIGN KEY (pID) REFERENCES Products (pID) +); diff --git a/src/main/sql/migrate0.sql b/src/main/sql/migrate0.sql deleted file mode 100644 index 2ed145d..0000000 --- a/src/main/sql/migrate0.sql +++ /dev/null @@ -1,29 +0,0 @@ --- run these as postgres - --- Create the user 'minhtran' if it does not exist -DO -$$ - BEGIN - IF NOT EXISTS (SELECT - FROM pg_catalog.pg_roles - WHERE rolname = 'minhtran') THEN - CREATE ROLE minhtran LOGIN PASSWORD 'password'; - END IF; - END -$$; - --- Terminate all connections to the database -REVOKE CONNECT ON DATABASE assignment1 FROM PUBLIC; -SELECT pg_terminate_backend(pg_stat_activity.pid) -FROM pg_stat_activity -WHERE pg_stat_activity.datname = 'assignment1' - AND pid <> pg_backend_pid(); - --- Drop the database -DROP DATABASE IF EXISTS "assignment1"; - --- Create the new database -CREATE DATABASE "assignment1"; - --- Grant all privileges on the new database to 'minhtran' -GRANT ALL PRIVILEGES ON DATABASE "assignment1" TO minhtran; diff --git a/src/main/sql/migrate1.sql b/src/main/sql/migrate1.sql deleted file mode 100644 index f7a06e0..0000000 --- a/src/main/sql/migrate1.sql +++ /dev/null @@ -1,94 +0,0 @@ --- Run this as minh tran user - --- Create the schema if it doesn't exist -CREATE SCHEMA IF NOT EXISTS "assignment 1"; - --- Drop the domain canada_postal_code if it exists -DROP DOMAIN IF EXISTS canada_postal_code; - --- Drop the type canadian_province if it exists -DROP TYPE IF EXISTS canadian_province; - -CREATE DOMAIN canada_postal_code AS VARCHAR(7) - CHECK (VALUE ~ '^[A-Z]\d[A-Z]\s?\d[A-Z]\d$'); - -CREATE TYPE canadian_province AS ENUM ( - 'AB', -- Alberta - 'BC', -- British Columbia - 'MB', -- Manitoba - 'NB', -- New Brunswick - 'NL', -- Newfoundland and Labrador - 'NS', -- Nova Scotia - 'NT', -- Northwest Territories - 'NU', -- Nunavut - 'ON', -- Ontario - 'PE', -- Prince Edward Island - 'QC', -- Quebec - 'SK', -- Saskatchewan - 'YT' -- Yukon - ); - -CREATE TABLE "assignment 1".Donors -( - donorID INT NOT NULL, - firstName VARCHAR(50) NOT NULL, - lastName VARCHAR(50) NOT NULL, - middleInitial CHAR(1), - dateOfBirth DATE, - address VARCHAR(100), - city VARCHAR(50), - postalCode canada_postal_code, - province canadian_province, - gender CHAR(1), - SSN VARCHAR(11), - hobby VARCHAR(100), - phone VARCHAR(15), - email VARCHAR(100), - CONSTRAINT donors_pk PRIMARY KEY (donorID), - CONSTRAINT valid_canada_postal_code CHECK (postalCode ~ '^[A-Z]\d[A-Z]\s?\d[A-Z]\d$'), - CONSTRAINT valid_gender CHECK (gender IN ('M', 'F', 'O')), - CONSTRAINT valid_ssn CHECK (SSN ~ '^\d{3}-\d{3}-\d{3}$'), - CONSTRAINT valid_email CHECK (email ~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}$') -); - -CREATE TABLE "assignment 1".Donations -( - dID INT NOT NULL, - donorID INT NOT NULL, - date DATE NOT NULL, - type VARCHAR(7) NOT NULL, - amount DECIMAL(10, 2) NOT NULL, - CONSTRAINT donations_pk PRIMARY KEY (dID), - CONSTRAINT donations_donorID_fk FOREIGN KEY (donorID) REFERENCES "assignment 1".Donors (donorID), - CONSTRAINT valid_donation_type CHECK (type IN ('money', 'product')) -); - -create table "assignment 1".Products -( - pID INT NOT NULL, - description varchar(100), - date DATE NOT NULL, - price DECIMAL(10, 2) NOT NULL, - weight DECIMAL(5, 2) NOT NULL, - CONSTRAINT products_pk PRIMARY KEY (pID) -); - -CREATE TABLE "assignment 1".Sales -( - sID INT NOT NULL, - date DATE NOT NULL, - amount DECIMAL(10, 2) NOT NULL, - totalWeight DECIMAL(10, 2) NOT NULL, - deliveryFee DECIMAL(10, 2) DEFAULT 0 NOT NULL, - CONSTRAINT sales_pk primary key (sID), - CONSTRAINT valid_delivery_fee CHECK (deliveryFee >= 0) -); - -CREATE TABLE "assignment 1".SalesItems -( - sID INT NOT NULL, - pID INT NOT NULL, - PRIMARY KEY (sID, pID), - FOREIGN KEY (sID) REFERENCES "assignment 1".Sales (sID), - FOREIGN KEY (pID) REFERENCES "assignment 1".Products (pID) -);