diff --git a/data/database.db b/data/database.db index 91376c3..beaf1ba 100644 Binary files a/data/database.db and b/data/database.db differ diff --git a/data/sample.test b/data/sample.test index df07643..b0d2784 100644 --- a/data/sample.test +++ b/data/sample.test @@ -1,11 +1,11 @@ # Двоичная система. Двоичная арифметика ? Двоичная системой счисления является - Унарная система счисления -- Непозиционная система счисления ++ Непозиционная система счисления - Позиционная система счисления ? Для записи в двоичной системе счисления используют только две цифры. Какие? - 2 и 3 -- 2 и 10 ++ 2 и 10 - 0 и 1 ? Переведите число 1010100 из двоичной системы в десятичную - 84 @@ -19,8 +19,6 @@ - 110101 ? Вычислите 11001 - 1111 = - 1010 -- 1110 ++ 1110 - 1011 - 0110 -? Вычислите 11001 - 1111 = -- 1010 diff --git a/source/app.d b/source/app.d index df3e6ff..aa19f90 100644 --- a/source/app.d +++ b/source/app.d @@ -4,6 +4,7 @@ import core.stdc.stdlib : exit, EXIT_SUCCESS, EXIT_FAILURE; import std.stdio, std.conv, std.path, std.file, std.format, std.regex, std.array, std.algorithm; import source.database; +import source.sql; enum { GROUP_THEME = 2, @@ -51,29 +52,45 @@ int main(string[] args) auto regular = regex(pattern, "m"); struct Answer { + int number; string text; - bool right; + bool truth; - // ToDo - bool addToDB() { - return false; + bool addToDB(int question_id) { + int id = sqlAddNewAnswer(question_id, this.number, this.text, this.truth); + + if (!id) + return false; + + return true; } } struct Question { + int number; string text; Answer[int] answers; - ulong getCount() { + ulong count() { return answers.length; } bool isValid() { return answers.length > 1; } - // ToDo - bool addToDB() { - return false; + + bool addToDB(int topic_id) { + int id = sqlAddNewQuestion(topic_id, this.number, this.text); + + if (!id) + return false; + + foreach (answer; answers.byKeyValue.array.sort!((a, b) => a.key < b.key)) { + if (!answer.value.addToDB(id)) + return false; + } + + return true; } } @@ -81,7 +98,7 @@ int main(string[] args) string text; Question[int] questions; - ulong getCount() { + ulong count() { return questions.length; } @@ -89,25 +106,69 @@ int main(string[] args) return questions.length > 1; } - // ToDo bool addToDB() { - return false; + if (!check()) + return false; + + int id = sqlAddNewTheme(this.text); + + if (!id) + return false; + + foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) { + if (!question.value.addToDB(id)) + return false; + } + + return true; } void print() { - writeln("Количество вопросов: %s".format(this.getCount())); + writeln("Количество вопросов: %s".format(this.count())); foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) { writeln("\tВопрос №%d: %s".format(question.key, question.value.text)); - writeln("\tКоличество ответов: %d".format(question.value.getCount())); - if (question.value.isValid()) - foreach (answer; question.value.answers.byKeyValue.array.sort!((a, b) => a.key < b.key)) { - writeln("\t\tОтвет №%d: %s".format(answer.key, answer.value.text)); - } - else - writeln("\t\tНедостаточно количества ответов"); + writeln("\tКоличество ответов: %d".format(question.value.count())); + foreach (answer; question.value.answers.byKeyValue.array.sort!((a, b) => a.key < b.key)) { + writeln("\t\tОтвет №%d: %s".format(answer.key, answer.value.text)); + } } } + + bool check() { + bool error = false; + + if (!this.isValid()) { + writeln("Недостаточное количество вопросов: %d".format(this.count())); + error = true; + } + + if (!error) { + foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) { + if (!question.value.isValid()) { + writeln("Вопрос №%d \"%s\" содержит недостаточное количество ответов: %d".format( + question.key, question.value.text, question.value.count() + )); + error = true; + } + + int truth; + + foreach (answer; question.value.answers) { + if (answer.truth) + ++truth; + } + + if (truth > 1) { + writeln("Вопрос №%d \"%s\" содержит более одного правильного ответа".format( + question.key, question.value.text + )); + error = true; + } + } + } + return !error; + } } Theme theme; @@ -132,24 +193,26 @@ int main(string[] args) if (match[GROUP_QUESTION].length) { numAnswer = 0; - theme.questions[++numQuestion] = Question(match[GROUP_QUESTION_TEXT]); + theme.questions[++numQuestion] = Question(numQuestion, match[GROUP_QUESTION_TEXT]); continue; } if (match[GROUP_ANSWER].length) { - theme.questions[numQuestion].answers[++numAnswer] = Answer(match[GROUP_ANSWER_TEXT], false); + theme.questions[numQuestion].answers[++numAnswer] = Answer(numAnswer, match[GROUP_ANSWER_TEXT], false); continue; } if (match[GROUP_ANSWER_RIGHT].length) { - theme.questions[numQuestion].answers[++numAnswer] = Answer(match[GROUP_ANSWER_RIGHT_TEXT], true); + theme.questions[numQuestion].answers[++numAnswer] = Answer(numAnswer, match[GROUP_ANSWER_RIGHT_TEXT], true); continue; } } - theme.print(); + // theme.print(); + // theme.check(); + theme.addToDB(); return EXIT_SUCCESS; } diff --git a/source/sql.d b/source/sql.d new file mode 100644 index 0000000..c30ce93 --- /dev/null +++ b/source/sql.d @@ -0,0 +1,51 @@ +module source.sql; + +import singlog; +import std.conv; + +import source.dblite; + +int sqlAddNewTheme(string topic) { + try { + auto queryResult = dblite.sql( + "insert into topics (name) values (?) returning id", + topic + ); + if (!queryResult.empty()) + return queryResult.front()["id"].to!int; + } catch (Exception e) { + log.e("Не удалось выполнить запрос к БД. " ~ e.msg); + } + + return 0; +} + +int sqlAddNewQuestion(int topic_id, int question_number, string question_text) { + try { + auto queryResult = dblite.sql( + "insert into questions (topic_id, number, text) values (?, ?, ?) returning id", + topic_id, question_number, question_text + ); + if (!queryResult.empty()) + return queryResult.front()["id"].to!int; + } catch (Exception e) { + log.e("Не удалось выполнить запрос к БД. " ~ e.msg); + } + + return 0; +} + +int sqlAddNewAnswer(int question_id, int answer_number, string answer_text, int answer_truth) { + try { + auto queryResult = dblite.sql( + "insert into answers (question_id, number, text, truth) values (?, ?, ?, ?) returning id", + question_id, answer_number, answer_text, answer_truth + ); + if (!queryResult.empty()) + return queryResult.front()["id"].to!int; + } catch (Exception e) { + log.e("Не удалось выполнить запрос к БД. " ~ e.msg); + } + + return 0; +}