#ifndef CONFIG_HPP_NEROSHOP//DATABASE_LUA_HPP_NEROSHOP // recommended to add unique identifier like _NEROSHOP to avoid naming collision with other libraries
//extern lua_State * lua_state;// (luaL_newstate());//static lua_State * lua_state;// (luaL_newstate());//(nullptr);//should I use extern ?//because its in a namespace, there may not be a need to use extern // extern is for declaration in .h and then defined in a .cpp file
//////////////////////////////
namespaceneroshop{
//namespace DB {
//class Lua {
//public:
//////////////////////////////
externlua_State*lua_state;// (luaL_newstate());//static lua_State * lua_state;// (luaL_newstate());//(nullptr);//should I use extern ?//because its in a namespace, there may not be a need to use extern // extern is for declaration in .h and then defined in a .cpp file
externlua_State*lua_state;// (luaL_newstate());//(nullptr);// extern is for declaration in .h and then defined in a .cpp file
#include<openssl/pem.h> // includes "openssl/evp.h" which includes "openssl/bio.h"
#include<openssl/err.h>
#include<iostream>
#include<fstream>
#include<sstream>
@ -19,12 +20,9 @@ public:
staticboolgenerate_key_pair();
staticboolgenerate_key_pair_ex();// requires openssl 3.0 // the _ex suffix is for extended versions of existing functions//static bool generate_public_key_from_private_key();
staticstd::stringpublic_encrypt(conststd::string&public_key,conststd::string&plain_text);// encrypts plain text with a receiver's public key then returns a cipher text otherwise it returns an empty string on failure
staticstd::stringprivate_decrypt(conststd::string&private_key,conststd::string&cipher_text);// decrypts cipher text using the receiver's private key then returns a plain text otherwise it returns an empty string on failure
#include<process.hpp> // to open daemon process //#include "script.hpp"
#include<message.hpp>
#include<progressbar.hpp>
#include<iostream>
#include<string>
#include<vector>
#include<utility> // std::pair
#include<cmath>
#include"process.hpp" // for monerod daemon process
#include"message.hpp"
namespaceneroshop{
// this wallet class is only meant for creating and loading wallets, generating subaddresses, and listening to transactions. sending transactions? not so much - more focused on receiving
classWallet:publicmonero_wallet_listener{
public:
Wallet();
Wallet(conststd::string&file);// include .keys
~Wallet();
// wallet-related functions
voidconnect();// connect to a hw
voidcreate(std::stringpassword=""/*, const std::string& confirm_pw*/);// creates a new wallet
voidcreate_from_mnemonic(conststd::string&mnemonic,std::stringpassword=""/*, const std::string &confirm_pw*/);// create wallet from mnemonic phrase
voidcreate_from_keys(conststd::string&address,conststd::string&view_key,conststd::string&spend_key,std::stringpassword=""/*, const std::string &confirm_pw*/);// create wallet from address, view_key, and spend_key
std::stringupload(boolopen=true,std::stringpassword="");// change to mainnet later
// NOTE: use address_new to automatically generate a unique subaddress for each customer to make it easier to track who and where the payments are coming from
std::pair<std::string,std::string>get_viewkey(conststd::string&password)const;// secret, public // "viewkey"
std::pair<std::string,std::string>get_spendkey(conststd::string&password)const;// secret, public // "spendkey"
BIO*bio_private=BIO_new_file("private.pem","w+");// or .key
if(PEM_write_bio_PKCS8PrivateKey(bio_private,const_cast<EVP_PKEY*>(pkey),nullptr,nullptr,0,nullptr,nullptr)!=1){// same as PEM_write_bio_PrivateKey - both use PKCS#8 format which supports all algorithms including RSA // to-do: add encryption e.g: EVP_aes_256_cbc() (in arg 3) using a passphrase/password (in arg 4) and passphrase_len (in arg 5)
BIO*bio_private=BIO_new_file(filename.c_str(),"w+");// or .key
if(PEM_write_bio_PKCS8PrivateKey(bio_private,const_cast<EVP_PKEY*>(pkey),nullptr,nullptr,0,nullptr,nullptr)!=1){// same as PEM_write_bio_PrivateKey - both use PKCS#8 format which supports all algorithms including RSA // to-do: add encryption e.g: EVP_aes_256_cbc() (in arg 3) using a passphrase/password (in arg 4) and passphrase_len (in arg 5)
////std::cout << database->get_text_params("SELECT name FROM users WHERE id = $1", { "1" }) << std::endl;
// Modify new row
//database->execute_params("SELECT * FROM users WHERE id = $1 AND name = $2", { "1", "dude" });
//-------------------------
// todo: store this code in a initialize_database function
database->execute("BEGIN;");
//-------------------------
// table: account_type
/*if(!database->table_exists("account_type")) {
database->execute("CREATE TABLE account_type(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);");
database->execute("ALTER TABLE account_type ADD COLUMN name TEXT");
database->execute("INSERT INTO account_type(name) VALUES('Buyer');");
database->execute("INSERT INTO account_type(name) VALUES('Seller');");
}*/
//-------------------------
// users
// if 2 users share the same id or name then the raft consensus protocol must decide whether t
if(!database->table_exists("users")){// todo: rename "users" to "peers" or create a separate peers table
database->execute("CREATE TABLE users(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);");
////database->execute("ALTER TABLE users ADD COLUMN name TEXT;"); // mostly suitable for centralized or federated apps
database->execute("ALTER TABLE users ADD COLUMN key TEXT;");// verify_key - public_key used for verification of signatures
////database->execute("ALTER TABLE users ADD COLUMN verify_key TEXT;"); // verify_key - public_key used for verification of signatures
////database->execute("ALTER TABLE users ADD COLUMN encrypt_key TEXT;"); // encrypt_key - public_key used for encryption of messages
////database->execute("CREATE UNIQUE INDEX index_user_names ON users (name);");
database->execute("CREATE UNIQUE INDEX index_user_auth_keys ON users (key);");//database->execute("CREATE UNIQUE INDEX index_users ON users (name, verify_key, encrypt_key);");// enforce that the user names are unique, in case there is an attempt to insert a new "name" of the same value
////database->execute("CREATE UNIQUE INDEX index_verify_keys ON users (verify_key);");//database->execute("CREATE UNIQUE INDEX index_users ON users (name, verify_key, encrypt_key);");// enforce that the user names are unique, in case there is an attempt to insert a new "name" of the same value
////database->execute("CREATE UNIQUE INDEX index_encrypt_keys ON users (encrypt_key);");//database->execute("CREATE UNIQUE INDEX index_users ON users (name, verify_key, encrypt_key);");// enforce that the user names are unique, in case there is an attempt to insert a new "name" of the same value
// sellers require a username and buyers do not
// passwords will no longer be stored as salted bcrpyt hashes, only public keys will be stored
}
while(true){
std::stringshellinput;
std::cout<<"neroshop> ";
std::cin>>shellinput;
if(shellinput=="help"){std::cout<<"Available commands:\n\n help Display list of available commands\n\n exit Exit CLI\n\n";}
elseif(shellinput=="monero_nodes"){
for(std::stringn:nodes_list){
std::cout<<n<<std::endl;
}
//-------------------------
// products (items)
if(!database->table_exists("products")){
database->execute("CREATE TABLE products(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);");
database->execute("ALTER TABLE products ADD COLUMN name TEXT;");
database->execute("ALTER TABLE products ADD COLUMN description TEXT;");// desc or description
database->execute("ALTER TABLE products ADD COLUMN price REAL");//INTEGER;");//numeric(20, 12);"); // unit_price or price_per_unit // 64-bit integer (uint64_t) that will be multipled by a piconero to get the actual monero price
database->execute("ALTER TABLE products ADD COLUMN weight REAL;");// kg
//database->execute("ALTER TABLE products ADD COLUMN size ?datatype;"); // l x w x h
database->execute("ALTER TABLE products ADD COLUMN code TEXT;");// product_code can be either upc (universal product code) or a custom sku
database->execute("ALTER TABLE inventory ADD COLUMN stock_qty INTEGER;");// alternative names: "stock" or "stock_available"
database->execute("ALTER TABLE inventory ADD COLUMN sales_price REAL;");//numeric(20,12);"); // alternative names: "seller_price" or "list_price" // this is the final price of a product
database->execute("ALTER TABLE inventory ADD COLUMN currency TEXT;");// the fiat currency the seller is selling the item in
//database->execute("ALTER TABLE inventory ADD COLUMN discount numeric(20,12);"); // alternative names: "seller_discount", or "discount_price"
//database->execute("ALTER TABLE inventory ADD COLUMN ?col ?datatype;"); // discount_times_can_use - number of times the discount can be used
//database->execute("ALTER TABLE inventory ADD COLUMN ?col ?datatype;"); // discounted_items_qty - number of items that the discount will apply to
//database->execute("ALTER TABLE inventory ADD COLUMN ?col ?datatype;"); // discount_expiry - date and time that the discount expires (will be in UTC format)
//database->execute("ALTER TABLE cart_item ADD COLUMN item_price numeric;"); // sales_price will be used for the final pricing rather than the unit_price
database->execute("ALTER TABLE orders ADD COLUMN timestamp TEXT DEFAULT CURRENT_TIMESTAMP;");// creation_date // to get UTC time: set to datetime('now');
database->execute("ALTER TABLE orders ADD COLUMN number TEXT;");// uuid
database->execute("ALTER TABLE orders ADD COLUMN status TEXT;");
database->execute("ALTER TABLE orders ADD COLUMN user_id INTEGER REFERENCES users(id);");// the user that placed the order
//database->execute("ALTER TABLE orders ADD COLUMN weight REAL;"); // weight of all order items combined - not essential
database->execute("ALTER TABLE orders ADD COLUMN total numeric(20, 12);");
//database->execute("ALTER TABLE orders ADD COLUMN notes TEXT;"); // will contain sensative such as shipping address and tracking numbers that will be encrypted and can only be decrypted by the seller - this may not be necessary since buyer can contact seller privately
// order_item
database->execute("CREATE TABLE order_item(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);");
intcategory_id=database->get_integer("INSERT INTO categories (name, alt_names) VALUES ('Food', 'Grocery & Gourmet Foods; Produce') RETURNING id;");// Almost done :) // Food & Beverage in one category? nah
// subcategories here
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Canned Foods', $1)",{std::to_string(category_id)});// sub subcategory
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Condiments', $1)",{std::to_string(category_id)});// sweet and savory sauces // includes ketchup, mustard, mayonnaise, sour cream, barbecue sauce, compound butter, etc. // A condiment is a preparation that is added to food, typically after cooking, to impart a specific flavor, to enhance the flavor, or to complement the dish
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Confections', $1)",{std::to_string(category_id)});// confections or confectionery are sweets like cake, deserts, candies, marshmellows, and other food items that are sweet // sugar confections (aka sweets) = candy, baker/flour confection = cake, chocolate confection = hershey
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Dairy', $1)",{std::to_string(category_id)});// includes food items like cheese, milk, and yogurt
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Fish & Seafood', $1)",{std::to_string(category_id)});// includes fish, crab, and all other seafoods
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Food Additives - Sweeteners', $1)",{std::to_string(category_id)});// includes honey, maple syrup, raw sugar, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Frozen Foods', $1)",{std::to_string(category_id)});// sub subcategory
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Fruits', $1)",{std::to_string(category_id)});// includes berries, melons, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Grains, Breads & Cereals', $1)",{std::to_string(category_id)});// includes cereal, rice, oatmeal, pasta and traditional bakery like biscuits and bread (whole grains)
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Herbs & Spices', $1)",{std::to_string(category_id)});//include ginger, turmeric, cinnamon, cocoa powder, parsley, and basil, etc. // herbs are leafy things, like basil, tarragon, thyme, and cilantro; and spices are seeds, either whole or ground, like coriander, cumin, and anise. Leaves vs. seeds is indeed a simple version of the separation. But simple isn't always accurate.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Meat & Poutry', $1)",{std::to_string(category_id)});//Protein -// All poutry is meat, well since a bird and chicken are meat // fish should have its own subcategory // pescatarians - vegetarians who eat fish and no other flesh or meat
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Nuts, Seeds & Legumes', $1)",{std::to_string(category_id)});// a nut is a hard-shell containing a seed and a seed is without a shell // legumes are beans
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Organic Foods', $1)",{std::to_string(category_id)});// sub subcategory
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Processed Foods', $1)",{std::to_string(category_id)});// sub subcategory
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Proteins - Eggs', $1)",{std::to_string(category_id)});// eggs are neither dairy (since they don't come from milk, but laid by chickens) nor meat (eggs contain no animal flesh since they are unfertilized)
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Vegetables', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Vitamins & Dietary Supplements', $1)",{std::to_string(category_id)});//Nutritional and herbal supplements // includes bee pollen, matcha powder, protein powder, and powdered vitamin or mineral supplements, etc. // Dietary supplements can include a variety of components such as vitamins, minerals, herbs, amino acids, enzymes and other ingredients taken in various forms such as a pill, gel, capsule, gummy, powder, drink or food
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Alchoholic Beverages - Hard Liquors & Spirits', $1)",{std::to_string(category_id)});// spirits is another name for liquor (almost), both are distilled beverages and are usually put into these two categories: liquors and spirits // distilled rather than fermented alcoholic beverage
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Alchoholic Beverages - Beer', $1)",{std::to_string(category_id)});// beer is made from fermented grain
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Alchoholic Beverages - Wine', $1)",{std::to_string(category_id)});// most wine is produced by fermenting grape juice. However, you can’t just use any type of grape. You need wine grapes
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Coffee', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Juices', $1)",{std::to_string(category_id)});// lemonade included :} // lemonade could also be a carbonated drink :O // is smoothie a juice? :O
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Milk or milk-based', $1)",{std::to_string(category_id)});// milkshake, most hot chocolate and some protein shake included :}
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Mixed drinks', $1)",{std::to_string(category_id)});// cocktail is a mixed drink with a mix of alcohol, fruit juice, soda, etc. :O // what about smoothies? :O
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Soft drinks', $1)",{std::to_string(category_id)});// soda
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Sports & Energy drinks', $1)",{std::to_string(category_id)});// sports drinks like gatorade and energy drinks like red bull
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Tea', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Water - Carbonated', $1)",{std::to_string(category_id)});// same thing as sparkling water
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Water - Non-carbonated', $1)",{std::to_string(category_id)});// regular drinking water
//---------------------------
// category here
category_id=database->get_integer("INSERT INTO categories (name, alt_names) VALUES ('Electronics', '') RETURNING id;");// aka Consumer Electronics or Hardware
// subcategories here
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Appliances', $1)",{std::to_string(category_id)});// Home Appliances
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Appliances - Dishwashers', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Appliances - Heating, Cooling & Air Quality Appliances', $1)",{std::to_string(category_id)});// air conditioners, heaters
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Appliances - Home Appliance Warranties', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Appliances - Kitchen Small Appliances', $1)",{std::to_string(category_id)});// blenders, toasters, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Appliances - Laundry Appliances', $1)",{std::to_string(category_id)});// washing machines, dryers, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('AC Adapters, Chargers, Power strips, & Converters', $1)",{std::to_string(category_id)});// includes chargers, power outlet (wall) chargers, universal power adapters / Travel Adapters & Converters, power strips, voltage converters, power banks, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Computer Parts & Hardware', $1)",{std::to_string(category_id)});// or Computer Hardware
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Entertainment - 3D Glasses', $1)",{std::to_string(category_id)});// Entertainment or TV & Theater
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Entertainment - CD, DVD and Blu-ray players', $1)",{std::to_string(category_id)});// Blu-ray, is a digital optical disc storage format. It is designed to supersede the DVD format
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Entertainment - ', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Entertainment - ', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Electronic Musical Instruments', $1)",{std::to_string(category_id)});// includes Audio Interfaces, Electronic Drums, Digital Synthesizers and Midi Controllers, Microphones, Studio Monitors, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Hardware - ', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Industrial & Scientific - Electronic Measurement Devices', $1)",{std::to_string(category_id)});// scales, calipers, etc. // Industrial & Scientific will have its own main category
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('', $1)",{std::to_string(category_id)});
////database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Lighting - Lamps, Lightbulbs', $1)", { std::to_string(category_id) }); // reading lamps, etc. // put this in Home Tools & Improvements category
//database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Lawn Mowers', $1)", { std::to_string(category_id) }); // reading lamps, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Peripherals', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Peripherals - Headsets', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Peripherals - Microphone', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Peripherals - Mouse', $1)",{std::to_string(category_id)});// dont forget touchpad and pen input, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Peripherals - Keyboards', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Peripherals - Monitors', $1)",{std::to_string(category_id)});// screen - led, lcd, ctr, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Peripherals - Power Adapters', $1)",{std::to_string(category_id)});// laptop power adaptors
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Hardware - Ports, Jacks, Slots, Sockets & Connectors', $1)",{std::to_string(category_id)});// includes audio jacks, usb ports, microSD card reader, etc. // all plugs and ports are connectors
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Portable Media Devices', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Portable Media Devices - ', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Portable Media Devices - CB & Two-way Radio', $1)",{std::to_string(category_id)});// walkie-talkies
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Portable Media Devices - ', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Portable Media Devices - Media Players', $1)",{std::to_string(category_id)});// portable mp3 players, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Portable Media Devices - ', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Printers - 3D Printers', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Printers - Inkjet Printers', $1)",{std::to_string(category_id)});// single function printers only print while multi-function printers can print, scan, copy, and fax
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Printers, Scanners, Copiers, & Fax machines', $1)",{std::to_string(category_id)});// single function printers only print while multi-function printers can print, scan, copy, and fax
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Storage Media', $1)",{std::to_string(category_id)});// includes hard disk drives (hdd), solid state drives (ssd), m.2 ssd, network attached storage (nas), etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Storage Media - Cassette Tapes', $1)",{std::to_string(category_id)});// small ones for audio, big ones for video
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Storage Media - CDs/DVDs/Blu-rays', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Storage Media - Floppy Disks', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Storage Media - Game Discs & ROM Catridges', $1)",{std::to_string(category_id)});// aka game cartridge, cart, or card
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Storage Media - Hard disk drives (HDD), Solid state drives (SSD)', $1)",{std::to_string(category_id)});// includes hdd, sdd, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Storage Media - Memory Cards', $1)",{std::to_string(category_id)});// includes sd cards, card readers
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Storage Media - USB Flash Drives', $1)",{std::to_string(category_id)});// flash memory
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Tablets', $1)",{std::to_string(category_id)});// includes ipad, android tablets, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Tablets - Graphics and Drawing Tablets', $1)",{std::to_string(category_id)});// includes pen tablets (without a screen) and graphics tablets like wacom, etc. // https://www.autopano.net/types-of-drawing-tablets/
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Toys & Games', $1)",{std::to_string(category_id)});// toys and games should have a category of its own
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Toys & Games - Electronic Toys', $1)",{std::to_string(category_id)});// includes electric car toys, remote control cars, drones, robots, etc. // toys and games should have a category of its own
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Video Game Consoles, Games & Accessories', $1)",{std::to_string(category_id)});// includes video game controllers, remote controllers, headsets, virtual reality headsets (PSVR), covers, etc.
category_id=database->get_integer("INSERT INTO categories (name, alt_names) VALUES ('Digital Goods', '') RETURNING id;");// DONE :D! // SELECT * FROM subcategories WHERE category_id = $1;--ORDER BY name;
// subcategories here
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Codes - Cheat codes and hacks', $1)",{std::to_string(category_id)});// replace "Codes" with "Information" anaa? :O // includes hacked information and leaks
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Codes - Discount and coupons', $1)",{std::to_string(category_id)});// discounts, coupons/vouchers, promo codes etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Codes - Gift cards', $1)",{std::to_string(category_id)});// gift certificates included
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Codes - Membership and subscription cards', $1)",{std::to_string(category_id)});// PSN Membership card, PS+ subscription card, Xbox Live cards, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Codes - Prepaid cards', $1)",{std::to_string(category_id)});// A prepaid card is not linked to a bank checking account or to a credit union share draft account. Instead, you are spending money you placed in the prepaid card account in advance. This is sometimes called “loading money onto the card”.// For hacked credit cards, this subcategory can be used >:D JK!
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Digital Art', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('eBooks', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Freelancing', $1)",{std::to_string(category_id)});// sell your personal services online in a gig-economy and work from home // freelancing is different and better than remote work cuz you are your own boss // Gigs are also known as “freelancing” and “independent contracting” jobs
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Information - Online accounts', $1)",{std::to_string(category_id)});// includes online accounts such as video game accounts, netflix accounts, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Media - Audio', $1)",{std::to_string(category_id)});// sound, video, text, etc. // Multimedia is the combined use of sound, video, and text to present an idea
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Media - Documents', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Media - Photos', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Media - Videos', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Software', $1)",{std::to_string(category_id)});// general software
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Video Games', $1)",{std::to_string(category_id)});// video games are softwares with their own category :O
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Virtual Goods - In-Game content', $1)",{std::to_string(category_id)});// video game/virtual avatars, items, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Virtual Goods - NFTs', $1)",{std::to_string(category_id)});// NFTs can be more than just art ranging from Fashion and wearables, DeFi, Events and ticketing, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Websites and Domain names', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Bottomwear', $1)",{std::to_string(category_id)});// pants/trousers/jeans, shorts, skirts, miniskirts, leggings, breeches, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Cookwear - Aprons & Bibs', $1)",{std::to_string(category_id)});// kappōgis, pinafores, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Costumes & Cosplay', $1)",{std::to_string(category_id)});// costumes, reanactment and theater, and masks too
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Textiles', $1)",{std::to_string(category_id)});// cloth pieces, fabrics:knitted, woven, and non-woven, silk, cotton, leather, etc. // https://www.masterclass.com/articles/28-types-of-fabrics-and-their-uses#28-different-types-of-fabric //
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Topwear - Shirts & Tops', $1)",{std::to_string(category_id)});// tees, tank-tops/singlets, vests, coats, sweaters, and jackets, cardigans
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Topwear', $1)",{std::to_string(category_id)});// tees, tank-tops/singlets, vests, coats, sweaters, and jackets, cardigans
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Traditional Wear', $1)",{std::to_string(category_id)});// kimonos, kilts, sari(s), hwarots, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Underwear', $1)",{std::to_string(category_id)});// slips, panties and boxers, bras, other undergarments
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Uniforms & Work Clothing', $1)",{std::to_string(category_id)});// school uniforms, police uniforms, etc.
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Unisex', $1)",{std::to_string(category_id)});
database->execute_params("INSERT INTO subcategories (name, category_id) VALUES ('Waistwear - Belts & Suspenders', $1)",{std::to_string(category_id)});// belts, sashes like obi, karate belts, etc.
category_id=database->get_integer("INSERT INTO categories (name, alt_names) VALUES ('Cosmetics', 'Beauty & Personal Care') RETURNING id;");// skin and hair care
// to prevent duplicating item_id that is being sold by the same seller_id (a seller cannot list the same item twice, except change the stock amount)
intlisted_item=database->get_integer_params("SELECT item_id FROM inventory WHERE item_id = $1 AND seller_id = $2",{std::to_string(item_id),std::to_string(get_id())});
if(listed_item==item_id){
@ -45,11 +45,11 @@ void neroshop::Seller::list_item(unsigned int item_id, unsigned int stock_qty, d
return;
}
// begin transaction - this is not necessary since it is just a single operation
DB::Postgres::get_singleton()->execute_params("DELETE FROM inventory WHERE item_id = $1 AND seller_id = $2",{std::to_string(item_id),std::to_string(get_id())});// update item stock to 0 beforehand or nah?
db::Postgres::get_singleton()->execute_params("DELETE FROM inventory WHERE item_id = $1 AND seller_id = $2",{std::to_string(item_id),std::to_string(get_id())});// update item stock to 0 beforehand or nah?
// get number of order_items to be purchased by customers from this particular seller
intseller_customer_order_item_count=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM order_item WHERE seller_id = $1",{std::to_string(get_id())});
intseller_customer_order_item_count=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM order_item WHERE seller_id = $1",{std::to_string(get_id())});
if(seller_customer_order_item_count<1){neroshop::print("No buyer has ordered an item from you yet");return;}
// load customer orders
std::stringcommand="SELECT order_id FROM order_item WHERE seller_id = $1 ORDER BY order_id";
unsignedintitem_id=DB::Postgres::get_singleton()->get_integer_params("SELECT item_id FROM order_item WHERE id = $1 AND seller_id = $2",{std::to_string(i),std::to_string(get_id())});
unsignedintitem_qty=DB::Postgres::get_singleton()->get_integer_params("SELECT item_qty FROM order_item WHERE id = $1 AND seller_id = $2",{std::to_string(i),std::to_string(get_id())});
unsignedintitem_id=db::Postgres::get_singleton()->get_integer_params("SELECT item_id FROM order_item WHERE id = $1 AND seller_id = $2",{std::to_string(i),std::to_string(get_id())});
unsignedintitem_qty=db::Postgres::get_singleton()->get_integer_params("SELECT item_qty FROM order_item WHERE id = $1 AND seller_id = $2",{std::to_string(i),std::to_string(get_id())});
Itemitem(item_id);// item obj will die at the end of this scope
std::cout<<"You've received an order (id: "<<order_id<<") from a customer "
}//DB::Postgres::get_singleton()->get_integer_params("SELECT item_id FROM order_item WHERE id = $1 AND seller_id = $2", { std::to_string(i), std::to_string(get_id()) });
}//db::Postgres::get_singleton()->get_integer_params("SELECT item_id FROM order_item WHERE id = $1 AND seller_id = $2", { std::to_string(i), std::to_string(get_id()) });
boolis_pending=DB::Postgres::get_singleton()->get_integer_params("SELECT id FROM orders WHERE id = $1 AND status = $2",{std::to_string(customer_order_id),"Pending"});
boolis_pending=db::Postgres::get_singleton()->get_integer_params("SELECT id FROM orders WHERE id = $1 AND status = $2",{std::to_string(customer_order_id),"Pending"});
if(is_pending){
std::cout<<"You have received a new customer order (status: PENDING)"<<std::endl;// for terminal
neroshop::Message::get_first()->set_text("You have received a new customer order (status: PENDING)");//\n Do you wish to proceed with this order?");
@ -249,7 +249,7 @@ void neroshop::Seller::set_stock_quantity(unsigned int item_id, unsigned int sto
// a seller can create an item and then register it to the database
if(item_id<=0){NEROSHOP_TAG_OUTstd::cout<<"\033[0;91m"<<"Could not set stock_qty (invalid Item id)"<<"\033[0m"<<std::endl;return;}
/*// update stock_qty in database
DB::Sqlite3db("neroshop.db");
db::Sqlite3db("neroshop.db");
//db.execute("PRAGMA journal_mode = WAL;"); // this may reduce the incidence of SQLITE_BUSY errors (such as database being locked)
if(db.table_exists("inventory"))
db.update("inventory","stock_qty",std::to_string(stock_qty),"item_id = "+std::to_string(item_id)+" AND seller_id = "+std::to_string(get_id()));
@ -258,9 +258,9 @@ void neroshop::Seller::set_stock_quantity(unsigned int item_id, unsigned int sto
DB::Postgres::get_singleton()->execute_params("UPDATE inventory SET stock_qty = $1 WHERE item_id = $2 AND seller_id = $3",{std::to_string(stock_qty),std::to_string(item_id),std::to_string(get_id())});
std::stringitem_name=DB::Postgres::get_singleton()->get_text_params("SELECT name FROM item WHERE id = $1",{std::to_string(item_id)});
db::Postgres::get_singleton()->execute_params("UPDATE inventory SET stock_qty = $1 WHERE item_id = $2 AND seller_id = $3",{std::to_string(stock_qty),std::to_string(item_id),std::to_string(get_id())});
std::stringitem_name=db::Postgres::get_singleton()->get_text_params("SELECT name FROM item WHERE id = $1",{std::to_string(item_id)});
neroshop::print("\""+item_name+"\"'s stock has been updated",3);
unsignedintgood_ratings_count=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(score) FROM seller_ratings WHERE seller_id = $1 AND score = $2",{std::to_string(get_id()),std::to_string(1)});
unsignedintgood_ratings_count=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(score) FROM seller_ratings WHERE seller_id = $1 AND score = $2",{std::to_string(get_id()),std::to_string(1)});
returngood_ratings_count;
////////////////////////////////
@ -313,7 +313,7 @@ unsigned int neroshop::Seller::get_good_ratings() const {
unsignedintbad_ratings_count=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(score) FROM seller_ratings WHERE seller_id = $1 AND score = $2",{std::to_string(get_id()),std::to_string(0)});
unsignedintbad_ratings_count=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(score) FROM seller_ratings WHERE seller_id = $1 AND score = $2",{std::to_string(get_id()),std::to_string(0)});
returnbad_ratings_count;
////////////////////////////////
@ -334,7 +334,7 @@ unsigned int neroshop::Seller::get_bad_ratings() const {
unsignedintratings_count=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM seller_ratings WHERE seller_id = $1",{std::to_string(get_id())});
unsignedintratings_count=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM seller_ratings WHERE seller_id = $1",{std::to_string(get_id())});
returnratings_count;
////////////////////////////////
@ -359,7 +359,7 @@ unsigned int neroshop::Seller::get_total_ratings() const {
unsignedintratings_count=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM seller_ratings WHERE seller_id = $1",{std::to_string(get_id())});
unsignedintratings_count=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM seller_ratings WHERE seller_id = $1",{std::to_string(get_id())});
if(ratings_count==0){return0;}// seller has not yet been rated so his or her reputation will be 0%
// get seller's good ratings
unsignedintgood_ratings=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(score) FROM seller_ratings WHERE seller_id = $1 AND score = $2",{std::to_string(get_id()),std::to_string(1)});
unsignedintgood_ratings=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(score) FROM seller_ratings WHERE seller_id = $1 AND score = $2",{std::to_string(get_id()),std::to_string(1)});
@ -396,7 +396,7 @@ std::vector<unsigned int> neroshop::Seller::get_top_rated_sellers(unsigned int l
// ISSUE: both seller_4 and seller_1 have the same number of 1_score_values but seller_1 has the highest reputation and it places seller_4 first [solved - by using reputation in addition]
std::stringcommand="SELECT users.id FROM users JOIN seller_ratings ON users.id = seller_ratings.seller_id WHERE score = 1 GROUP BY users.id ORDER BY COUNT(score) DESC LIMIT $1;";
neroshop::print("Seller::get_top_rated_sellers(): No sellers found",2);
PQclear(result);
@ -407,9 +407,9 @@ std::vector<unsigned int> neroshop::Seller::get_top_rated_sellers(unsigned int l
for(inti=0;i<rows;i++){
intseller_id=std::stoi(PQgetvalue(result,i,0));
// calculate the reputation of each seller_id
unsignedintratings_count=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM seller_ratings WHERE seller_id = $1",{std::to_string(seller_id)});
unsignedintratings_count=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM seller_ratings WHERE seller_id = $1",{std::to_string(seller_id)});
if(ratings_count==0)continue;// seller has not yet been rated so his or her reputation will be 0%. Skip this seller
intgood_ratings=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(score) FROM seller_ratings WHERE seller_id = $1 AND score = $2",{std::to_string(seller_id),std::to_string(1)});
intgood_ratings=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(score) FROM seller_ratings WHERE seller_id = $1 AND score = $2",{std::to_string(seller_id),std::to_string(1)});
intpending_orders=DB::Postgres::get_singleton()->get_integer_params("SELECT id FROM orders WHERE id = $1 AND status = $2",{std::to_string(customer_order_list[i]),"Pending"});
intpending_orders=db::Postgres::get_singleton()->get_integer_params("SELECT id FROM orders WHERE id = $1 AND status = $2",{std::to_string(customer_order_list[i]),"Pending"});
// should item not be considered sold until the order is done processing or nah ?
intitems_sold=DB::Postgres::get_singleton()->get_integer_params("SELECT SUM(item_qty) FROM order_item WHERE seller_id = $1;",{std::to_string(get_id())});
intitems_sold=db::Postgres::get_singleton()->get_integer_params("SELECT SUM(item_qty) FROM order_item WHERE seller_id = $1;",{std::to_string(get_id())});
returnitems_sold;
#endif
return0;
@ -513,7 +513,7 @@ unsigned int neroshop::Seller::get_sales_count() const {
intunits_sold=DB::Postgres::get_singleton()->get_integer_params("SELECT SUM(item_qty) FROM order_item WHERE item_id = $1 AND seller_id = $2",{std::to_string(item_id),std::to_string(get_id())});
intunits_sold=db::Postgres::get_singleton()->get_integer_params("SELECT SUM(item_qty) FROM order_item WHERE item_id = $1 AND seller_id = $2",{std::to_string(item_id),std::to_string(get_id())});
returnunits_sold;
#endif
return0;
@ -525,7 +525,7 @@ unsigned int neroshop::Seller::get_units_sold(const neroshop::Item& item) const
////////////////////
doubleneroshop::Seller::get_sales_profit()const{
#if defined(NEROSHOP_USE_POSTGRESQL)
doubleprofit_from_sales=DB::Postgres::get_singleton()->get_real_params("SELECT SUM(item_price * item_qty) FROM order_item WHERE seller_id = $1;",{std::to_string(get_id())});//neroshop::print("The overall profit made from all sales combined is: $" + std::to_string(profit_from_sales), 3);
doubleprofit_from_sales=db::Postgres::get_singleton()->get_real_params("SELECT SUM(item_price * item_qty) FROM order_item WHERE seller_id = $1;",{std::to_string(get_id())});//neroshop::print("The overall profit made from all sales combined is: $" + std::to_string(profit_from_sales), 3);
doubleitem_profits=DB::Postgres::get_singleton()->get_real_params("SELECT SUM(item_price * item_qty) FROM order_item WHERE item_id = $1 AND seller_id = $2;",{std::to_string(item_id),std::to_string(get_id())});//std::string item_name = DB::Postgres::get_singleton()->get_text_params("SELECT name FROM item WHERE id = $1", { std::to_string(item_id) });neroshop::print("The overall profit made from \"" + item_name + "\" is: $" + std::to_string(item_profits), 3);
doubleitem_profits=db::Postgres::get_singleton()->get_real_params("SELECT SUM(item_price * item_qty) FROM order_item WHERE item_id = $1 AND seller_id = $2;",{std::to_string(item_id),std::to_string(get_id())});//std::string item_name = db::Postgres::get_singleton()->get_text_params("SELECT name FROM item WHERE id = $1", { std::to_string(item_id) });neroshop::print("The overall profit made from \"" + item_name + "\" is: $" + std::to_string(item_profits), 3);
unsignedintneroshop::Seller::get_item_id_with_most_sales()const{// this function is preferred over the "_by_mode" version as it provides the most accurate best-selling item_id result
#if defined(NEROSHOP_USE_POSTGRESQL)
// get the item with the biggest quantity sold (returns multiple results but I've limited it to 1)
intitem_with_biggest_qty=DB::Postgres::get_singleton()->get_integer_params("SELECT item_id FROM order_item WHERE seller_id = $1 GROUP BY item_id ORDER BY SUM(item_qty) DESC LIMIT 1;",{std::to_string(get_id())});// from the biggest to smallest sum of item_qty
intitem_with_biggest_qty=db::Postgres::get_singleton()->get_integer_params("SELECT item_id FROM order_item WHERE seller_id = $1 GROUP BY item_id ORDER BY SUM(item_qty) DESC LIMIT 1;",{std::to_string(get_id())});// from the biggest to smallest sum of item_qty
#ifdef NEROSHOP_DEBUG
std::stringitem_name=DB::Postgres::get_singleton()->get_text_params("SELECT name FROM item WHERE id = $1",{std::to_string(item_with_biggest_qty)});
std::stringitem_name=db::Postgres::get_singleton()->get_text_params("SELECT name FROM item WHERE id = $1",{std::to_string(item_with_biggest_qty)});
neroshop::print("\""+item_name+"\" is your best-selling item with a sale of "+std::to_string(get_units_sold(item_with_biggest_qty))+" units",3);
#endif
returnitem_with_biggest_qty;
@ -559,10 +559,10 @@ unsigned int neroshop::Seller::get_item_id_with_most_sales() const { // this fun
// get the item with the most occurences in all orders - if two items are the most occuring then it will select the lowest item_id of the two (unless I add DESC)
intitem_with_most_occurrences=DB::Postgres::get_singleton()->get_integer_params("SELECT MODE() WITHIN GROUP (ORDER BY item_id) FROM order_item WHERE seller_id = $1;",{std::to_string(get_id())});
intitem_with_most_occurrences=db::Postgres::get_singleton()->get_integer_params("SELECT MODE() WITHIN GROUP (ORDER BY item_id) FROM order_item WHERE seller_id = $1;",{std::to_string(get_id())});
#ifdef NEROSHOP_DEBUG
std::stringitem_name=DB::Postgres::get_singleton()->get_text_params("SELECT name FROM item WHERE id = $1",{std::to_string(item_with_most_occurrences)});
inttimes_occured=DB::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM order_item WHERE item_id = $1 AND seller_id = $2;",{std::to_string(item_with_most_occurrences),std::to_string(get_id())});
std::stringitem_name=db::Postgres::get_singleton()->get_text_params("SELECT name FROM item WHERE id = $1",{std::to_string(item_with_most_occurrences)});
inttimes_occured=db::Postgres::get_singleton()->get_integer_params("SELECT COUNT(*) FROM order_item WHERE item_id = $1 AND seller_id = $2;",{std::to_string(item_with_most_occurrences),std::to_string(get_id())});
neroshop::print("\""+item_name+"\" is your most ordered item occuring a total of "+std::to_string(times_occured)+" times in all orders",2);
#endif
returnitem_with_most_occurrences;
@ -579,7 +579,7 @@ unsigned int neroshop::Seller::get_item_id_with_most_orders() const {
boollisted=(DB::Postgres::get_singleton()->get_text_params("SELECT EXISTS(SELECT item_id FROM inventory WHERE item_id = $1 AND seller_id = $2);",{std::to_string(item_id),std::to_string(get_id())})=="t")?true:false;
boollisted=(db::Postgres::get_singleton()->get_text_params("SELECT EXISTS(SELECT item_id FROM inventory WHERE item_id = $1 AND seller_id = $2);",{std::to_string(item_id),std::to_string(get_id())})=="t")?true:false;
boolin_stock=(DB::Postgres::get_singleton()->get_text_params("SELECT EXISTS(SELECT item_id FROM inventory WHERE item_id = $1 AND seller_id = $2 AND stock_qty > 0);",{std::to_string(item_id),std::to_string(get_id())})=="t")?true:false;
boolin_stock=(db::Postgres::get_singleton()->get_text_params("SELECT EXISTS(SELECT item_id FROM inventory WHERE item_id = $1 AND seller_id = $2 AND stock_qty > 0);",{std::to_string(item_id),std::to_string(get_id())})=="t")?true:false;
dynamic_cast<Seller*>(user)->set_logged(true);// protected, so can only be accessed by child class obj // if validator::login(user, pw) returns true, then set neroshop::User::logged to true
#if defined(NEROSHOP_USE_POSTGRESQL)
intuser_id=DB::Postgres::get_singleton()->get_integer_params("SELECT id FROM users WHERE name = $1",{username});
intuser_id=db::Postgres::get_singleton()->get_integer_params("SELECT id FROM users WHERE name = $1",{username});
database->execute_params("INSERT INTO users(verify_key) VALUES($1);",{public_key});//database->execute_params("INSERT INTO users(name, verify_key) VALUES($1, $2);", { user_id, public_key });//database->execute_params("INSERT INTO users(name, verify_key, encrypt_key) VALUES($1, $2, $3);", { user_id, public_key });
// Save private_key locally on the user's device
Encryptor::save_private_key(pkey,NEROSHOP_CONFIG_PATH+"/secret.key");//"/keys/private.key"); // alternative names: secret.key, verify.key or private.key
// Display notification message
std::stringsha256sum;
generate_sha256_hash(public_key,sha256sum);
std::stringuser_id=sha256sum;
neroshop::print((!user_id.empty())?std::string("Welcome to neroshop, user "+user_id):"Welcome to neroshop",4);
// free up the pkey
EVP_PKEY_free(pkey);
////EVP_PKEY_CTX_free(ctx);
returntrue;
}
////////////////////
boolneroshop::Validator::login_peer(){
// user will supply their id or name or public key (verify_key)
// message will be signed using user's public_key (verify_key)
// verify that public_key matches private_key (verify_key)
monero_wallet_obj=std::unique_ptr<monero_wallet_full>(monero_wallet_full::create_wallet_from_mnemonic("","",network_type,mnemonic));// set path to "" for an in-memory wallet
monero_wallet_obj=std::unique_ptr<monero_wallet_full>(monero_wallet_full::create_wallet_from_keys("","",network_type,primary_address,view_key,spend_key));// set path to "" for an in-memory wallet
monero_wallet_obj=std::unique_ptr<monero_wallet_full>(monero::monero_wallet_full::open_wallet(path,password,network_type));// will apply ".keys" ext to the wallet file
if(!monero::monero_wallet_full::wallet_exists(filename+".keys")){neroshop::print("wallet not found",1);return"";}// check if wallet file is valid (or exists)
if(open==true)neroshop::Wallet::open(filename,password);// will re-apply ".keys" ext to the wallet file
if(open==true)neroshop::Wallet::open(filename,password);// will apply ".keys" ext to the wallet file
returnstd::string(filename+".keys");
}
////////////////////
voidneroshop::Wallet::open(conststd::string&path,std::stringpassword){// opens the wallet file's name without the ".key" extension
monero_wallet_obj=std::unique_ptr<monero_wallet_full>(monero::monero_wallet_full::open_wallet(path,password,network_type));// will re-apply ".keys" ext to the wallet file
// Initialize monero wallet with existing wallet file
std::stringwallet_password;// = "supersecretpassword123"; // Apparently passwords are not used nor required for mnemonics. ONLY wallet files use passwords
//std::cout << "Please upload your wallet file:\n";
std::cout<<"Please enter your wallet password:\n";
// Initialize monero wallet with existing wallet mnemonic
std::stringwallet_mnemonic;// = "hefty value later extra artistic firm radar yodel talent future fungal nutshell because sanity awesome nail unjustly rage unafraid cedar delayed thumbs comb custom sanity";
std::stringwallet_password;// = "supersecretpassword123"; // Apparently passwords are not used nor required for mnemonics. ONLY wallet files use passwords
std::cout<<"Please enter your wallet mnemonic:\n";
std::getline(std::cin,wallet_mnemonic);
// todo: allow user to specify a custom location for the wallet keyfile or use a default location