Skip to content

Commit f37e884

Browse files
committed
Backend write_record update
Now it accepts a mode argument, so it can act as "current" or "random". Current is the strategy used in the previous write_record, and random is the strategy used in signin.py.
1 parent 3ef9081 commit f37e884

1 file changed

Lines changed: 87 additions & 8 deletions

File tree

write_record.cpp

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#include "dbman.h"
2+
#include <functional>
23
#include <iostream>
34
#include <sstream>
4-
#include <thread>
55

6-
// Input: dk_curr
7-
// whitespace-separated list of card numbers
6+
// Input: dk_curr <mode> [<start time> <end time>]
7+
// <cardnums>
8+
// ...
9+
// <cardnum n> <time str n>
810
// Output: none
911

1012
// [currmin, currmax): the range of ID for a DK session
@@ -25,14 +27,94 @@ int get_op_lock(int currmin, int currmax, Spirit::Connection& conn) {
2527
return row->get<int>(0);
2628
}
2729

30+
// Given a string of 'xx:xx:xx', returns the second it is in a day
31+
// For example, '07:00:00' -> 3600 * 7
32+
int str2time(const std::string& timestr) {
33+
if (timestr.length() != 8 || timestr[2] != ':' || timestr[5] != ':')
34+
throw std::logic_error("Time string format incorrect");
35+
auto toint = [&timestr](int pos) {
36+
return 10 * (timestr[pos] - '0') + (timestr[pos + 1] - '0');
37+
};
38+
return 3600 * toint(0) + 60 * toint(3) + toint(6);
39+
}
40+
41+
class RandomTimeGetter {
42+
private:
43+
// mGen: [0, 9]
44+
std::function<int()> mGen;
45+
// Used with start and end
46+
std::function<int()> mRandTime;
47+
public:
48+
RandomTimeGetter(int start, int end) {
49+
std::mt19937 mt(std::chrono::system_clock::now().time_since_epoch().count());
50+
std::uniform_int_distribution dist(0, 9);
51+
mGen = std::bind(dist, mt);
52+
std::uniform_int_distribution dist2(start + 5, end - 5);
53+
mRandTime = std::bind(dist2, mt);
54+
}
55+
56+
[[nodiscard]] std::string operator() () {
57+
std::string res;
58+
// Let's do the random part first
59+
do {
60+
res = "0123-56-89 12:45:78.0123456";
61+
for (std::size_t pos = 20; pos <= 26; pos++)
62+
res[pos] = mGen() + '0';
63+
while (res.back() == '0')
64+
res.pop_back();
65+
} while (res.back() == '.'); // Turn back if only . is left
66+
const auto ct = []{
67+
auto t = std::time(nullptr);
68+
return std::localtime(&t);
69+
}();
70+
// Year constituent
71+
const int year = ct->tm_year + 1900;
72+
res[0] = '0' + year / 1000;
73+
res[1] = '0' + year / 100 % 10;
74+
res[2] = '0' + year / 10 % 10;
75+
res[3] = '0' + year % 10;
76+
auto fill = [&res](int num, int pos) {
77+
res[pos] = '0' + num / 10;
78+
res[pos + 1] = '0' + num % 10;
79+
};
80+
// Fill in month, date, hms
81+
fill(ct->tm_mon + 1, 5);
82+
fill(ct->tm_mday, 8);
83+
int rand_time = mRandTime();
84+
fill(rand_time / 3600, 11);
85+
fill(rand_time / 60 % 60, 14);
86+
fill(rand_time % 60, 17);
87+
return res;
88+
}
89+
};
90+
2891
int main() {
2992
// Reads in the card number of people who need to sign in
3093
// and writes to the database.
31-
std::string card;
3294
Spirit::Connection conn(Spirit::dbname, Spirit::passwd);
3395
int dk_tot = 3, dk_curr;
3496
std::cin >> dk_curr;
3597
const auto [currmin, currmax] = Spirit::get_id_range(dk_tot, dk_curr, conn);
98+
char mode;
99+
std::function<std::string()> get_time;
100+
std::cin >> mode;
101+
switch (mode) {
102+
case 'c': // current
103+
// no input
104+
get_time = Spirit::get_current_time;
105+
break;
106+
case 'r': {
107+
// random, read in
108+
std::string start_time, end_time;
109+
std::cin >> start_time >> end_time;
110+
get_time = RandomTimeGetter(str2time(start_time), str2time(end_time));
111+
break;
112+
}
113+
default:
114+
std::cerr << "Unrecognized mode" << std::endl;
115+
return 1;
116+
}
117+
std::string card;
36118
while (std::cin) {
37119
std::cin >> card;
38120
// Do not explicitly check the card number to be valid,
@@ -42,7 +124,7 @@ int main() {
42124
query << "update 上课考勤 set OptimisticLockField="
43125
<< get_op_lock(currmin, currmax, conn)
44126
<< " , 打卡时间='"
45-
<< Spirit::get_current_time()
127+
<< get_time()
46128
<< "' where "
47129
<< currmin
48130
<< " <= ID and ID < "
@@ -56,8 +138,5 @@ int main() {
56138
if (!row)
57139
break;
58140
}
59-
// Wait for 0.7s to simulate the real scenario
60-
using namespace std::chrono_literals;
61-
std::this_thread::sleep_for(700ms);
62141
}
63142
}

0 commit comments

Comments
 (0)