1 /*
2    Copyright (c) 2005, 2021, Oracle and/or its affiliates.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 /***************************************************************
26 * I N C L U D E D   F I L E S                                  *
27 ***************************************************************/
28 
29 #include <ndb_global.h>
30 
31 #include "userInterface.h"
32 
33 #include "dbPopulate.h"
34 #include <NdbOut.hpp>
35 #include <random.h>
36 
37 /***************************************************************
38 * L O C A L   C O N S T A N T S                                *
39 ***************************************************************/
40 
41 /***************************************************************
42 * L O C A L   D A T A   S T R U C T U R E S                    *
43 ***************************************************************/
44 
45 /***************************************************************
46 * L O C A L   F U N C T I O N S                                *
47 ***************************************************************/
48 
49 static void getRandomSubscriberData(int              subscriberNo,
50 		                    SubscriberNumber number,
51 		                    SubscriberName   name);
52 
53 static void populate(const char *title,
54                      int   count,
55                      void (*func)(UserHandle*,int),
56                      UserHandle *uh);
57 
58 static void populateServers(UserHandle *uh, int count);
59 static void populateSubscribers(UserHandle *uh, int count);
60 static void populateGroups(UserHandle *uh, int count);
61 
62 /***************************************************************
63 * L O C A L   D A T A                                          *
64 ***************************************************************/
65 
66 static SequenceValues permissionsDefinition[] = {
67    {90, 1},
68    {10, 0},
69    {0,  0}
70 };
71 
72 /***************************************************************
73 * P U B L I C   D A T A                                        *
74 ***************************************************************/
75 
76 
77 /***************************************************************
78 ****************************************************************
79 * L O C A L   F U N C T I O N S   C O D E   S E C T I O N      *
80 ****************************************************************
81 ***************************************************************/
82 
getRandomSubscriberData(int subscriberNo,SubscriberNumber number,SubscriberName name)83 static void getRandomSubscriberData(int              subscriberNo,
84 		                    SubscriberNumber number,
85 		                    SubscriberName   name)
86 {
87    char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1];
88    sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, subscriberNo);
89    memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH);
90 
91    memset(name, myRandom48(26)+'A', SUBSCRIBER_NAME_LENGTH);
92 }
93 
populate(const char * title,int count,void (* func)(UserHandle *,int),UserHandle * uh)94 static void populate(const char *title,
95                      int   count,
96                      void (*func)(UserHandle*, int),
97                      UserHandle *uh)
98 {
99    ndbout_c("Populating %d '%s' ... ",count, title);
100    /* fflush(stdout); */
101    func(uh,count);
102    ndbout_c("done");
103 }
104 
populateServers(UserHandle * uh,int count)105 static void populateServers(UserHandle *uh, int count)
106 {
107    int  i, j;
108    int len;
109    char tmp[80];
110    int suffix_length = 1;
111    ServerName serverName;
112    SubscriberSuffix suffix;
113 
114    int commitCount = 0;
115 
116    for(i = 0; i < SUBSCRIBER_NUMBER_SUFFIX_LENGTH; i++)
117      suffix_length *= 10;
118 
119    for(i = 0; i < count; i++) {
120       sprintf(tmp, "-Server %d-", i);
121 
122       len = (int)strlen(tmp);
123       for(j = 0; j < SERVER_NAME_LENGTH; j++){
124          serverName[j] = tmp[j % len];
125       }
126       /* serverName[j] = 0;	not null-terminated */
127 
128       for(j = 0; j < suffix_length; j++){
129 	 char sbuf[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 1];
130          sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, j);
131 	 memcpy(suffix, sbuf, SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
132          userDbInsertServer(uh, i, suffix, serverName);
133 	 commitCount ++;
134 	 if((commitCount % OP_PER_TRANS) == 0)
135 	   userDbCommit(uh);
136       }
137    }
138    if((commitCount % OP_PER_TRANS) != 0)
139      userDbCommit(uh);
140 }
141 
populateSubscribers(UserHandle * uh,int count)142 static void populateSubscribers(UserHandle *uh, int count)
143 {
144    SubscriberNumber number;
145    SubscriberName   name;
146    int i, j, k;
147    int res;
148 
149    SequenceValues values[NO_OF_GROUPS+1];
150    RandomSequence seq;
151 
152    for(i = 0; i < NO_OF_GROUPS; i++) {
153       values[i].length = 1;
154       values[i].value  = i;
155    }
156 
157    values[i].length = 0;
158    values[i].value  = 0;
159 
160    if( initSequence(&seq, values) != 0 ) {
161       ndbout_c("could not set the sequence of random groups");
162       exit(0);
163    }
164 
165 #define RETRIES 25
166 
167    for(i = 0; i < count; i+= OP_PER_TRANS) {
168      for(j = 0; j<RETRIES; j++){
169        for(k = 0; k<OP_PER_TRANS && i+k < count; k++){
170 	 getRandomSubscriberData(i+k, number, name);
171 	 userDbInsertSubscriber(uh, number, getNextRandom(&seq), name);
172        }
173        res = userDbCommit(uh);
174        if(res == 0)
175 	 break;
176        if(res != 1){
177 	 ndbout_c("Terminating");
178 	 exit(0);
179        }
180      }
181      if(j == RETRIES){
182        ndbout_c("Terminating");
183        exit(0);
184      }
185    }
186 }
187 
populateGroups(UserHandle * uh,int count)188 static void populateGroups(UserHandle *uh, int count)
189 {
190    int i;
191    int j;
192    int len;
193    RandomSequence seq;
194    Permission     allow[NO_OF_GROUPS];
195    ServerBit      serverBit;
196    GroupName      groupName;
197    char           tmp[80];
198    int commitCount = 0;
199 
200    if( initSequence(&seq, permissionsDefinition) != 0 ) {
201       ndbout_c("could not set the sequence of random permissions");
202       exit(0);
203    }
204 
205    for(i = 0; i < NO_OF_GROUPS; i++)
206       allow[i] = 0;
207 
208    for(i = 0; i < NO_OF_SERVERS; i++) {
209       serverBit = 1 << i;
210 
211       for(j = 0; j < NO_OF_GROUPS; j++ ) {
212          if( getNextRandom(&seq) )
213             allow[j] |= serverBit;
214       }
215    }
216 
217    for(i = 0; i < NO_OF_GROUPS; i++) {
218       sprintf(tmp, "-Group %d-", i);
219 
220       len = (int)strlen(tmp);
221 
222       for(j = 0; j < GROUP_NAME_LENGTH; j++) {
223         groupName[j] = tmp[j % len];
224       }
225       /* groupName[j] = 0;	not null-terminated */
226 
227       userDbInsertGroup(uh,
228 		        i,
229 		        groupName,
230 		        allow[i],
231 		        allow[i],
232 		        allow[i]);
233       commitCount ++;
234       if((commitCount % OP_PER_TRANS) == 0)
235 	userDbCommit(uh);
236    }
237    if((commitCount % OP_PER_TRANS) != 0)
238      userDbCommit(uh);
239 }
240 
241 /***************************************************************
242 ****************************************************************
243 * P U B L I C   F U N C T I O N S   C O D E   S E C T I O N    *
244 ****************************************************************
245 ***************************************************************/
246 
247 extern int subscriberCount;
248 
dbPopulate(UserHandle * uh)249 void dbPopulate(UserHandle *uh)
250 {
251    populate("servers", NO_OF_SERVERS, populateServers, uh);
252    populate("subscribers", subscriberCount, populateSubscribers, uh);
253    populate("groups", NO_OF_GROUPS, populateGroups, uh);
254 }
255