Program documentation
./addnewanimalform.cpp
#include "addnewanimalform.h" #include "iostream" AddNewAnimalForm::AddNewAnimalForm(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); nameBox = new QLineEdit(); speciesBox = new QLineEdit(); ageBox = new QLineEdit(); ageBox->setValidator(new QIntValidator());//Only ints allowed weightBox = new QLineEdit(); weightBox->setValidator(new QIntValidator());//Only ints allowed sizeBox = new QLineEdit(); colorBox = new QLineEdit(); genderBox = new QComboBox(); //Set up the options for the drop-down menu QStringList genderOptions = QStringList(); genderOptions << "Male" << "Female"; genderBox->addItems(genderOptions); //Now that we've created all the input fields, we add them to the form ui->addForm->addRow(QString("Name:"), nameBox); ui->addForm->addRow(QString("Species:"), speciesBox); ui->addForm->addRow(QString("Gender:"), genderBox); ui->addForm->addRow(QString("Color:"), colorBox); ui->addForm->addRow(QString("Age:"), ageBox); ui->addForm->addRow(QString("Weight(g):"), weightBox); ui->addForm->addRow(QString("Size:"), sizeBox); } AddNewAnimalForm::~AddNewAnimalForm() { delete nameBox; delete speciesBox; delete genderBox; delete colorBox; delete ageBox; delete weightBox; delete sizeBox; delete ui; } void AddNewAnimalForm::accept() { std::string name = nameBox->text().toStdString(); std::string species = speciesBox->text().toStdString(); std::string color = colorBox->text().toStdString(); std::string age = ageBox->text().toStdString(); std::string weight = weightBox->text().toStdString(); std::string gender = genderBox->currentText().toStdString(); std::string size = sizeBox->text().toStdString(); //If all of the fields hold a value, we create a new animal and emit the addNew signal if (!name.empty() && !species.empty() && !color.empty() && !age.empty() && !weight.empty() && !gender.empty() && !size.empty()) { Animal * newAnimal = new Animal(name, species, color, std::stoi(age), std::stoi(weight), gender, size); emit addNew(newAnimal); } //Either way we close the panel emit closePane(); close(); } void AddNewAnimalForm::reject() { emit closePane(); close(); }
./addnewanimalform.h
#ifndef ADDNEWANIMALFORM_H #define ADDNEWANIMALFORM_H #include <QWidget> #include <QDialog> #include <QLineEdit> #include <QComboBox> #include "ui_addnewanimalform.h" #include "animal.h" //This is the class for the form that pops down when you click File > Add Animal. addnewanimalform.ui is the .ui file which corresponds to it. class AddNewAnimalForm : public QDialog { Q_OBJECT public: explicit AddNewAnimalForm(QWidget *parent = nullptr); ~AddNewAnimalForm(); signals: void addNew(Animal * animal);//Sent when the user hits 'OK' and successfully adds an animal to the program void closePane();//Sent when the user closes the form by any means public slots: void accept(); //Received when the user hits the OK button void reject(); //Received when the user hits the Cancel button private: Ui::Dialog *ui; //We add these widgets to the FormLayout located in ui, and get user input from them. QLineEdit * nameBox; QLineEdit * ageBox; QLineEdit * colorBox; QLineEdit * weightBox; QLineEdit * sizeBox; QLineEdit * speciesBox; QComboBox * genderBox; }; #endif // ADDNEWANIMALFORM_H
./addnewanimalform.ui
Dialog 0 0 400 300 Dialog Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox rejected() Dialog reject() 316 260 286 274 buttonBox accepted() Dialog accept() 248 254 157 274
./animal.cpp
#include "animal.h" Animal::Animal(int id, std::string &name, std::string &species, std::string &color, int age, int weight, std::string &gender, std::string &size): id(id), name(name), species(species), color(color), age(age), weight(weight), gender(gender), size(size) { } //This constructor is for brand-new animals, for whom we don't have a database ID yet. We set the id to -1 so that we know to assign the proper id later. Animal::Animal(std::string &name, std::string &species, std::string &color, int age, int weight, std::string &gender, std::string &size): Animal(-1, name, species, color, age, weight, gender, size) { } std::string Animal::getName() { return name; } std::string Animal::getSpecies() { return species; } std::string Animal::getColor() { return color; } int Animal::getAge() { return age; } int Animal::getWeight() { return weight; } std::string Animal::getGender() { return gender; } std::string Animal::getSize() { return size; } void Animal::setName(const std::string &value) { name = value; } void Animal::setSpecies(const std::string &value) { species = value; } void Animal::setColor(const std::string &value) { color = value; } void Animal::setAge(int value) { age = value; } void Animal::setWeight(int value) { weight = value; } void Animal::setGender(const std::string &value) { gender = value; } void Animal::setSize(const std::string &value) { size = value; } int Animal::getId() const { return id; } void Animal::setId(int value) { //We can only set the ID if the current ID is less than 0 (meaning, is not a valid database ID) if (id < 0) { id = value; } }
./Animal.db
./animal.h
#ifndef ANIMAL_H #define ANIMAL_H #include<string> //A class representing a generic animal. Will probably see significant restructuring as the project continues. Right now, just a container for attributes. class Animal { public: Animal(int id, std::string & name, std::string & species, std::string & color, int age, int weight, std::string & gender, std::string & size); Animal(std::string & name, std::string & species, std::string & color, int age, int weight, std::string & gender, std::string & size); std::string getName(); std::string getSpecies(); std::string getColor(); int getAge(); int getWeight(); std::string getGender(); std::string getSize(); void setName(const std::string &value); void setSpecies(const std::string &value); void setColor(const std::string &value); void setAge(int value); void setWeight(int value); void setGender(const std::string &value); void setSize(const std::string &value); int getId() const; void setId(int value); private: std::string name; std::string species; std::string color; int age; int weight; std::string gender; std::string size; int id; }; #endif // ANIMAL_H
./animaltablemodel.cpp
#include "animaltablemodel.h" AnimalTableModel::AnimalTableModel(QObject *parent) { storedParent = parent; animals = std::vector<Animal *>(); } AnimalTableModel::~AnimalTableModel() { foreach (Animal * animal, animals) { delete animal; } } int AnimalTableModel::rowCount(const QModelIndex &parent) const { return animals.size(); } int AnimalTableModel::columnCount(const QModelIndex &parent) const { return 2; } QVariant AnimalTableModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { if (index.column() == 0) { auto name = animals[index.row()]->getName().c_str(); return QString("%1").arg(name); } else if (index.column() == 1) { auto species = animals[index.row()]->getSpecies().c_str(); return QString("%1").arg(species); } } return QVariant(); } QVariant AnimalTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole) { if (orientation == Qt::Horizontal) { switch (section) { case 0: return QString("Name"); case 1: return QString("Species"); } } } return QVariant(); } void AnimalTableModel::addItem(Animal *item) { //If the animal's ID is less than or equal to zero, it is not yet in the database, so we add it and retrieve the new ID#. if (item->getId() <= 0) { SqlHandler::addNew(item); } beginInsertRows(QModelIndex(), animals.size(), animals.size()); animals.push_back(item); insertRows(animals.size(), 1); endInsertRows(); } //Not currently used, database not supported, largely untested void AnimalTableModel::removeItem(Animal *item) { int index = -1; for (unsigned int i = 0; i < animals.size(); i++) { if (animals[i]->getName() == item->getName()) { index = i; } } if (index < 0) { return; } animals.erase(animals.begin() + index); } std::vector<Animal *> AnimalTableModel::getAnimals() { return animals; }
./animaltablemodel.h
#ifndef ANIMALTABLEMODEL_H #define ANIMALTABLEMODEL_H #include <QAbstractTableModel> #include "animal.h" #include "sqlhandler.h" #include <vector> //The Model for the table containing the animals. Displays the name and species, and stores the rest of the data for display elsewhere class AnimalTableModel : public QAbstractTableModel { Q_OBJECT public: AnimalTableModel(QObject *parent); ~AnimalTableModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const ; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; //Function which defines the output to the table QVariant headerData(int section, Qt::Orientation orientation, int role) const; void removeItem(Animal * item); //We have the capability to remove objects from the table but it is not currently used and does not remove from the database std::vector<Animal *> getAnimals(); public slots: void addItem(Animal * item); //Adds an animal to the table and database private: std::vector<Animal *> animals; //A vector containing all of the animals in the table QObject *storedParent; //We store the parent of the model; not currently used }; #endif // ANIMALTABLEMODEL_H
./cuACS.pro
#------------------------------------------------- # # Project created by QtCreator 2019-02-08T23:09:20 # #------------------------------------------------- QT += core gui sql greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = cuACS TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ mainwindow.cpp \ animaltablemodel.cpp \ animal.cpp \ addnewanimalform.cpp \ sqlhandler.cpp HEADERS += \ mainwindow.h \ animaltablemodel.h \ animal.h \ addnewanimalform.h \ sqlhandler.h FORMS += \ mainwindow.ui \ addnewanimalform.ui DISTFILES += \ Animal.db
./cuACS.pro.user
EnvironmentId {c76633c0-7a82-4780-8688-cb14bec9d289} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal 2 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 1 true true true false ProjectExplorer.Project.PluginSettings ProjectExplorer.Project.Target.0 Desktop Desktop {d29fab11-7d8e-483c-ace2-f5f2564c9bb1} 0 0 0 /home/student/Desktop/FinalTemp/build-cuACS-Desktop-Debug true qmake QtProjectManager.QMakeBuildStep true false false false true Make Qt4ProjectManager.MakeStep -w -r false 2 Build ProjectExplorer.BuildSteps.Build true Make Qt4ProjectManager.MakeStep -w -r true clean 1 Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 true /home/student/Desktop/FinalTemp/build-cuACS-Desktop-Release true qmake QtProjectManager.QMakeBuildStep false false false false true Make Qt4ProjectManager.MakeStep -w -r false 2 Build ProjectExplorer.BuildSteps.Build true Make Qt4ProjectManager.MakeStep -w -r true clean 1 Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 true /home/student/Desktop/FinalTemp/build-cuACS-Desktop-Profile true qmake QtProjectManager.QMakeBuildStep true false true false true Make Qt4ProjectManager.MakeStep -w -r false 2 Build ProjectExplorer.BuildSteps.Build true Make Qt4ProjectManager.MakeStep -w -r true clean 1 Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 true 3 0 Deploy ProjectExplorer.BuildSteps.Deploy 1 Deploy locally ProjectExplorer.DefaultDeployConfiguration 1 false false 1000 true false false false false true 0.01 10 true 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 cuACS Qt4ProjectManager.Qt4RunConfiguration:/home/student/Desktop/FinalTemp/COMP3004Temp/cuACS.pro true cuACS.pro false /home/student/Desktop/FinalTemp/build-cuACS-Desktop-Debug 3768 false true false false true 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 18 Version 18
./install
mkdir --parents -v /opt/cuACS cp --verbose -uR Animal.db $_ chmod --recursive a+w /opt/cuACS qmake make
./main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
./mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); setWindowTitle("cuACS 0.01"); //Set up table model = new AnimalTableModel(this); ui->tableView->setModel(model); ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); std::vector<Animal *> database = SqlHandler::fetchDatabase(); foreach(Animal * animal, database) { model->addItem(animal); } //Set up details panel detailsPanel = ui->animalDetails; nameBox = new QLineEdit(); speciesBox = new QLineEdit(); ageBox = new QLineEdit(); ageBox->setValidator(new QIntValidator()); weightBox = new QLineEdit(); weightBox->setValidator(new QIntValidator()); sizeBox = new QLineEdit(); colorBox = new QLineEdit(); genderBox = new QComboBox(); QStringList genderOptions = QStringList(); genderOptions << "Male" << "Female"; genderBox->addItems(genderOptions); //Add all the input fields to the form layout detailsPanel->addRow(QString("Name:"), nameBox); detailsPanel->addRow(QString("Species:"), speciesBox); detailsPanel->addRow(QString("Gender:"), genderBox); detailsPanel->addRow(QString("Color:"), colorBox); detailsPanel->addRow(QString("Age:"), ageBox); detailsPanel->addRow(QString("Weight(g):"), weightBox); detailsPanel->addRow(QString("Size:"), sizeBox); //Set up the selectionChanged signal QItemSelectionModel *selectionModel= ui->tableView->selectionModel(); connect(selectionModel, SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT(selectionChangedSlot(const QItemSelection &, const QItemSelection &))); //Set up the signals for the details/editing box connect(nameBox, SIGNAL(editingFinished()), this, SLOT(valueUpdatedSlot())); connect(speciesBox, SIGNAL(editingFinished()), this, SLOT(valueUpdatedSlot())); connect(ageBox, SIGNAL(editingFinished()), this, SLOT(valueUpdatedSlot())); connect(weightBox, SIGNAL(editingFinished()), this, SLOT(valueUpdatedSlot())); connect(sizeBox, SIGNAL(editingFinished()), this, SLOT(valueUpdatedSlot())); connect(colorBox, SIGNAL(editingFinished()), this, SLOT(valueUpdatedSlot())); connect(genderBox, SIGNAL(activated(int)), this, SLOT(valueUpdatedSlot())); //Now we hide all the input fields until a selection is made in the table nameBox->hide(); speciesBox->hide(); ageBox->hide(); weightBox->hide(); sizeBox->hide(); colorBox->hide(); genderBox->hide(); } MainWindow::~MainWindow() { delete ui; delete nameBox; delete speciesBox; delete genderBox; delete colorBox; delete ageBox; delete weightBox; delete sizeBox; delete model; delete detailsPanel; delete docker; } void MainWindow::removeDocker() { docker->close(); } void MainWindow::selectionChangedSlot(const QItemSelection & /*newSelection*/, const QItemSelection & /*oldSelection*/) { nameBox->show(); speciesBox->show(); ageBox->show(); weightBox->show(); sizeBox->show(); colorBox->show(); genderBox->show(); const QModelIndex index = ui->tableView->selectionModel()->currentIndex(); currentAnimal = model->getAnimals()[index.row()]; nameBox->setText(QString(currentAnimal->getName().c_str())); ageBox->setText(QString(std::to_string(currentAnimal->getAge()).c_str())); speciesBox->setText(QString(currentAnimal->getSpecies().c_str())); genderBox->setCurrentIndex(genderBox->findText(QString(currentAnimal->getGender().c_str()))); weightBox->setText(QString(std::to_string(currentAnimal->getWeight()).c_str())); sizeBox->setText(QString(currentAnimal->getSize().c_str())); colorBox->setText(QString(currentAnimal->getColor().c_str())); } void MainWindow::valueUpdatedSlot() { currentAnimal->setName(nameBox->text().toStdString()); currentAnimal->setSpecies(speciesBox->text().toStdString()); currentAnimal->setAge(std::stoi(ageBox->text().toStdString())); currentAnimal->setColor(colorBox->text().toStdString()); currentAnimal->setWeight(std::stoi(weightBox->text().toStdString())); currentAnimal->setGender(genderBox->currentText().toStdString()); currentAnimal->setSize(sizeBox->text().toStdString()); if (currentAnimal->getId() > 0) { SqlHandler::updateItem(currentAnimal); } } void MainWindow::on_actionAdd_triggered() { docker = new QDockWidget(QString("Add New"), this); AddNewAnimalForm * form = new AddNewAnimalForm(this); docker->setWidget(form); connect(form, SIGNAL(addNew(Animal *)), model, SLOT(addItem(Animal*))); connect(form, SIGNAL(closePane()), this, SLOT(removeDocker())); addDockWidget(Qt::TopDockWidgetArea, docker); }
./mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QLineEdit> #include <QComboBox> #include <QItemSelection> #include <QInputDialog> #include <QFormLayout> #include <QDockWidget> #include "animaltablemodel.h" #include "addnewanimalform.h" #include "sqlhandler.h" //This class defines and controls the main window of the UI. //The ui file corresponding to this class is mainwindow.ui namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void removeDocker(); //Removes the docked widget (the add animals widget) because it's no longer needed private: Ui::MainWindow *ui; //These are the input fields on the right which allow the user to edit the sleected animal QComboBox * genderBox; QLineEdit * nameBox; QLineEdit * ageBox; QLineEdit * speciesBox; QLineEdit * colorBox; QLineEdit * weightBox; QLineEdit * sizeBox; //The current animal selected in the table Animal * currentAnimal; //The table model AnimalTableModel * model; //The form layout containing the details/edit fields for the selected animal QFormLayout * detailsPanel; //The widget for adding animals to the database QDockWidget * docker; private slots: void selectionChangedSlot(const QItemSelection & newSelection, const QItemSelection & oldSelection); //Received when the selected item in the table changes void valueUpdatedSlot(); //Received when the value in an input field changes void on_actionAdd_triggered(); //Received when File > Add Animal is clicked on }; #endif // MAINWINDOW_H
./mainwindow.ui
MainWindow 0 0 1224 800 MainWindow 0 0 1224 22 File Add Animal
./README.md
# Carleton University Animal Care System Created for Carleton University's COMP3004 course (taught by Prof. Christine Laurendeau) by Peter MacDonald (100683150), Ibiduneyitayo(101018199), and Nicholas Aubé(101032093) ## Installation To install the software after extracting it from the .tar file, simply run the following command in the directory: ``` sudo bash install ``` You will likely be prompted to input your administrator password in order to run the install script with sudo. Local files, such as the animal database, are installed to the directory /opt/cuACS in your file system. If this directory already contains files, they may be overwritten in this process. ## Running To run the software, after installing, run the following command from the same directory: ``` ./cuACS ``` ## Cleanup To clean up the software, run the following command from its directory: ``` sudo bash uninstall ``` Note that this uninstall script will delete the /opt/cuACS directory we are storing local files in. If you wish to retain this directory, you may want to run: ``` make clean ``` Instead. This will clean up the software directory without affecting /opt/cuACS. You will likely be prompted to input your administrator password in order to run the uninstall script with sudo. ## A note for developers When you open the project in QT Creator, it has its own build directory in mind, and does not know to deploy the local files to /opt/cuACS. Either run the installer script yourself, or manually move the files over.
./sqlhandler.cpp
#include "sqlhandler.h" const QString SqlHandler::DB_LOCATION = "/opt/cuACS/Animal.db"; QSqlDatabase SqlHandler::db = QSqlDatabase::addDatabase("QSQLITE", "Connection"); std::vector<Animal *> SqlHandler::fetchDatabase() { std::vector<Animal *> returnValue = std::vector<Animal *>(); db.setDatabaseName(DB_LOCATION); if (!db.open()) { qDebug("Error occurred opening the database."); qDebug("%s.", qPrintable(db.lastError().text())); throw "Error opening database."; } QSqlQuery query(db); //Get the properties for all the animals in the table query.prepare("SELECT animal_ID, name, type, color, age, weight_kg, gender, size FROM animal"); if (!query.exec()) { qDebug("Error occurred querying."); qDebug("%s.", qPrintable(db.lastError().text())); db.close(); throw "Error reading database."; } //For each animal, assemble the object in memory from the properties retrieved from the server while (query.next()) { int id = query.value(0).toInt(); std::string name = qPrintable(query.value(1).toString()); std::string type = qPrintable(query.value(2).toString()); std::string color = qPrintable(query.value(3).toString()); int age = query.value(4).toInt(); int weight = query.value(5).toInt(); std::string gender = qPrintable(query.value(6).toString()); std::string size = qPrintable(query.value(7).toString()); returnValue.push_back(new Animal(id, name, type, color, age, weight, gender, size)); } db.close(); return returnValue; } bool SqlHandler::updateItem(Animal * animal) { db.setDatabaseName(DB_LOCATION); if (!db.open()) { qDebug("Error occurred opening the database."); qDebug("%s.", qPrintable(db.lastError().text())); return false; } QSqlQuery query(db); //Update the animal corresponding to our ID in the database with the current property values query.prepare("UPDATE animal SET name=:name, type=:type, color=:color, age=:age, weight_kg=:weight, gender=:gender, size=:size WHERE animal_ID=:id"); query.bindValue(":name", QVariant(animal->getName().c_str())); query.bindValue(":color", QVariant(animal->getColor().c_str())); query.bindValue(":type", QVariant(animal->getSpecies().c_str())); query.bindValue(":age", QVariant(animal->getAge())); query.bindValue(":weight", QVariant(animal->getWeight())); query.bindValue(":gender", QVariant(animal->getGender().c_str())); query.bindValue(":size", QVariant(animal->getSize().c_str())); query.bindValue(":id", QVariant(animal->getId())); if (!query.exec()) { qDebug("Error occurred querying."); qDebug("%s.", qPrintable(db.lastError().text())); db.close(); return false; } db.close(); return true; } bool SqlHandler::addNew(Animal * animal) { if (animal->getId() >= 0) { return false; } db.setDatabaseName(DB_LOCATION); if (!db.open()) { qDebug("Error occurred opening the database."); qDebug("%s.", qPrintable(db.lastError().text())); return false; } //Add the animal to the database QSqlQuery query(db); query.prepare("INSERT INTO animal (name, color, type, age, weight_kg, gender, size) VALUES (:name, :color, :type, :age, :weight, :gender, :size)"); query.bindValue(":name", QVariant(animal->getName().c_str())); query.bindValue(":color", QVariant(animal->getColor().c_str())); query.bindValue(":type", QVariant(animal->getSpecies().c_str())); query.bindValue(":age", QVariant(animal->getAge())); query.bindValue(":weight", QVariant(animal->getWeight())); query.bindValue(":gender", QVariant(animal->getGender().c_str())); query.bindValue(":size", QVariant(animal->getSize().c_str())); if (!query.exec()) { qDebug("Error occurred inserting."); qDebug("%s.", qPrintable(db.lastError().text())); db.close(); return false; } //Retrieve the auto-generated id from the database for the animal we just put in QSqlQuery idQuery(db); idQuery.prepare("SELECT animal_ID FROM animal WHERE name=:name AND type=:type AND color=:color AND age=:age AND weight_kg=:weight AND gender=:gender AND size=:size"); idQuery.bindValue(":name", QVariant(animal->getName().c_str())); idQuery.bindValue(":color", QVariant(animal->getColor().c_str())); idQuery.bindValue(":type", QVariant(animal->getSpecies().c_str())); idQuery.bindValue(":age", QVariant(animal->getAge())); idQuery.bindValue(":weight", QVariant(animal->getWeight())); idQuery.bindValue(":gender", QVariant(animal->getGender().c_str())); idQuery.bindValue(":size", QVariant(animal->getSize().c_str())); if (!idQuery.exec()) { qDebug("Error occurred querying."); qDebug("%s.", qPrintable(db.lastError().text())); db.close(); return false; } idQuery.next(); //Set the animal object's ID to match the database ID. animal->setId(idQuery.value(0).toInt()); db.close(); return true; } SqlHandler::SqlHandler() { }
./sqlhandler.h
#ifndef SQLHANDLER_H #define SQLHANDLER_H #include <QtSql> #include <vector> #include "animal.h" //This class interfaces with the database and performs SQL queries/updates class SqlHandler { public: static std::vector<Animal *> fetchDatabase(); //Retrieves all animals from the database and loads its contents into the table static bool updateItem(Animal *); //Updates an animal in the database static bool addNew(Animal *); //Adds a new animal to the database and assigns it the ID number provided by the db. private: static const QString DB_LOCATION; //The path where the database can be found on the hard drive. SqlHandler(); //Constructoir is private because this class only has static functions static QSqlDatabase db; //The database connection is stored once opened. }; #endif // SQLHANDLER_H
./uninstall
make clean rm -r /opt/cuACS rm ./cuACS rm ./Makefile