1 //-< GUESS.CPP >-----------------------------------------------------*--------*
2 // FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
3 // (Main Memory Database Management System)                          *   /\|  *
4 //                                                                   *  /  \  *
5 //                          Created:     19-Mar-2001    K.A. Knizhnik  * / [] \ *
6 //                          Last update: 19-Mar-2001    K.A. Knizhnik  * GARRET *
7 //-------------------------------------------------------------------*--------*
8 // Example of sharinf classes between databases
9 //-------------------------------------------------------------------*--------*
10 
11 #include "fastdb.h"
12 
13 USE_FASTDB_NAMESPACE
14 
15 const int maxStrLen = 256;
16 
17 dbDatabase  database[2];
18 dbDatabase* db;
19 
20 class Guess {
21   public:
22     dbReference<Guess> yes;
23     dbReference<Guess> no;
24     char const* question;
25 
26     TYPE_DESCRIPTOR((FIELD(yes), FIELD(question), FIELD(no)));
27 };
28 
29 REGISTER_UNASSIGNED(Guess);
30 
input(char const * prompt,char * buf,size_t buf_size)31 void input(char const* prompt, char* buf, size_t buf_size)
32 {
33     char* p;
34     do {
35         printf(prompt);
36         *buf = '\0';
37         fgets(buf, (int)buf_size, stdin);
38         p = buf + strlen(buf);
39     } while (p <= buf+1);
40 
41     if (*(p-1) == '\n') {
42         *--p = '\0';
43     }
44 }
45 
askQuestion(char const * question)46 bool askQuestion(char const* question) {
47     char answer[maxStrLen];
48     input(question, answer, sizeof answer);
49     return *answer == 'y' || *answer == 'Y';
50 }
51 
52 
whoIsIt(dbReference<Guess> const & parent)53 dbReference<Guess> whoIsIt(dbReference<Guess> const& parent) {
54     char animal[maxStrLen];
55     char difference[maxStrLen];
56     input("What is it ? ", animal, sizeof animal);
57     input("What is a difference from other ? ", difference, sizeof difference);
58     Guess node;
59     node.question = animal;
60     dbReference<Guess> child = db->insert(node);
61     node.question = difference;
62     node.yes = child;
63     node.no = parent;
64     return db->insert(node);
65 }
66 
67 
dialog(dbCursor<Guess> & cur)68 dbReference<Guess> dialog(dbCursor<Guess>& cur) {
69     char question[maxStrLen+16];
70     dbCursor<Guess> c(db, dbCursorForUpdate);
71     sprintf(question, "May be %s (y/n) ? ", cur->question);
72     if (askQuestion(question)) {
73         if (cur->yes == null) {
74             printf("It was very simple question for me...\n");
75         } else {
76             c.at(cur->yes);
77             dbReference<Guess> clarify = dialog(c);
78             if (clarify != null) {
79                 cur->yes = clarify;
80                 cur.update();
81             }
82         }
83     } else {
84         if (cur->no == null) {
85             if (cur->yes == null) {
86                 return whoIsIt(cur.currentId());
87             } else {
88                 cur->no = whoIsIt(null);
89                 cur.update();
90             }
91         } else {
92             c.at(cur->no);
93             dbReference<Guess> clarify = dialog(c);
94             if (clarify != null) {
95                 cur->no = clarify;
96                 cur.update();
97             }
98         }
99     }
100     return null;
101 }
102 
103 
104 
105 
main()106 int main()
107 {
108     if (database[0].open(_T("guess1")) && database[1].open(_T("guess2"))) {
109         int i = 0;
110         while (askQuestion("Think of an animal. Ready (y/n) ? ")) {
111             db = &database[i ^= 1];
112             dbCursor<Guess> cur(db, dbCursorForUpdate);
113             if (cur.select() != 0) {
114                 cur.next(); // first question is in record number 2
115                 dialog(cur);
116             } else {
117                 whoIsIt(null);
118             }
119             db->commit();
120         }
121         database[0].close();
122         database[1].close();
123         printf("End of the game\n");
124         return EXIT_SUCCESS;
125     } else {
126         fprintf(stderr, "Failed to open database\n");
127         return EXIT_FAILURE;
128     }
129 }
130 
131