1 //-< GUESS.CPP >-----------------------------------------------------*--------*
2 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
3 // (Post Relational Database Management System)                      *   /\|  *
4 //                                                                   *  /  \  *
5 //                          Created:     10-Dec-98    K.A. Knizhnik  * / [] \ *
6 //                          Last update: 19-Dec-98    K.A. Knizhnik  * GARRET *
7 //-------------------------------------------------------------------*--------*
8 // Sample of database application: game "Guess an animal"
9 //-------------------------------------------------------------------*--------*
10 
11 #include "gigabase.h"
12 
13 #ifdef SUPPORT_DATA_ENCRYPTION
14 #include "crypt/crypt_file.h"
15 #endif
16 
17 USE_GIGABASE_NAMESPACE
18 
19 const int maxStrLen = 256;
20 
21 class Guess {
22   public:
23     dbReference<Guess> yes;
24     dbReference<Guess> no;
25     char const* question;
26 
27     TYPE_DESCRIPTOR((FIELD(yes), FIELD(question), FIELD(no)));
28 };
29 
30 REGISTER(Guess);
31 
input(char const * prompt,char * buf,size_t buf_size)32 void input(char const* prompt, char* buf, size_t buf_size)
33 {
34     char* p;
35     do {
36         printf(prompt);
37         *buf = '\0';
38         fgets(buf, (int)buf_size, stdin);
39         p = buf + strlen(buf);
40     } while (p <= buf+1);
41 
42     if (*(p-1) == '\n') {
43         *--p = '\0';
44     }
45 }
46 
askQuestion(char const * question)47 bool askQuestion(char const* question) {
48     char answer[maxStrLen];
49     input(question, answer, sizeof answer);
50     return *answer == 'y' || *answer == 'Y';
51 }
52 
53 
whoIsIt(dbReference<Guess> const & parent)54 dbReference<Guess> whoIsIt(dbReference<Guess> const& parent) {
55     char animal[maxStrLen];
56     char difference[maxStrLen];
57     input("What is it ? ", animal, sizeof animal);
58     input("What is a difference from other ? ", difference, sizeof difference);
59     Guess node;
60     node.question = animal;
61     dbReference<Guess> child = insert(node);
62     node.question = difference;
63     node.yes = child;
64     node.no = parent;
65     return insert(node);
66 }
67 
68 
dialog(dbCursor<Guess> & cur)69 dbReference<Guess> dialog(dbCursor<Guess>& cur) {
70     char question[maxStrLen+16];
71     dbCursor<Guess> c(dbCursorForUpdate);
72     sprintf(question, "May be %s (y/n) ? ", cur->question);
73     if (askQuestion(question)) {
74         if (cur->yes == null) {
75             printf("It was very simple question for me...\n");
76         } else {
77             c.at(cur->yes);
78             dbReference<Guess> clarify = dialog(c);
79             if (clarify != null) {
80                 cur->yes = clarify;
81                 cur.update();
82             }
83         }
84     } else {
85         if (cur->no == null) {
86             if (cur->yes == null) {
87                 return whoIsIt(cur.currentId());
88             } else {
89                 cur->no = whoIsIt(null);
90                 cur.update();
91             }
92         } else {
93             c.at(cur->no);
94             dbReference<Guess> clarify = dialog(c);
95             if (clarify != null) {
96                 cur->no = clarify;
97                 cur.update();
98             }
99         }
100     }
101     return null;
102 }
103 
104 
main(int argc,char * argv[])105 int __cdecl main(int argc, char* argv[])
106 {
107     dbDatabase db(dbDatabase::dbMulticlientReadWrite);
108 #ifdef SUPPORT_DATA_ENCRYPTION
109     dbCryptFile cf("KEY");
110     dbCryptFile bck("KEY");
111     int rc = cf.open(_T("guess.dbs"), 0);
112     if (rc != dbFile::ok) {
113         char_t buf[256];
114         cf.errorText(rc, buf, itemsof(buf));
115         FPRINTF(stderr, _T("Failed to open encrupted file: %s\n"), buf);
116         return EXIT_FAILURE;
117     }
118     if (db.open(&cf)) {
119 #else
120     if (db.open(STRLITERAL("guess.dbs"))) {
121 #endif
122         dbCursor<Guess> cur(dbCursorForUpdate);
123 #ifdef TEST_XML_IMPORT
124         {
125             FILE* f = fopen("guess.xml", "r");
126             if (f != NULL) {
127                 db.importDatabaseFromXml(f);
128                 fclose(f);
129             }
130         }
131 #endif
132         //db.scheduleBackup(STRLITERAL("guess.bck?"), 10);
133         //db.scheduleBackup(STRLITERAL("guess.bc"), 10);
134         while (askQuestion("Think of an animal. Ready (y/n) ? ")) {
135             if (cur.select() != 0) {
136                 cur.next(); // first question is in record number 2
137                 dialog(cur);
138             } else {
139                 whoIsIt(null);
140             }
141             db.commit();
142         }
143 #ifdef SUPPORT_DATA_ENCRYPTION
144         rc = bck.open(_T("guess.bck"), 0);
145         if (rc != dbFile::ok) {
146             char_t buf[256];
147             bck.errorText(rc, buf, itemsof(buf));
148             FPRINTF(stderr, _T("Failed to open backup file: %s\n"), buf);
149             return EXIT_FAILURE;
150         }
151         db.backup(&bck, false);
152 #endif
153 #ifdef TEST_XML_IMPORT
154         {
155             FILE* f = fopen("guess.xml", "w");
156             if (f != NULL) {
157                 db.exportDatabaseToXml(f, NULL, 0, dbDatabase::sel_all);
158                 fclose(f);
159             }
160         }
161 #endif
162         db.close();
163         printf("End of the game\n");
164         return EXIT_SUCCESS;
165     } else {
166         fprintf(stderr, "Failed to open database\n");
167         return EXIT_FAILURE;
168     }
169 }
170 
171