├── logs
└── .logs_here
├── res
└── wait.gif
├── src
├── t
├── t.bat
├── m
├── m.bat
├── npp_app.h
├── npp_svc.cpp
└── npp_app.cpp
├── README.md
├── resmin
├── npp.css
├── dsk.css
├── dsk.js
└── npp.js
├── LICENSE
├── bin
├── npp.conf
├── nppstop
├── nppstart
├── nppmake.bat
└── nppmake
└── lib
├── Cusers_groups.h
├── Cusers_avatars.h
├── Cusers_p_resets.h
├── Cusers_settings.h
├── Cusers_messages.h
├── Cusers_activations.h
├── Cusers_logins.h
├── users.sql
├── Cusers.h
├── npp_watcher.c
├── Cusers_groups.cpp
├── Cusers_avatars.cpp
├── Cusers_settings.cpp
├── Cusers_p_resets.cpp
├── Cusers_messages.cpp
├── Cusers_activations.cpp
├── Cusers_logins.cpp
├── npp_usr.h
├── Cusers.cpp
└── npp_update.c
/logs/.logs_here:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/res/wait.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rekmus/perf-web/master/res/wait.gif
--------------------------------------------------------------------------------
/src/t:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export NPP_DIR=..
4 |
5 | $NPP_DIR/bin/npp_app 8080
6 |
--------------------------------------------------------------------------------
/src/t.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | set NPP_DIR=..
4 |
5 | %NPP_DIR%\bin\npp_app 8080
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # perf
2 | Web application performance tester with browser interface (based on Node++)
3 |
4 |
5 |

6 |
7 |
8 |
--------------------------------------------------------------------------------
/resmin/npp.css:
--------------------------------------------------------------------------------
1 | // ----------------------------------------
2 | // wait animation
3 | .wt
4 | {
5 | display: none;
6 | position: fixed;
7 | top: 0;
8 | left: 0;
9 | width: 100%;
10 | height: 100%;
11 | z-index: 900;
12 | background: url('/wait.gif') 50% 50% no-repeat;
13 | background-size: 52px;
14 | }
15 |
16 |
17 | // ----------------------------------------
18 | // modal window
19 | .mw
20 | {
21 | font-size: 12pt;
22 | background-color: white;
23 | padding: 3px 12px 13px 14px;
24 | box-shadow: 4px 4px 16px 0px rgba(0,0,0,0.2);
25 | border: 1px solid #bbbbbb;
26 | z-index: 1000;
27 | }
28 |
29 |
30 | // ----------------------------------------
31 | // yes/no buttons
32 | .ynb
33 | {
34 | width: 80px;
35 | height: 32px;
36 | margin-top: 20px;
37 | }
38 |
--------------------------------------------------------------------------------
/src/m:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # ----------------------------------------------------------------------------
4 | # Set the local compilation environment here
5 | # ----------------------------------------------------------------------------
6 |
7 |
8 | # ----------------------------------------------------------------------------
9 | # Set include path (might be required for OpenSSL and MySQL)
10 | # Example: export CPATH=/usr/include/mysql
11 |
12 | #export CPATH=
13 |
14 |
15 | # ----------------------------------------------------------------------------
16 | # Set library path (might be required for OpenSSL and MySQL)
17 | # Example: export LIBRARY_PATH=/usr/lib64/mysql
18 |
19 | #export LIBRARY_PATH=
20 |
21 |
22 | # ----------------------------------------------------------------------------
23 | # Call the main making script (don't change this)
24 |
25 | ../bin/nppmake $1
26 |
--------------------------------------------------------------------------------
/src/m.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem ----------------------------------------------------------------------------
4 | rem Set the local compilation environment here
5 | rem ----------------------------------------------------------------------------
6 |
7 |
8 | rem ----------------------------------------------------------------------------
9 | rem Set include path (might be required for OpenSSL and MySQL)
10 | rem Example: set CPATH=C:\usr\include;C:\usr\include\mysql
11 |
12 | rem set CPATH=
13 |
14 |
15 | rem ----------------------------------------------------------------------------
16 | rem Set library path (might be required for OpenSSL and MySQL)
17 | rem Example: set LIBRARY_PATH=C:\usr\lib\openssl;C:\usr\lib\mysql
18 |
19 | rem set LIBRARY_PATH=
20 |
21 |
22 | rem ----------------------------------------------------------------------------
23 | rem Call the main making script (don't change this)
24 |
25 | call ..\bin\nppmake.bat %1
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Jurek Muszynski
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/npp_app.h:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------------------
2 | Silgy Web App
3 | Jurek Muszynski
4 | -----------------------------------------------------------------------------
5 | Web App Performance Tester
6 | -------------------------------------------------------------------------- */
7 |
8 | #ifndef NPP_APP_H
9 | #define NPP_APP_H
10 |
11 |
12 | #define NPP_APP_NAME "Web App Performance Tester"
13 | #define NPP_REQUIRED_AUTH_LEVEL AUTH_LEVEL_ANONYMOUS
14 |
15 |
16 | /* List of additional C/C++ modules to compile. They have to be one-liners */
17 |
18 | #define NPP_APP_MODULES ""
19 | #define NPP_SVC_MODULES NPP_APP_MODULES
20 |
21 |
22 | #define NPP_ASYNC
23 | #define NPP_ASYNC_INCLUDE_SESSION_DATA
24 |
25 | #define NPP_MEM_MEDIUM
26 |
27 |
28 | #define NPP_HTTPS
29 | #define NPP_NO_HSTS
30 |
31 | //#define NPP_FD_MON_LINUX_POLL
32 | //#define NPP_DEBUG
33 |
34 |
35 | #define WAIT "onClick=\"wait();\""
36 | #define ONKEYDOWN "onkeydown=\"ent(event);\""
37 |
38 |
39 | /* app session data */
40 | /* accessible via SESSION_DATA macro */
41 |
42 | typedef struct {
43 | char url[256];
44 | int batch;
45 | int times;
46 | bool keep;
47 | double elapsed;
48 | } app_session_data_t;
49 |
50 |
51 | #endif /* NPP_APP_H */
52 |
--------------------------------------------------------------------------------
/bin/npp.conf:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Node++ application configuration file
3 | #
4 | # This file should be placed in $NPP_DIR/bin
5 | #
6 | # By default it's read at startup only
7 | #
8 | # With NPP_ENABLE_RELOAD_CONF defined in npp_app.h
9 | # it can be reloaded online by sending
10 | # POST /npp_reload_conf from its host (i.e. using curl)
11 | # ----------------------------------------------------------------------------
12 |
13 | # ----------------------------------------------------------------------------
14 | # Log
15 |
16 | logLevel=2 # between 0...4 (most detailed)
17 | logToStdout=0
18 | logCombined=0
19 |
20 |
21 | # ----------------------------------------------------------------------------
22 | # Ports
23 |
24 | httpPort=8080
25 | httpsPort=8443
26 |
27 |
28 | # ----------------------------------------------------------------------------
29 | # HTTPS
30 |
31 | #certFile=/home/ec2-user/dev/bin/cert.pem
32 | #keyFile=/home/ec2-user/dev/bin/key.pem
33 |
34 |
35 | # ----------------------------------------------------------------------------
36 | # Database connection details
37 |
38 | #dbName=nodepp
39 | #dbUser=nodepp
40 | #dbPassword=nodepp
41 |
42 |
43 | # ----------------------------------------------------------------------------
44 | # Number of ASYNC (npp_svc) processes
45 |
46 | ASYNCSvcProcesses=10
47 |
48 |
49 | # ----------------------------------------------------------------------------
50 | # Setting this to 1 will add _t to the log file name and will cause
51 | # engine to ignore security redirections (NPP_DOMAIN_ONLY and HSTS)
52 | # to allow testing from localhost and without SSL.
53 | # For details search for "redirections table" in npp_eng_app.c.
54 |
55 | test=0
56 |
--------------------------------------------------------------------------------
/lib/Cusers_groups.h:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:15:25, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #ifndef CUSERS_GROUPS_H
9 | #define CUSERS_GROUPS_H
10 |
11 |
12 | #include
13 |
14 |
15 | typedef char USERS_GROUPS_NAME[120+1];
16 | typedef char USERS_GROUPS_ABOUT[250+1];
17 |
18 |
19 | typedef struct
20 | {
21 | int id;
22 | USERS_GROUPS_NAME name;
23 | USERS_GROUPS_ABOUT about;
24 | char auth_level;
25 | } USERS_GROUPS_REC;
26 |
27 |
28 | class Cusers_groups : public USERS_GROUPS_REC, public Cdb
29 | {
30 | public:
31 | Cusers_groups();
32 | ~Cusers_groups();
33 |
34 | // Get the next record
35 | // Return false if end of record set
36 | bool Fetch();
37 |
38 | // Get one record by PK
39 | // Not Found will return false
40 | bool Get(int arg_id);
41 |
42 | // Insert record
43 | unsigned Insert();
44 |
45 | // Update record by PK
46 | void Update(int arg_id);
47 |
48 | // Delete record by PK
49 | void Delete(int arg_id);
50 |
51 | // Insert or update record by PK
52 | void Set(int arg_id);
53 |
54 | // Reset all values
55 | void Reset();
56 |
57 |
58 | private:
59 | static bool slots_[CDB_MAX_INSTANCES];
60 |
61 | int k_id_;
62 |
63 | unsigned long name_len_;
64 | unsigned long about_len_;
65 |
66 |
67 | my_bool id_is_null_;
68 | my_bool name_is_null_;
69 | my_bool about_is_null_;
70 | my_bool auth_level_is_null_;
71 |
72 | MYSQL_BIND bndk_[1];
73 | MYSQL_BIND bndi_[5];
74 | MYSQL_BIND bndo_[4];
75 |
76 | void bindKey(MYSQL_STMT *s, int arg_id);
77 | void bindInput(MYSQL_STMT *s, bool withKey=false, int arg_id=0);
78 | void bindOutput(MYSQL_STMT *s);
79 | void bindSetOutput();
80 |
81 | };
82 |
83 |
84 | #endif /* CUSERS_GROUPS_H */
85 |
--------------------------------------------------------------------------------
/resmin/dsk.css:
--------------------------------------------------------------------------------
1 | body {font-family:"Roboto", sans-serif; font-size:11pt; margin-bottom:3em;}
2 | h1 {display:inline-block; font-size:26pt; margin-left:10px; vertical-align:top; margin-top:10px; margin-bottom:0.8em; color:#303030;}
3 | h2 {text-align:center;}
4 | h3 {margin-top:30px;}
5 | input {font-size:11pt; padding-left:1px; padding-top:1px; box-sizing:border-box; -moz-box-sizing:border-box; -webkit-box-sizing:border-box;}
6 | a {color:#103890;}
7 | p {margin-top:5px; margin-bottom:5px;}
8 | .f13 {font-size:13pt;}
9 | .mt {padding:3px 5px;}
10 | .p2 {padding:2px 7px;}
11 | .wt {display:none; position:fixed; top:0; left:0; width:100%; height:100%; z-index:100; background:url(wait.gif) 50% 50% no-repeat; background-size:52px;}
12 | .ct {text-align:center;}
13 | .rt {text-align:right;}
14 | .m10 {margin-top:1em;}
15 | .m15 {margin-top:1.5em;}
16 | .m20 {margin-top:2em;}
17 | .m25 {margin-top:2.5em;}
18 | .m30 {margin-top:3em;}
19 | .m40 {margin-top:4em;}
20 | .m50 {margin-top:5em;}
21 | .sbb {width:7em; height:2.2em; margin-left:0.9em;}
22 | .w10p {width:10%;}
23 | .w30p {width:30%;}
24 | .w40p {width:40%;}
25 | .w50p {width:50%;}
26 | .w70p {width:70%;}
27 | .w75p {width:75%;}
28 | .w90p {width:90%;}
29 | .w100p {width:100%;}
30 | .w30em {width:30em;}
31 | .w40em {width:40em;}
32 | .mb5 {margin-bottom:5px;}
33 | .mono {font-family:monospace; font-size:10pt; white-space:pre;}
34 | .fl {display:flex;}
35 | .cl {font-size:1.5em; cursor:pointer;}
36 | .mm {display:inline-block; font-size:13pt; float:right; text-align:right; margin-top:12px; margin-right:17px;}
37 | .gr {color:grey;}
38 | .red {color:#b40000;}
39 | .ylw {color:#b09000;}
40 | .grn {color:#00a000;}
41 | .rlform {margin-top:50px; margin-left:10%; width:50%; text-align:right;}
42 | .rlbutton {margin-top:20px; height:36px; width:30%; margin-right:10%;}
43 | .acchist {border-collapse:collapse; border:1px solid #d8d8d8; padding:3px 6px;}
44 | .tdb {border-collapse:collapse; border:1px solid #d8d8d8; padding:3px 6px;}
45 | th {background-color:#f0f0f0;}
46 | .pt5 {padding-top:5px;}
47 | .pt20 {padding-top:20px;}
48 | .vat {vertical-align:top;}
49 | .but {margin-left:5px; width:84px; height:32px;}
50 |
--------------------------------------------------------------------------------
/lib/Cusers_avatars.h:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-29 20:06:23, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #ifndef CUSERS_AVATARS_H
9 | #define CUSERS_AVATARS_H
10 |
11 |
12 | #include
13 |
14 |
15 | typedef char USERS_AVATARS_AVATAR_NAME[120+1];
16 | typedef char USERS_AVATARS_AVATAR_DATA[65535+1];
17 |
18 |
19 | typedef struct
20 | {
21 | int user_id;
22 | USERS_AVATARS_AVATAR_NAME avatar_name;
23 | USERS_AVATARS_AVATAR_DATA avatar_data;
24 | int avatar_len;
25 | } USERS_AVATARS_REC;
26 |
27 |
28 | class Cusers_avatars : public USERS_AVATARS_REC, public Cdb
29 | {
30 | public:
31 | unsigned long avatar_data_len;
32 |
33 | Cusers_avatars();
34 | ~Cusers_avatars();
35 |
36 | // Get the next record
37 | // Return false if end of record set
38 | bool Fetch();
39 |
40 | // Get one record by PK
41 | // Not Found will return false
42 | bool Get(int arg_user_id);
43 |
44 | // Insert record
45 | unsigned Insert();
46 |
47 | // Update record by PK
48 | void Update(int arg_user_id);
49 |
50 | // Delete record by PK
51 | void Delete(int arg_user_id);
52 |
53 | // Insert or update record by PK
54 | void Set(int arg_user_id);
55 |
56 | // Reset all values
57 | void Reset();
58 |
59 |
60 | private:
61 | static bool slots_[CDB_MAX_INSTANCES];
62 |
63 | int k_user_id_;
64 |
65 | unsigned long avatar_name_len_;
66 |
67 |
68 | my_bool user_id_is_null_;
69 | my_bool avatar_name_is_null_;
70 | my_bool avatar_data_is_null_;
71 | my_bool avatar_len_is_null_;
72 |
73 | MYSQL_BIND bndk_[1];
74 | MYSQL_BIND bndi_[5];
75 | MYSQL_BIND bndo_[4];
76 |
77 | void bindKey(MYSQL_STMT *s, int arg_user_id);
78 | void bindInput(MYSQL_STMT *s, bool withKey=false, int arg_user_id=0);
79 | void bindOutput(MYSQL_STMT *s);
80 | void bindSetOutput();
81 |
82 | void genDTStrings();
83 | };
84 |
85 |
86 | #endif /* CUSERS_AVATARS_H */
87 |
--------------------------------------------------------------------------------
/lib/Cusers_p_resets.h:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:16:49, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #ifndef CUSERS_P_RESETS_H
9 | #define CUSERS_P_RESETS_H
10 |
11 |
12 | #include
13 |
14 |
15 | typedef char USERS_P_RESETS_LINKKEY[20+1];
16 | typedef char USERS_P_RESETS_CREATED[19+1];
17 |
18 |
19 | typedef struct
20 | {
21 | USERS_P_RESETS_LINKKEY linkkey;
22 | int user_id;
23 | USERS_P_RESETS_CREATED created;
24 | short tries;
25 | } USERS_P_RESETS_REC;
26 |
27 |
28 | class Cusers_p_resets : public USERS_P_RESETS_REC, public Cdb
29 | {
30 | public:
31 | Cusers_p_resets();
32 | ~Cusers_p_resets();
33 |
34 | // Get the next record
35 | // Return false if end of record set
36 | bool Fetch();
37 |
38 | // Get one record by PK
39 | // Not Found will return false
40 | bool Get(const std::string& arg_linkkey);
41 |
42 | // Insert record
43 | unsigned Insert();
44 |
45 | // Update record by PK
46 | void Update(const std::string& arg_linkkey);
47 |
48 | // Delete record by PK
49 | void Delete(const std::string& arg_linkkey);
50 |
51 | // Insert or update record by PK
52 | void Set(const std::string& arg_linkkey);
53 |
54 | // Reset all values
55 | void Reset();
56 |
57 |
58 | private:
59 | static bool slots_[CDB_MAX_INSTANCES];
60 |
61 | USERS_P_RESETS_LINKKEY k_linkkey_;
62 |
63 | unsigned long linkkey_len_;
64 | MYSQL_TIME t_created_;
65 |
66 | unsigned long k_linkkey_len_;
67 |
68 | my_bool linkkey_is_null_;
69 | my_bool user_id_is_null_;
70 | my_bool created_is_null_;
71 | my_bool tries_is_null_;
72 |
73 | MYSQL_BIND bndk_[1];
74 | MYSQL_BIND bndi_[5];
75 | MYSQL_BIND bndo_[4];
76 |
77 | void bindKey(MYSQL_STMT *s, const std::string& arg_linkkey);
78 | void bindInput(MYSQL_STMT *s, bool withKey=false, const std::string& arg_linkkey="");
79 | void bindOutput(MYSQL_STMT *s);
80 | void bindSetOutput();
81 |
82 | void genDTStrings();
83 | };
84 |
85 |
86 | #endif /* CUSERS_P_RESETS_H */
87 |
--------------------------------------------------------------------------------
/lib/Cusers_settings.h:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:16:04, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #ifndef CUSERS_SETTINGS_H
9 | #define CUSERS_SETTINGS_H
10 |
11 |
12 | #include
13 |
14 |
15 | typedef char USERS_SETTINGS_US_KEY[30+1];
16 | typedef char USERS_SETTINGS_US_VAL[250+1];
17 |
18 |
19 | typedef struct
20 | {
21 | int user_id;
22 | USERS_SETTINGS_US_KEY us_key;
23 | USERS_SETTINGS_US_VAL us_val;
24 | } USERS_SETTINGS_REC;
25 |
26 |
27 | class Cusers_settings : public USERS_SETTINGS_REC, public Cdb
28 | {
29 | public:
30 | Cusers_settings();
31 | ~Cusers_settings();
32 |
33 | // Get the next record
34 | // Return false if end of record set
35 | bool Fetch();
36 |
37 | // Get one record by PK
38 | // Not Found will return false
39 | bool Get(int arg_user_id, const std::string& arg_us_key);
40 |
41 | // Insert record
42 | unsigned Insert();
43 |
44 | // Update record by PK
45 | void Update(int arg_user_id, const std::string& arg_us_key);
46 |
47 | // Delete record by PK
48 | void Delete(int arg_user_id, const std::string& arg_us_key);
49 |
50 | // Insert or update record by PK
51 | void Set(int arg_user_id, const std::string& arg_us_key);
52 |
53 | // Reset all values
54 | void Reset();
55 |
56 |
57 | private:
58 | static bool slots_[CDB_MAX_INSTANCES];
59 |
60 | int k_user_id_;
61 | USERS_SETTINGS_US_KEY k_us_key_;
62 |
63 | unsigned long us_key_len_;
64 | unsigned long us_val_len_;
65 |
66 | unsigned long k_us_key_len_;
67 |
68 | my_bool user_id_is_null_;
69 | my_bool us_key_is_null_;
70 | my_bool us_val_is_null_;
71 |
72 | MYSQL_BIND bndk_[2];
73 | MYSQL_BIND bndi_[5];
74 | MYSQL_BIND bndo_[3];
75 |
76 | void bindKey(MYSQL_STMT *s, int arg_user_id, const std::string& arg_us_key);
77 | void bindInput(MYSQL_STMT *s, bool withKey=false, int arg_user_id=0, const std::string& arg_us_key="");
78 | void bindOutput(MYSQL_STMT *s);
79 | void bindSetOutput();
80 |
81 | };
82 |
83 |
84 | #endif /* CUSERS_SETTINGS_H */
85 |
--------------------------------------------------------------------------------
/lib/Cusers_messages.h:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:17:27, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #ifndef CUSERS_MESSAGES_H
9 | #define CUSERS_MESSAGES_H
10 |
11 |
12 | #include
13 |
14 |
15 | typedef char USERS_MESSAGES_EMAIL[120+1];
16 | typedef char USERS_MESSAGES_MESSAGE[65535+1];
17 | typedef char USERS_MESSAGES_CREATED[19+1];
18 |
19 |
20 | typedef struct
21 | {
22 | int user_id;
23 | int msg_id;
24 | USERS_MESSAGES_EMAIL email;
25 | USERS_MESSAGES_MESSAGE message;
26 | USERS_MESSAGES_CREATED created;
27 | } USERS_MESSAGES_REC;
28 |
29 |
30 | class Cusers_messages : public USERS_MESSAGES_REC, public Cdb
31 | {
32 | public:
33 | Cusers_messages();
34 | ~Cusers_messages();
35 |
36 | // Get the next record
37 | // Return false if end of record set
38 | bool Fetch();
39 |
40 | // Get one record by PK
41 | // Not Found will return false
42 | bool Get(int arg_user_id, int arg_msg_id);
43 |
44 | // Insert record
45 | unsigned Insert();
46 |
47 | // Update record by PK
48 | void Update(int arg_user_id, int arg_msg_id);
49 |
50 | // Delete record by PK
51 | void Delete(int arg_user_id, int arg_msg_id);
52 |
53 | // Insert or update record by PK
54 | void Set(int arg_user_id, int arg_msg_id);
55 |
56 | // Reset all values
57 | void Reset();
58 |
59 |
60 | private:
61 | static bool slots_[CDB_MAX_INSTANCES];
62 |
63 | int k_user_id_;
64 | int k_msg_id_;
65 |
66 | unsigned long email_len_;
67 | unsigned long message_len_;
68 | MYSQL_TIME t_created_;
69 |
70 |
71 | my_bool user_id_is_null_;
72 | my_bool msg_id_is_null_;
73 | my_bool email_is_null_;
74 | my_bool message_is_null_;
75 | my_bool created_is_null_;
76 |
77 | MYSQL_BIND bndk_[2];
78 | MYSQL_BIND bndi_[7];
79 | MYSQL_BIND bndo_[5];
80 |
81 | void bindKey(MYSQL_STMT *s, int arg_user_id, int arg_msg_id);
82 | void bindInput(MYSQL_STMT *s, bool withKey=false, int arg_user_id=0, int arg_msg_id=0);
83 | void bindOutput(MYSQL_STMT *s);
84 | void bindSetOutput();
85 |
86 | void genDTStrings();
87 | };
88 |
89 |
90 | #endif /* CUSERS_MESSAGES_H */
91 |
--------------------------------------------------------------------------------
/lib/Cusers_activations.h:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:16:31, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #ifndef CUSERS_ACTIVATIONS_H
9 | #define CUSERS_ACTIVATIONS_H
10 |
11 |
12 | #include
13 |
14 |
15 | typedef char USERS_ACTIVATIONS_LINKKEY[20+1];
16 | typedef char USERS_ACTIVATIONS_CREATED[19+1];
17 | typedef char USERS_ACTIVATIONS_ACTIVATED[19+1];
18 |
19 |
20 | typedef struct
21 | {
22 | USERS_ACTIVATIONS_LINKKEY linkkey;
23 | int user_id;
24 | USERS_ACTIVATIONS_CREATED created;
25 | USERS_ACTIVATIONS_ACTIVATED activated;
26 | } USERS_ACTIVATIONS_REC;
27 |
28 |
29 | class Cusers_activations : public USERS_ACTIVATIONS_REC, public Cdb
30 | {
31 | public:
32 | Cusers_activations();
33 | ~Cusers_activations();
34 |
35 | // Get the next record
36 | // Return false if end of record set
37 | bool Fetch();
38 |
39 | // Get one record by PK
40 | // Not Found will return false
41 | bool Get(const std::string& arg_linkkey);
42 |
43 | // Insert record
44 | unsigned Insert();
45 |
46 | // Update record by PK
47 | void Update(const std::string& arg_linkkey);
48 |
49 | // Delete record by PK
50 | void Delete(const std::string& arg_linkkey);
51 |
52 | // Insert or update record by PK
53 | void Set(const std::string& arg_linkkey);
54 |
55 | // Reset all values
56 | void Reset();
57 |
58 |
59 | private:
60 | static bool slots_[CDB_MAX_INSTANCES];
61 |
62 | USERS_ACTIVATIONS_LINKKEY k_linkkey_;
63 |
64 | unsigned long linkkey_len_;
65 | MYSQL_TIME t_created_;
66 | MYSQL_TIME t_activated_;
67 |
68 | unsigned long k_linkkey_len_;
69 |
70 | my_bool linkkey_is_null_;
71 | my_bool user_id_is_null_;
72 | my_bool created_is_null_;
73 | my_bool activated_is_null_;
74 |
75 | MYSQL_BIND bndk_[1];
76 | MYSQL_BIND bndi_[5];
77 | MYSQL_BIND bndo_[4];
78 |
79 | void bindKey(MYSQL_STMT *s, const std::string& arg_linkkey);
80 | void bindInput(MYSQL_STMT *s, bool withKey=false, const std::string& arg_linkkey="");
81 | void bindOutput(MYSQL_STMT *s);
82 | void bindSetOutput();
83 |
84 | void genDTStrings();
85 | };
86 |
87 |
88 | #endif /* CUSERS_ACTIVATIONS_H */
89 |
--------------------------------------------------------------------------------
/resmin/dsk.js:
--------------------------------------------------------------------------------
1 | var started;
2 | var batches_done=0;
3 | var elapsed=0;
4 |
5 |
6 | // --------------------------------------------------------------------------
7 | // AJAX call
8 | // --------------------------------------------------------------------------
9 | function sendreqs()
10 | {
11 | wait();
12 |
13 | let url = document.getElementById("url").value;
14 | let batches = document.getElementById("batches").value;
15 | let times = document.getElementById("times").value;
16 | let keep = document.getElementById("keep").checked;
17 |
18 | if ( batches < 1 ) batches = 1;
19 | if ( batches > 1000 ) batches = 1000;
20 |
21 | if ( times < 1 ) times = 1;
22 | if ( times > 100000 ) times = 100000;
23 |
24 | p(" ");
25 |
26 | p("Sending "+batches+" batch(es) of "+times+" requests each to "+url);
27 |
28 | p("keep = " + keep);
29 |
30 | url = encodeURIComponent(url);
31 |
32 | batches_done = 0;
33 | started = performance.now();
34 | elapsed = 0;
35 |
36 | for ( i=1; i<=batches; ++i )
37 | sendbatch(url, times, keep, i, batches);
38 |
39 | document.getElementById("url").focus();
40 | }
41 |
42 |
43 | // --------------------------------------------------------------------------
44 | // Send one request
45 | // --------------------------------------------------------------------------
46 | function sendbatch(url, times, keep, i, batches)
47 | {
48 | let x = new XMLHttpRequest();
49 |
50 | x.onreadystatechange = function(e)
51 | {
52 | if ( x.readyState == 4 ) // Done
53 | {
54 | ++batches_done;
55 |
56 | let ret = x.responseText.split("|");
57 |
58 | if ( ret[0]=="0" ) // OK
59 | {
60 | p(i+": Average = "+ret[2]+" ms");
61 |
62 | if ( batches_done==batches ) // the last one
63 | {
64 | elapsed = performance.now() - started;
65 | wait_off();
66 | p("elapsed: "+elapsed+" ms");
67 | let seconds = elapsed / 1000;
68 | let per_second = (times*batches) / seconds;
69 | p(parseInt(per_second, 10) + " per second");
70 | }
71 | }
72 | else // error
73 | {
74 | p(i+": Error: "+ret[1]);
75 |
76 | if ( batches_done==batches ) // the last one
77 | {
78 | wait_off();
79 | }
80 | }
81 | }
82 | };
83 |
84 | x.open("GET", "sendbatch?batch="+i+"&url="+url+"×="+times+"&keep="+keep, true);
85 | x.send();
86 | }
87 |
--------------------------------------------------------------------------------
/lib/Cusers_logins.h:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 14:28:27, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #ifndef CUSERS_LOGINS_H
9 | #define CUSERS_LOGINS_H
10 |
11 |
12 | #include
13 |
14 |
15 | typedef char USERS_LOGINS_SESSID[15+1];
16 | typedef char USERS_LOGINS_UAGENT[250+1];
17 | typedef char USERS_LOGINS_IP[45+1];
18 | typedef char USERS_LOGINS_CSRFT[7+1];
19 | typedef char USERS_LOGINS_CREATED[19+1];
20 | typedef char USERS_LOGINS_LAST_USED[19+1];
21 |
22 |
23 | typedef struct
24 | {
25 | USERS_LOGINS_SESSID sessid;
26 | USERS_LOGINS_UAGENT uagent;
27 | USERS_LOGINS_IP ip;
28 | int user_id;
29 | USERS_LOGINS_CSRFT csrft;
30 | USERS_LOGINS_CREATED created;
31 | USERS_LOGINS_LAST_USED last_used;
32 | } USERS_LOGINS_REC;
33 |
34 |
35 | class Cusers_logins : public USERS_LOGINS_REC, public Cdb
36 | {
37 | public:
38 | Cusers_logins();
39 | ~Cusers_logins();
40 |
41 | // Get the next record
42 | // Return false if end of record set
43 | bool Fetch();
44 |
45 | // Get one record by PK
46 | // Not Found will return false
47 | bool Get(const std::string& arg_sessid);
48 |
49 | // Insert record
50 | unsigned Insert();
51 |
52 | // Update record by PK
53 | void Update(const std::string& arg_sessid);
54 |
55 | // Delete record by PK
56 | void Delete(const std::string& arg_sessid);
57 |
58 | // Insert or update record by PK
59 | void Set(const std::string& arg_sessid);
60 |
61 | // Reset all values
62 | void Reset();
63 |
64 |
65 | private:
66 | static bool slots_[CDB_MAX_INSTANCES];
67 |
68 | USERS_LOGINS_SESSID k_sessid_;
69 |
70 | unsigned long sessid_len_;
71 | unsigned long uagent_len_;
72 | unsigned long ip_len_;
73 | unsigned long csrft_len_;
74 | MYSQL_TIME t_created_;
75 | MYSQL_TIME t_last_used_;
76 |
77 | unsigned long k_sessid_len_;
78 |
79 | my_bool sessid_is_null_;
80 | my_bool uagent_is_null_;
81 | my_bool ip_is_null_;
82 | my_bool user_id_is_null_;
83 | my_bool csrft_is_null_;
84 | my_bool created_is_null_;
85 | my_bool last_used_is_null_;
86 |
87 | MYSQL_BIND bndk_[1];
88 | MYSQL_BIND bndi_[8];
89 | MYSQL_BIND bndo_[7];
90 |
91 | void bindKey(MYSQL_STMT *s, const std::string& arg_sessid);
92 | void bindInput(MYSQL_STMT *s, bool withKey=false, const std::string& arg_sessid="");
93 | void bindOutput(MYSQL_STMT *s);
94 | void bindSetOutput();
95 |
96 | void genDTStrings();
97 | };
98 |
99 |
100 | #endif /* CUSERS_LOGINS_H */
101 |
--------------------------------------------------------------------------------
/bin/nppstop:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # ------------------------------------------------------------------------------
4 | #
5 | # MIT License
6 | #
7 | # Copyright (c) 2020-2022 Jurek Muszynski (rekmus)
8 | #
9 | # Permission is hereby granted, free of charge, to any person obtaining a copy
10 | # of this software and associated documentation files (the "Software"), to deal
11 | # in the Software without restriction, including without limitation the rights
12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | # copies of the Software, and to permit persons to whom the Software is
14 | # furnished to do so, subject to the following conditions:
15 | #
16 | # The above copyright notice and this permission notice shall be included in all
17 | # copies or substantial portions of the Software.
18 | #
19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | # SOFTWARE.
26 | #
27 | # ------------------------------------------------------------------------------
28 | #
29 | # Node++ stop
30 | # nodepp.org
31 | #
32 | # ------------------------------------------------------------------------------
33 |
34 |
35 | # ---------------------------------------------------------------------
36 | # Environment check
37 |
38 | if [ -z $NPP_DIR ]
39 | then
40 | if [ -f ./npp_app ]
41 | then
42 | echo "WARNING: No NPP_DIR variable, setting to parent directory"
43 | export NPP_DIR=..
44 | else
45 | echo "ERROR: No NPP_DIR variable and no npp_app file present in the current directory, couldn't stop."
46 | echo "Your npp_app should be in \$NPP_DIR/bin"
47 | echo "Set the NPP_DIR environment variable like this:"
48 | echo ""
49 | echo "export NPP_DIR=/path/to/npp_application"
50 | echo ""
51 | exit 1
52 | fi
53 | fi
54 |
55 | # ---------------------------------------------------------------------
56 |
57 | echo "Stopping Node++ App..."
58 |
59 | # ---------------------------------------------------------------------
60 | # Services
61 |
62 | if [ -n "$(find $NPP_DIR/bin -name 's_*.pid' | head -1)" ]
63 | then
64 | for f in $NPP_DIR/bin/s_*.pid
65 | do
66 | kill `cat ${f}`
67 | done
68 | fi
69 |
70 | # ---------------------------------------------------------------------
71 | # Main app
72 |
73 | if [ -f $NPP_DIR/bin/npp_app.pid ]
74 | then
75 | kill `cat $NPP_DIR/bin/npp_app.pid`
76 | fi
77 |
78 | # ---------------------------------------------------------------------
79 |
--------------------------------------------------------------------------------
/bin/nppstart:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # ------------------------------------------------------------------------------
4 | #
5 | # MIT License
6 | #
7 | # Copyright (c) 2020-2022 Jurek Muszynski (rekmus)
8 | #
9 | # Permission is hereby granted, free of charge, to any person obtaining a copy
10 | # of this software and associated documentation files (the "Software"), to deal
11 | # in the Software without restriction, including without limitation the rights
12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | # copies of the Software, and to permit persons to whom the Software is
14 | # furnished to do so, subject to the following conditions:
15 | #
16 | # The above copyright notice and this permission notice shall be included in all
17 | # copies or substantial portions of the Software.
18 | #
19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | # SOFTWARE.
26 | #
27 | # ------------------------------------------------------------------------------
28 | #
29 | # Node++ startup
30 | # nodepp.org
31 | #
32 | # ------------------------------------------------------------------------------
33 |
34 |
35 | # ---------------------------------------------------------------------
36 | # Environment check
37 |
38 | if [ -z $NPP_DIR ]
39 | then
40 | if [ -f ./npp_app ]
41 | then
42 | echo "WARNING: No NPP_DIR variable, setting to parent directory"
43 | export NPP_DIR=..
44 | else
45 | echo "ERROR: No NPP_DIR variable and no npp_app file present in the current directory, couldn't start."
46 | echo "Your npp_app should be in \$NPP_DIR/bin"
47 | echo "Set the NPP_DIR environment variable like this:"
48 | echo ""
49 | echo "export NPP_DIR=/path/to/npp_application"
50 | echo ""
51 | exit 1
52 | fi
53 | fi
54 |
55 | # ---------------------------------------------------------------------
56 |
57 | echo "Starting Node++ App..."
58 |
59 | # ---------------------------------------------------------------------
60 | # Main app
61 |
62 | nohup $NPP_DIR/bin/npp_app > /dev/null 2>&1 &
63 |
64 | # ---------------------------------------------------------------------
65 | # Services
66 |
67 | if [ -f $NPP_DIR/bin/npp.conf ]
68 | then
69 | NPP_SVC_PROCESSES=`grep '^ASYNCSvcProcesses' $NPP_DIR/bin/npp.conf | head -1 | cut -d '=' -f 2 | sed 's/\r$//'`
70 | fi
71 |
72 | if [ -z $NPP_SVC_PROCESSES ]
73 | then
74 | NPP_SVC_PROCESSES=0
75 | fi
76 |
77 | if [ $NPP_SVC_PROCESSES -ne 0 ]
78 | then
79 | echo "Starting" $NPP_SVC_PROCESSES "svc process(es)..."
80 |
81 | sleep 1 # wait for the ASYNC queues to open
82 |
83 | for i in `seq 1 $NPP_SVC_PROCESSES`
84 | do
85 | nohup $NPP_DIR/bin/npp_svc > /dev/null 2>&1 &
86 | done
87 | fi
88 |
89 | # ---------------------------------------------------------------------
90 |
91 | sleep 1 # return to prompt
92 |
--------------------------------------------------------------------------------
/lib/users.sql:
--------------------------------------------------------------------------------
1 | -- ----------------------------------------------------------------------------
2 | -- Node++ USERS module tables -- MySQL version
3 | -- nodepp.org
4 | -- ----------------------------------------------------------------------------
5 |
6 | -- users
7 |
8 | CREATE TABLE users
9 | (
10 | id INT auto_increment PRIMARY KEY,
11 | login CHAR(30),
12 | login_u CHAR(30), -- uppercase version
13 | email VARCHAR(120),
14 | email_u VARCHAR(120), -- uppercase version
15 | name VARCHAR(120),
16 | phone VARCHAR(30),
17 | passwd1 CHAR(44), -- SHA256 hash in base64
18 | passwd2 CHAR(44), -- SHA256 hash in base64
19 | lang CHAR(5),
20 | about VARCHAR(250),
21 | group_id INT,
22 | auth_level TINYINT, -- 10 = user, 20 = customer, 30 = staff, 40 = moderator, 50 = admin, 100 = root
23 | status TINYINT, -- 0 = inactive, 1 = active, 2 = locked, 3 = requires password change, 9 = deleted
24 | created DATETIME,
25 | last_login DATETIME,
26 | visits INT,
27 | ula_cnt INT, -- unsuccessful login attempt count
28 | ula_time DATETIME -- and time
29 | );
30 |
31 | CREATE INDEX users_login ON users (login_u);
32 | CREATE INDEX users_email ON users (email_u);
33 | CREATE INDEX users_last_login ON users (last_login);
34 |
35 |
36 | -- avatars
37 |
38 | CREATE TABLE users_avatars
39 | (
40 | user_id INT PRIMARY KEY,
41 | avatar_name VARCHAR(120),
42 | avatar_data BLOB, -- 64 KiB
43 | avatar_len INT
44 | );
45 |
46 |
47 | -- groups
48 |
49 | CREATE TABLE users_groups
50 | (
51 | id INT auto_increment PRIMARY KEY,
52 | name VARCHAR(120),
53 | about VARCHAR(250),
54 | auth_level TINYINT
55 | );
56 |
57 |
58 | -- user settings
59 |
60 | CREATE TABLE users_settings
61 | (
62 | user_id INT,
63 | us_key CHAR(30),
64 | us_val VARCHAR(250),
65 | PRIMARY KEY (user_id, us_key)
66 | );
67 |
68 |
69 | -- user logins
70 |
71 | CREATE TABLE users_logins
72 | (
73 | sessid CHAR(15) CHARACTER SET latin1 COLLATE latin1_bin PRIMARY KEY,
74 | uagent VARCHAR(250),
75 | ip CHAR(45),
76 | user_id INT,
77 | csrft CHAR(7),
78 | created DATETIME,
79 | last_used DATETIME
80 | );
81 |
82 | CREATE INDEX users_logins_uid ON users_logins (user_id);
83 |
84 |
85 | -- account activations
86 |
87 | CREATE TABLE users_activations
88 | (
89 | linkkey CHAR(20) CHARACTER SET latin1 COLLATE latin1_bin PRIMARY KEY,
90 | user_id INT,
91 | created DATETIME,
92 | activated DATETIME
93 | );
94 |
95 |
96 | -- password resets
97 |
98 | CREATE TABLE users_p_resets
99 | (
100 | linkkey CHAR(20) CHARACTER SET latin1 COLLATE latin1_bin PRIMARY KEY,
101 | user_id INT,
102 | created DATETIME,
103 | tries SMALLINT
104 | );
105 |
106 | CREATE INDEX users_p_resets_uid ON users_p_resets (user_id);
107 |
108 |
109 | -- messages
110 |
111 | CREATE TABLE users_messages
112 | (
113 | user_id INT,
114 | msg_id INT,
115 | email VARCHAR(120),
116 | message TEXT, -- 64 KiB limit
117 | created DATETIME,
118 | PRIMARY KEY (user_id, msg_id)
119 | );
120 |
--------------------------------------------------------------------------------
/src/npp_svc.cpp:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------------------
2 | Node++ Web App
3 | Jurek Muszynski
4 | -----------------------------------------------------------------------------
5 | Web App Performance Tester
6 | -------------------------------------------------------------------------- */
7 |
8 |
9 | #include
10 |
11 |
12 | /* ======================================================================= */
13 | /* =============================== SERVICES ============================== */
14 | /* ======================================================================= */
15 |
16 |
17 | /* --------------------------------------------------------------------------
18 | Service
19 | -------------------------------------------------------------------------- */
20 | int sendbatch(int ci)
21 | {
22 | INF("sendbatch");
23 |
24 | INF("batch = %d", SESSION_DATA.batch);
25 | INF("URL [%s]", SESSION_DATA.url);
26 | INF("times = %d", SESSION_DATA.times);
27 |
28 | struct timespec start;
29 | clock_gettime(MONOTONIC_CLOCK_NAME, &start);
30 |
31 | char perfreqid[256];
32 | bool success;
33 |
34 | for ( int i=0; itm_hour, G_ptm->tm_min, G_ptm->tm_sec, SESSION_DATA.batch, i);
40 | INF("perfreqid [%s]", perfreqid);
41 | CALL_HTTP_HEADER_SET("perfreqid", perfreqid);
42 |
43 | // if ( SESSION_DATA.keep )
44 | // success = npp_call_http(NULL, NULL, "GET", SESSION_DATA.url, FALSE, TRUE);
45 | // else
46 | success = CALL_HTTP(NULL, NULL, "GET", SESSION_DATA.url, SESSION_DATA.keep);
47 |
48 | if ( !success )
49 | {
50 | ERR("Remote call failed\n");
51 | SESSION_DATA.elapsed = npp_elapsed(&start);
52 | return ERR_REMOTE_CALL;
53 | }
54 |
55 | // INF("Remote call status: %d", CALL_HTTP_STATUS);
56 | }
57 |
58 | SESSION_DATA.elapsed = npp_elapsed(&start);
59 |
60 | INF("elapsed: %.3lf ms\n", SESSION_DATA.elapsed);
61 |
62 | return OK;
63 | }
64 |
65 |
66 |
67 |
68 | /* ======================================================================= */
69 | /* ========================== END OF SERVICES ============================ */
70 | /* ======================================================================= */
71 |
72 |
73 |
74 | /* --------------------------------------------------------------------------
75 | Entry point
76 | -------------------------------------------------------------------------- */
77 | void npp_svc_main(int ci)
78 | {
79 | if ( SVC("sendbatch") )
80 | ASYNC_ERR_CODE = sendbatch(ci);
81 |
82 | OUT("%d|", ASYNC_ERR_CODE);
83 |
84 | if ( ASYNC_ERR_CODE == ERR_REMOTE_CALL )
85 | OUT("Call failed");
86 | else if ( ASYNC_ERR_CODE == ERR_REMOTE_CALL_STATUS )
87 | OUT("Call response status wasn't successful");
88 | else if ( ASYNC_ERR_CODE == OK )
89 | OUT("OK");
90 |
91 | OUT("|%s", AMT(G_call_http_average));
92 | OUT("|%0.3lf", SESSION_DATA.elapsed);
93 |
94 | RES_DONT_CACHE;
95 | }
96 |
97 |
98 | /* --------------------------------------------------------------------------
99 | Server start
100 | Return true if successful
101 | -------------------------------------------------------------------------- */
102 | bool npp_svc_init()
103 | {
104 | return true;
105 | }
106 |
107 |
108 | /* --------------------------------------------------------------------------
109 | Server stop
110 | -------------------------------------------------------------------------- */
111 | void npp_svc_done()
112 | {
113 | }
114 |
--------------------------------------------------------------------------------
/lib/Cusers.h:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-29 20:05:41, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #ifndef CUSERS_H
9 | #define CUSERS_H
10 |
11 |
12 | #include
13 |
14 |
15 | typedef char USERS_LOGIN[30+1];
16 | typedef char USERS_LOGIN_U[30+1];
17 | typedef char USERS_EMAIL[120+1];
18 | typedef char USERS_EMAIL_U[120+1];
19 | typedef char USERS_NAME[120+1];
20 | typedef char USERS_PHONE[30+1];
21 | typedef char USERS_PASSWD1[44+1];
22 | typedef char USERS_PASSWD2[44+1];
23 | typedef char USERS_LANG[5+1];
24 | typedef char USERS_ABOUT[250+1];
25 | typedef char USERS_CREATED[19+1];
26 | typedef char USERS_LAST_LOGIN[19+1];
27 | typedef char USERS_ULA_TIME[19+1];
28 |
29 |
30 | typedef struct
31 | {
32 | int id;
33 | USERS_LOGIN login;
34 | USERS_LOGIN_U login_u;
35 | USERS_EMAIL email;
36 | USERS_EMAIL_U email_u;
37 | USERS_NAME name;
38 | USERS_PHONE phone;
39 | USERS_PASSWD1 passwd1;
40 | USERS_PASSWD2 passwd2;
41 | USERS_LANG lang;
42 | USERS_ABOUT about;
43 | int group_id;
44 | char auth_level;
45 | char status;
46 | USERS_CREATED created;
47 | USERS_LAST_LOGIN last_login;
48 | int visits;
49 | int ula_cnt;
50 | USERS_ULA_TIME ula_time;
51 | } USERS_REC;
52 |
53 |
54 | class Cusers : public USERS_REC, public Cdb
55 | {
56 | public:
57 | Cusers();
58 | ~Cusers();
59 |
60 | // Get the next record
61 | // Return false if end of record set
62 | bool Fetch();
63 |
64 | // Get one record by PK
65 | // Not Found will return false
66 | bool Get(int arg_id);
67 |
68 | // Insert record
69 | unsigned Insert();
70 |
71 | // Update record by PK
72 | void Update(int arg_id);
73 |
74 | // Delete record by PK
75 | void Delete(int arg_id);
76 |
77 | // Insert or update record by PK
78 | void Set(int arg_id);
79 |
80 | // Reset all values
81 | void Reset();
82 |
83 |
84 | private:
85 | static bool slots_[CDB_MAX_INSTANCES];
86 |
87 | int k_id_;
88 |
89 | unsigned long login_len_;
90 | unsigned long login_u_len_;
91 | unsigned long email_len_;
92 | unsigned long email_u_len_;
93 | unsigned long name_len_;
94 | unsigned long phone_len_;
95 | unsigned long passwd1_len_;
96 | unsigned long passwd2_len_;
97 | unsigned long lang_len_;
98 | unsigned long about_len_;
99 | MYSQL_TIME t_created_;
100 | MYSQL_TIME t_last_login_;
101 | MYSQL_TIME t_ula_time_;
102 |
103 |
104 | my_bool id_is_null_;
105 | my_bool login_is_null_;
106 | my_bool login_u_is_null_;
107 | my_bool email_is_null_;
108 | my_bool email_u_is_null_;
109 | my_bool name_is_null_;
110 | my_bool phone_is_null_;
111 | my_bool passwd1_is_null_;
112 | my_bool passwd2_is_null_;
113 | my_bool lang_is_null_;
114 | my_bool about_is_null_;
115 | my_bool group_id_is_null_;
116 | my_bool auth_level_is_null_;
117 | my_bool status_is_null_;
118 | my_bool created_is_null_;
119 | my_bool last_login_is_null_;
120 | my_bool visits_is_null_;
121 | my_bool ula_cnt_is_null_;
122 | my_bool ula_time_is_null_;
123 |
124 | MYSQL_BIND bndk_[1];
125 | MYSQL_BIND bndi_[20];
126 | MYSQL_BIND bndo_[19];
127 |
128 | void bindKey(MYSQL_STMT *s, int arg_id);
129 | void bindInput(MYSQL_STMT *s, bool withKey=false, int arg_id=0);
130 | void bindOutput(MYSQL_STMT *s);
131 | void bindSetOutput();
132 |
133 | void genDTStrings();
134 | };
135 |
136 |
137 | #endif /* CUSERS_H */
138 |
--------------------------------------------------------------------------------
/lib/npp_watcher.c:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------------------
2 |
3 | MIT License
4 |
5 | Copyright (c) 2020-2022 Jurek Muszynski (rekmus)
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
25 | -----------------------------------------------------------------------------
26 |
27 | Node++ Web App Engine
28 | Restart Node++ app if dead
29 | nodepp.org
30 |
31 | -------------------------------------------------------------------------- */
32 |
33 |
34 | #include "npp.h"
35 |
36 |
37 | #define STOP_COMMAND "$NPP_DIR/bin/nppstop"
38 | #define START_COMMAND "$NPP_DIR/bin/nppstart"
39 |
40 |
41 | int G_httpPort=80;
42 |
43 |
44 | static char M_watcherStopCmd[256];
45 | static char M_watcherStartCmd[256];
46 | static int M_watcherWait;
47 | static int M_watcherLogRestart;
48 |
49 |
50 | /* --------------------------------------------------------------------------
51 | Restart
52 | -------------------------------------------------------------------------- */
53 | static void restart()
54 | {
55 | ALWAYS_T("Restarting...");
56 |
57 | INF_T("Stopping...");
58 | INF_T(M_watcherStopCmd);
59 |
60 | if ( system(M_watcherStopCmd) != EXIT_SUCCESS )
61 | WAR("Couldn't execute %s", M_watcherStopCmd);
62 |
63 | npp_update_time_globals();
64 |
65 | INF_T("Waiting %d second(s)...", M_watcherWait);
66 | #ifdef _WIN32
67 | Sleep(M_watcherWait*1000);
68 | #else /* Linux */
69 | sleep(M_watcherWait);
70 | #endif
71 |
72 | npp_update_time_globals();
73 |
74 | INF_T("Starting...");
75 | INF_T(M_watcherStartCmd);
76 |
77 | if ( system(M_watcherStartCmd) != EXIT_SUCCESS )
78 | WAR("Couldn't execute %s", M_watcherStartCmd);
79 |
80 | #ifdef NPP_ADMIN_EMAIL
81 | if ( strlen(NPP_ADMIN_EMAIL) )
82 | {
83 | char message[1024];
84 | strcpy(message, "Node++ Watcher had to restart web server.");
85 | npp_email(NPP_ADMIN_EMAIL, "Node++ restart", message);
86 | }
87 | #endif
88 | }
89 |
90 |
91 | /* --------------------------------------------------------------------------
92 | main
93 | -------------------------------------------------------------------------- */
94 | int main(int argc, char *argv[])
95 | {
96 | /* library init ------------------------------------------------------ */
97 |
98 | if ( !npp_lib_init(FALSE, NULL) )
99 | return EXIT_FAILURE;
100 |
101 | /* ------------------------------------------------------------------- */
102 |
103 | if ( !npp_read_param_int("watcherLogLevel", &G_logLevel) )
104 | G_logLevel = 0; /* don't create log file */
105 |
106 | if ( !npp_read_param_int("watcherLogToStdout", &G_logToStdout) )
107 | G_logToStdout = 0;
108 |
109 | if ( !npp_read_param_str("watcherStopCmd", M_watcherStopCmd) )
110 | strcpy(M_watcherStopCmd, STOP_COMMAND);
111 |
112 | if ( !npp_read_param_str("watcherStartCmd", M_watcherStartCmd) )
113 | strcpy(M_watcherStartCmd, START_COMMAND);
114 |
115 | if ( !npp_read_param_int("watcherWait", &M_watcherWait) )
116 | M_watcherWait = 10;
117 |
118 | if ( !npp_read_param_int("watcherLogRestart", &M_watcherLogRestart) )
119 | M_watcherLogRestart = 3;
120 |
121 | /* start log --------------------------------------------------------- */
122 |
123 | if ( G_logLevel && !npp_log_start("watcher", FALSE, FALSE) )
124 | return EXIT_FAILURE;
125 |
126 | /* ------------------------------------------------------------------- */
127 |
128 | INF_T("Trying to connect...");
129 |
130 | G_callHTTPTimeout = 60000; /* 60 seconds */
131 |
132 | char url[1024];
133 |
134 | sprintf(url, "127.0.0.1:%d", G_httpPort);
135 |
136 | CALL_HTTP_HEADER_SET("User-Agent", "Node++ Watcher Bot");
137 |
138 | if ( !CALL_HTTP(NULL, NULL, "GET", url, FALSE) )
139 | {
140 | npp_update_time_globals();
141 |
142 | if ( M_watcherLogRestart > G_logLevel )
143 | {
144 | int old_level = G_logLevel;
145 | G_logLevel = M_watcherLogRestart;
146 | if ( old_level < 1 )
147 | npp_log_start("watcher", FALSE, FALSE);
148 | }
149 |
150 | ERR_T("Couldn't connect");
151 |
152 | restart();
153 | }
154 |
155 | /* ------------------------------------------------------------------- */
156 |
157 | npp_update_time_globals();
158 |
159 | INF_T("npp_watcher ended");
160 |
161 | npp_lib_done();
162 |
163 | return EXIT_SUCCESS;
164 | }
165 |
--------------------------------------------------------------------------------
/resmin/npp.js:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------------------
2 | // Show wait animation
3 | // --------------------------------------------------------------------------
4 | function wait()
5 | {
6 | if ( !document.getElementById("wait") )
7 | {
8 | let w = document.createElement("div");
9 | w.id = "wait";
10 | w.className = "wt"; // see npp.css
11 | w.style.display = "block";
12 | document.body.appendChild(w);
13 | }
14 | else
15 | document.getElementById("wait").style.display = "block";
16 | }
17 |
18 |
19 | // --------------------------------------------------------------------------
20 | // Turn the spinning wheel off
21 | // --------------------------------------------------------------------------
22 | function wait_off()
23 | {
24 | document.getElementById("wait").style.display = "none";
25 | }
26 |
27 |
28 | // --------------------------------------------------------------------------
29 | // Go to link
30 | // l = url
31 | // --------------------------------------------------------------------------
32 | function gt(l)
33 | {
34 | wait();
35 | window.location.href = l;
36 | }
37 |
38 |
39 | // --------------------------------------------------------------------------
40 | // Append a paragraph to the page
41 | // --------------------------------------------------------------------------
42 | function p(t)
43 | {
44 | let p = document.createElement("p");
45 | if ( t ) p.innerHTML = t;
46 | document.body.appendChild(p);
47 | return p;
48 | }
49 |
50 |
51 | // --------------------------------------------------------------------------
52 | // Enter or Esc key hit
53 | // --------------------------------------------------------------------------
54 | function ent(e)
55 | {
56 | if (e.keyCode==13) // Enter
57 | {
58 | document.getElementById("sbm").click(); // submit
59 | return false;
60 | }
61 | else if (e.keyCode==27) // Esc
62 | {
63 | document.getElementById("cnc").click(); // cancel
64 | return false;
65 | }
66 |
67 | return true;
68 | }
69 |
70 |
71 | // --------------------------------------------------------------------------
72 | // Return true if cookies are enabled
73 | // --------------------------------------------------------------------------
74 | function cookies()
75 | {
76 | try
77 | {
78 | document.cookie = "ct=1";
79 | let enabled = document.cookie.indexOf("ct=") !== -1;
80 | document.cookie = "ct=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";
81 | return enabled;
82 | }
83 | catch (e)
84 | {
85 | return false;
86 | }
87 | }
88 |
89 |
90 | // --------------------------------------------------------------------------
91 | // Center div
92 | // Call after appendChild
93 | // d = div handle
94 | // --------------------------------------------------------------------------
95 | function center(d)
96 | {
97 | d.style.position = "fixed";
98 | d.style.top = "50%";
99 | d.style.left = "50%";
100 | d.style.marginTop = -d.offsetTop/2 + "px";
101 | d.style.marginLeft = -d.offsetWidth/2 + "px";
102 | }
103 |
104 |
105 | // --------------------------------------------------------------------------
106 | // Create modal window
107 | // l1 = first line
108 | // l2 = second line
109 | // w = width (em)
110 | // --------------------------------------------------------------------------
111 | function mw(l1, l2, w)
112 | {
113 | let d = document.createElement("div");
114 |
115 | if ( w )
116 | d.style.width = w + "em";
117 | else
118 | d.style.width = "20em";
119 |
120 | d.className = "mw";
121 | d.id = "mw";
122 |
123 | let s1 = document.createElement("span");
124 |
125 | s1.innerHTML = ""
126 | + "
" + l1 + ""
127 | + "
✕
"
128 | + "
";
129 |
130 | d.appendChild(s1);
131 |
132 | if ( l2 )
133 | {
134 | let s2 = document.createElement("span");
135 | s2.innerHTML = l2;
136 | d.appendChild(s2);
137 | }
138 |
139 | document.body.appendChild(d);
140 | center(d);
141 |
142 | window.addEventListener("keydown", mw_off); // allow keyboard escape
143 | }
144 |
145 |
146 | // --------------------------------------------------------------------------
147 | // Remove modal window
148 | // --------------------------------------------------------------------------
149 | function mw_off(e)
150 | {
151 | if ( e && e.keyCode!=27 ) return;
152 | window.removeEventListener("keydown", mw_off);
153 | let d = document.getElementById("mw");
154 | d.parentNode.removeChild(d);
155 | }
156 |
157 |
158 | // --------------------------------------------------------------------------
159 | // Create Yes/No modal window
160 | // t = text to display
161 | // a = action if Yes
162 | // w = width (em)
163 | // --------------------------------------------------------------------------
164 | function yn(t, a, w)
165 | {
166 | mw(t, "
", w);
167 | }
168 |
169 |
170 | // --------------------------------------------------------------------------
171 | // Set client's time on the server
172 | // --------------------------------------------------------------------------
173 | function set_tz()
174 | {
175 | let dt = new Date();
176 |
177 | let x = new XMLHttpRequest();
178 |
179 | x.open("POST", "/npp_set_tz", true);
180 | x.send("tz=" + Intl.DateTimeFormat().resolvedOptions().timeZone + "&tzo=" + dt.getTimezoneOffset());
181 | }
182 |
--------------------------------------------------------------------------------
/bin/nppmake.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem ----------------------------------------------------------------------------
4 | rem
5 | rem MIT License
6 | rem
7 | rem Copyright (c) 2020-2022 Jurek Muszynski (rekmus)
8 | rem
9 | rem Permission is hereby granted, free of charge, to any person obtaining a copy
10 | rem of this software and associated documentation files (the "Software"), to deal
11 | rem in the Software without restriction, including without limitation the rights
12 | rem to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | rem copies of the Software, and to permit persons to whom the Software is
14 | rem furnished to do so, subject to the following conditions:
15 | rem
16 | rem The above copyright notice and this permission notice shall be included in all
17 | rem copies or substantial portions of the Software.
18 | rem
19 | rem THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | rem IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | rem FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | rem AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | rem LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | rem OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | rem SOFTWARE.
26 | rem
27 | rem ----------------------------------------------------------------------------
28 | rem
29 | rem Compile/make Node++ application on Windows
30 | rem This is a generic script -- customize your environment in src\m.bat
31 | rem nodepp.org
32 | rem
33 | rem ----------------------------------------------------------------------------
34 |
35 |
36 | set NPP_VERBOSE=0
37 | if /i "%1"=="v" set NPP_VERBOSE=1
38 |
39 |
40 | rem ----------------------------------------------------------------------------
41 | rem Determine Node++ modules that are enabled in npp_app.h
42 |
43 | call :get_presence "NPP_HTTPS" NPP_HTTPS
44 |
45 | call :get_presence "NPP_MYSQL" NPP_MYSQL
46 |
47 | call :get_presence "NPP_USERS" NPP_USERS
48 |
49 | call :get_presence "NPP_ICONV" NPP_ICONV
50 |
51 |
52 | rem ----------------------------------------------------------------------------
53 | rem APP modules to compile
54 |
55 | set "NPP_M_MODULES_APP=npp_app.cpp ..\lib\npp_eng_app.c ..\lib\npp_lib.c"
56 |
57 | call :get_quoted_value "NPP_APP_MODULES" NPP_APP_MODULES
58 |
59 | if not "%NPP_APP_MODULES%"=="" (
60 | set "NPP_M_MODULES_APP=%NPP_M_MODULES_APP% %NPP_APP_MODULES%"
61 | )
62 |
63 | if %NPP_MYSQL%==1 (
64 | set "NPP_M_MODULES_APP=%NPP_M_MODULES_APP% ..\lib\npp_mysql.cpp"
65 | )
66 |
67 | if %NPP_USERS%==1 (
68 | set "NPP_M_MODULES_APP=%NPP_M_MODULES_APP% ..\lib\npp_usr.cpp ..\lib\Cusers.cpp ..\lib\Cusers_avatars.cpp ..\lib\Cusers_groups.cpp ..\lib\Cusers_settings.cpp ..\lib\Cusers_logins.cpp ..\lib\Cusers_activations.cpp ..\lib\Cusers_p_resets.cpp ..\lib\Cusers_messages.cpp"
69 | )
70 |
71 | if %NPP_VERBOSE%==1 echo NPP_M_MODULES_APP=%NPP_M_MODULES_APP%
72 |
73 |
74 | rem ----------------------------------------------------------------------------
75 | rem NPP_CPP_STRINGS
76 |
77 | call :get_presence "NPP_CPP_STRINGS" NPP_CPP_STRINGS
78 |
79 | if %NPP_CPP_STRINGS%==1 (
80 | set "NPP_M_MODULES_APP=%NPP_M_MODULES_APP% -std=c++17"
81 | )
82 |
83 |
84 | rem ----------------------------------------------------------------------------
85 | rem Include paths
86 |
87 | set "NPP_M_INCLUDE=-I. -I..\lib"
88 |
89 | if %NPP_VERBOSE%==1 echo NPP_M_INCLUDE=%NPP_M_INCLUDE%
90 |
91 |
92 | rem ----------------------------------------------------------------------------
93 | rem System and third-party libraries
94 |
95 | set "NPP_M_LIBS_APP="
96 | set "NPP_M_LIBS_UPDATE="
97 |
98 | if %NPP_HTTPS%==1 (
99 | set "NPP_M_LIBS_APP=-lssl -lcrypto"
100 | set "NPP_M_LIBS_UPDATE=-lssl -lcrypto"
101 | )
102 |
103 | if %NPP_MYSQL%==1 (
104 | set "NPP_M_LIBS_APP=%NPP_M_LIBS_APP% -lmysql"
105 | )
106 |
107 | if %NPP_ICONV%==1 (
108 | set "NPP_M_LIBS_APP=%NPP_M_LIBS_APP% -liconv"
109 | )
110 |
111 | set "NPP_M_LIBS_APP=%NPP_M_LIBS_APP% -lpsapi -lws2_32"
112 | set "NPP_M_LIBS_UPDATE=%NPP_M_LIBS_UPDATE% -lpsapi -lws2_32"
113 |
114 | if %NPP_VERBOSE%==1 echo NPP_M_LIBS_APP=%NPP_M_LIBS_APP%
115 | if %NPP_VERBOSE%==1 echo NPP_M_LIBS_UPDATE=%NPP_M_LIBS_UPDATE%
116 |
117 |
118 | rem ----------------------------------------------------------------------------
119 | rem Compile
120 |
121 | call :get_quoted_value "NPP_APP_NAME" NPP_APP_NAME
122 |
123 | if not "%NPP_APP_NAME%"=="" (
124 | echo Building %NPP_APP_NAME%...
125 | ) else (
126 | echo Building application...
127 | )
128 |
129 | echo Making npp_app...
130 |
131 | g++ %NPP_M_MODULES_APP% ^
132 | -D NPP_APP ^
133 | %NPP_M_INCLUDE% ^
134 | %NPP_M_LIBS_APP% ^
135 | -O3 ^
136 | -o ..\bin\npp_app ^
137 | -static
138 |
139 |
140 | if %errorlevel% neq 0 goto :eof
141 |
142 |
143 | if /i "%1"=="all" (
144 |
145 | echo Making npp_watcher...
146 |
147 | gcc ..\lib\npp_watcher.c ^
148 | ..\lib\npp_lib.c ^
149 | -D NPP_WATCHER ^
150 | %NPP_M_INCLUDE% ^
151 | -lws2_32 -lpsapi ^
152 | -O3 ^
153 | -o ..\bin\npp_watcher ^
154 | -static
155 |
156 |
157 | echo Making npp_update...
158 |
159 | gcc ..\lib\npp_update.c ^
160 | ..\lib\npp_lib.c ^
161 | -D NPP_UPDATE ^
162 | %NPP_M_INCLUDE% ^
163 | %NPP_M_LIBS_UPDATE% ^
164 | -O3 ^
165 | -o ..\bin\npp_update ^
166 | -static
167 |
168 | )
169 |
170 |
171 | goto :eof
172 |
173 |
174 | rem ----------------------------------------------------------------------------
175 | rem Functions
176 |
177 | :get_presence
178 | set %~2=0
179 | set FIRST_TOKEN="x"
180 | for /f %%i in ('findstr /r /c:"^#define *%~1$" npp_app.h') do set FIRST_TOKEN=%%i
181 | if "%FIRST_TOKEN%"=="#define" set %~2=1
182 | goto :eof
183 |
184 |
185 | :get_value
186 | set "%~2="
187 | for /f tokens^=3 %%i in ('findstr /r /c:"^#define *%~1" npp_app.h') do set %~2=%%i
188 | goto :eof
189 |
190 |
191 | :get_quoted_value
192 | set "%~2="
193 | for /f delims^=^"^ tokens^=2 %%i in ('findstr /r /c:"^#define *%~1" npp_app.h') do set %~2=%%i
194 | goto :eof
195 |
--------------------------------------------------------------------------------
/src/npp_app.cpp:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------------------
2 | Node++ Web App
3 | Jurek Muszynski
4 | -----------------------------------------------------------------------------
5 | Web App Performance Tester
6 | -------------------------------------------------------------------------- */
7 |
8 |
9 | #include
10 |
11 |
12 | /* --------------------------------------------------------------------------
13 | Output HTML & page header
14 | -------------------------------------------------------------------------- */
15 | void gen_header(int ci)
16 | {
17 | OUT("");
18 | OUT("");
19 | OUT("");
20 | OUT("");
21 | OUT("%s", NPP_APP_NAME);
22 | OUT("");
23 | OUT("");
24 | OUT("");
25 | OUT("");
26 | OUT("");
27 |
28 | OUT("");
29 |
30 | if ( REQ("") || REQ("dashboard") )
31 | OUT("%s
", NPP_APP_NAME);
32 | else
33 | OUT("", WAIT, NPP_APP_NAME);
34 |
35 | char lnk_home[256]="Home";
36 |
37 | if ( REQ("") )
38 | strcpy(lnk_home, "Home");
39 |
40 | OUT("");
41 | if ( !REQ("") ) OUT(lnk_home);
42 | OUT("
");
43 | }
44 |
45 |
46 | /* --------------------------------------------------------------------------
47 | Output footer; body & html tags close here
48 | -------------------------------------------------------------------------- */
49 | void gen_footer(int ci)
50 | {
51 | OUT("");
52 | }
53 |
54 |
55 | /* --------------------------------------------------------------------------
56 | Show main page
57 | -------------------------------------------------------------------------- */
58 | void gen_page_main(int ci)
59 | {
60 | gen_header(ci);
61 |
62 | OUT("");
69 |
70 | gen_footer(ci);
71 | }
72 |
73 |
74 | /* --------------------------------------------------------------------------
75 | Send one batch (AJAX)
76 | -------------------------------------------------------------------------- */
77 | void sendbatch(int ci)
78 | {
79 | if ( !QSI("batch", &SESSION_DATA.batch) ) return;
80 | if ( !QS("url", SESSION_DATA.url) ) return;
81 | if ( !QSI("times", &SESSION_DATA.times) ) return;
82 |
83 | QSB("keep", &SESSION_DATA.keep);
84 |
85 | if ( SESSION_DATA.times < 1 ) SESSION_DATA.times = 1;
86 | if ( SESSION_DATA.times > 100000 ) SESSION_DATA.times = 100000;
87 |
88 | INF("batch = %d", SESSION_DATA.batch);
89 | INF("URL [%s]", SESSION_DATA.url);
90 | INF("times = %d", SESSION_DATA.times);
91 | INF("keep = %s", SESSION_DATA.keep?"true":"false");
92 |
93 | CALL_ASYNC_TM("sendbatch", 600); // 10 minutes timeout
94 | }
95 |
96 |
97 | /* --------------------------------------------------------------------------------
98 | This is the main entry point for a request
99 | ------------------------------
100 | Called after parsing HTTP request headers
101 | ------------------------------
102 | If required (NPP_REQUIRED_AUTH_LEVEL >= AUTH_LEVEL_ANONYMOUS),
103 | the session is already created
104 |
105 | If valid ls cookie is present in the request or
106 | it's over existing connection that has already been authenticated,
107 | the session is already authenticated
108 | ------------------------------
109 | Response status is 200 by default
110 | Use RES_STATUS() if you want to change it
111 |
112 | Response content type is text/html by default
113 | Use RES_CONTENT_TYPE() if you want to change it
114 | -------------------------------------------------------------------------------- */
115 | void npp_app_main(int ci)
116 | {
117 | if ( REQ("sendbatch") )
118 | sendbatch(ci);
119 | else
120 | gen_page_main(ci);
121 | }
122 |
123 |
124 | /* --------------------------------------------------------------------------------
125 | Called when application starts
126 | ------------------------------
127 | Return true if everything OK
128 | ------------------------------
129 | Returning false will stop booting process,
130 | npp_app_done() will be called and application will be terminated
131 | -------------------------------------------------------------------------------- */
132 | bool npp_app_init(int argc, char *argv[])
133 | {
134 | return true;
135 | }
136 |
137 |
138 | /* --------------------------------------------------------------------------------
139 | Called when new anonymous user session starts
140 | ------------------------------
141 | Return true if everything OK
142 | ------------------------------
143 | Returning false will cause the session to be closed
144 | and npp_app_session_done() will be called
145 | Response status will be set to 500
146 | -------------------------------------------------------------------------------- */
147 | bool npp_app_session_init(int ci)
148 | {
149 | return true;
150 | }
151 |
152 |
153 | /* --------------------------------------------------------------------------------
154 | ******* Only for USERS *******
155 | ------------------------------
156 | Called after successful authentication (using password or cookie)
157 | when user session is upgraded from anonymous to logged in
158 | ------------------------------
159 | Return true if everything OK
160 | ------------------------------
161 | Returning false will cause the session to be downgraded back to anonymous
162 | and npp_app_user_logout() will be called
163 | -------------------------------------------------------------------------------- */
164 | bool npp_app_user_login(int ci)
165 | {
166 | return true;
167 | }
168 |
169 |
170 | /* --------------------------------------------------------------------------------
171 | ******* Only for USERS *******
172 | ------------------------------
173 | Called when downgrading logged in user session to anonymous
174 | -------------------------------------------------------------------------------- */
175 | void npp_app_user_logout(int ci)
176 | {
177 | }
178 |
179 |
180 | /* --------------------------------------------------------------------------------
181 | Called when closing anonymous user session
182 | After calling this the session memory will be zero-ed
183 | -------------------------------------------------------------------------------- */
184 | void npp_app_session_done(int ci)
185 | {
186 | }
187 |
188 |
189 | /* --------------------------------------------------------------------------------
190 | Called when application shuts down
191 | -------------------------------------------------------------------------------- */
192 | void npp_app_done()
193 | {
194 | }
195 |
--------------------------------------------------------------------------------
/bin/nppmake:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # ------------------------------------------------------------------------------
4 | #
5 | # MIT License
6 | #
7 | # Copyright (c) 2020-2022 Jurek Muszynski (rekmus)
8 | #
9 | # Permission is hereby granted, free of charge, to any person obtaining a copy
10 | # of this software and associated documentation files (the "Software"), to deal
11 | # in the Software without restriction, including without limitation the rights
12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | # copies of the Software, and to permit persons to whom the Software is
14 | # furnished to do so, subject to the following conditions:
15 | #
16 | # The above copyright notice and this permission notice shall be included in all
17 | # copies or substantial portions of the Software.
18 | #
19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | # SOFTWARE.
26 | #
27 | # ------------------------------------------------------------------------------
28 | #
29 | # Compile/make Node++ application on Linux/Unix
30 | # This is a generic script -- customize your environment in src/m
31 | # nodepp.org
32 | #
33 | # ------------------------------------------------------------------------------
34 |
35 |
36 | NPP_VERBOSE=0
37 | if [ "$1" = "v" ] || [ "$1" = "V" ]
38 | then
39 | NPP_VERBOSE=1
40 | fi
41 |
42 |
43 | # ----------------------------------------------------------------------------
44 | # Functions
45 |
46 | get_presence () {
47 | local present=`grep "^#define\s*$1[[:cntrl:]]*$" npp_app.h | head -1 | awk '{ print $2 }' | sed 's/\r$//'`
48 |
49 | if [ "$present" = "$1" ]
50 | then
51 | echo 1
52 | else
53 | echo 0
54 | fi
55 | }
56 |
57 | get_value () {
58 | echo `grep "^#define\s*$1\s" npp_app.h | head -1 | awk '{ print $3 }' | sed 's/\r$//'`
59 | }
60 |
61 | get_quoted_value () {
62 | echo `grep "^#define\s*$1\s" npp_app.h | head -1 | awk -F'"' '{ print $2 }'`
63 | }
64 |
65 |
66 | # ----------------------------------------------------------------------------
67 | # Determine the OS family
68 |
69 | NPP_OS=`grep ID_LIKE /etc/os-release | head -1 | cut -d '=' -f 2`
70 |
71 | if [ $NPP_VERBOSE -eq 1 ]
72 | then
73 | echo "NPP_OS=${NPP_OS}"
74 | fi
75 |
76 |
77 | # ----------------------------------------------------------------------------
78 | # Determine Node++ modules that are enabled in npp_app.h
79 |
80 | NPP_HTTPS=$(get_presence "NPP_HTTPS")
81 |
82 | NPP_MYSQL=$(get_presence "NPP_MYSQL")
83 |
84 | NPP_USERS=$(get_presence "NPP_USERS")
85 |
86 | NPP_ASYNC=$(get_presence "NPP_ASYNC")
87 |
88 |
89 | # ----------------------------------------------------------------------------
90 | # APP & SVC modules to compile
91 |
92 | NPP_M_MODULES_APP="npp_app.cpp ../lib/npp_eng_app.c ../lib/npp_lib.c"
93 | NPP_M_MODULES_SVC="npp_svc.cpp ../lib/npp_eng_svc.c ../lib/npp_lib.c"
94 |
95 | NPP_APP_MODULES=$(get_quoted_value "NPP_APP_MODULES")
96 |
97 | if [ ! -z "$NPP_APP_MODULES" ]
98 | then
99 | NPP_M_MODULES_APP="${NPP_M_MODULES_APP} ${NPP_APP_MODULES}"
100 | fi
101 |
102 | NPP_SVC_MODULES_SAME=$(get_value "NPP_SVC_MODULES")
103 |
104 | if [ "$NPP_SVC_MODULES_SAME" = "NPP_APP_MODULES" ]
105 | then
106 | NPP_SVC_MODULES=$NPP_APP_MODULES
107 | else
108 | NPP_SVC_MODULES=$(get_quoted_value "NPP_SVC_MODULES")
109 | fi
110 |
111 | if [ ! -z "$NPP_SVC_MODULES" ]
112 | then
113 | NPP_M_MODULES_SVC="${NPP_M_MODULES_SVC} ${NPP_SVC_MODULES}"
114 | fi
115 |
116 | if [ $NPP_MYSQL -eq 1 ]
117 | then
118 | NPP_M_MODULES_APP="${NPP_M_MODULES_APP} ../lib/npp_mysql.cpp"
119 | NPP_M_MODULES_SVC="${NPP_M_MODULES_SVC} ../lib/npp_mysql.cpp"
120 | fi
121 |
122 | if [ $NPP_USERS -eq 1 ]
123 | then
124 | NPP_M_MODULES_APP="${NPP_M_MODULES_APP} ../lib/npp_usr.cpp ../lib/Cusers.cpp ../lib/Cusers_avatars.cpp ../lib/Cusers_groups.cpp ../lib/Cusers_settings.cpp ../lib/Cusers_logins.cpp ../lib/Cusers_activations.cpp ../lib/Cusers_p_resets.cpp ../lib/Cusers_messages.cpp"
125 | NPP_M_MODULES_SVC="${NPP_M_MODULES_SVC} ../lib/npp_usr.cpp ../lib/Cusers.cpp ../lib/Cusers_avatars.cpp ../lib/Cusers_groups.cpp ../lib/Cusers_settings.cpp ../lib/Cusers_logins.cpp ../lib/Cusers_activations.cpp ../lib/Cusers_p_resets.cpp ../lib/Cusers_messages.cpp"
126 | fi
127 |
128 | if [ $NPP_VERBOSE -eq 1 ]
129 | then
130 | echo "NPP_M_MODULES_APP=${NPP_M_MODULES_APP}"
131 | echo "NPP_M_MODULES_SVC=${NPP_M_MODULES_SVC}"
132 | fi
133 |
134 |
135 | # ----------------------------------------------------------------------------
136 | # NPP_CPP_STRINGS
137 |
138 | NPP_CPP_STRINGS=$(get_presence "NPP_CPP_STRINGS")
139 |
140 | if [ $NPP_CPP_STRINGS -eq 1 ]
141 | then
142 | NPP_M_MODULES_APP="${NPP_M_MODULES_APP} -std=c++17"
143 | NPP_M_MODULES_SVC="${NPP_M_MODULES_SVC} -std=c++17"
144 | fi
145 |
146 |
147 | # ----------------------------------------------------------------------------
148 | # Include paths
149 |
150 | NPP_INCLUDE="-I. -I../lib"
151 |
152 | if [ $NPP_VERBOSE -eq 1 ]
153 | then
154 | echo "NPP_INCLUDE=${NPP_INCLUDE}"
155 | fi
156 |
157 |
158 | # ----------------------------------------------------------------------------
159 | # System and third-party libraries
160 |
161 | NPP_LIBS_APP=""
162 | NPP_LIBS_SVC=""
163 |
164 | if [ $NPP_ASYNC -eq 1 ]
165 | then
166 | if [ "$NPP_OS" = "debian" ] || [ -z "${NPP_OS##*rhel*}" ] || [ -z "${NPP_OS##*fedora*}" ]
167 | then
168 | NPP_LIBS_APP="-lrt"
169 | NPP_LIBS_SVC="-lrt"
170 | fi
171 | fi
172 |
173 | NPP_LIBS_UPDATE=""
174 |
175 | if [ $NPP_HTTPS -eq 1 ]
176 | then
177 | NPP_LIBS_APP="${NPP_LIBS_APP} -lssl -lcrypto"
178 | NPP_LIBS_SVC="${NPP_LIBS_SVC} -lssl -lcrypto"
179 | NPP_LIBS_UPDATE="${NPP_LIBS_UPDATE} -lssl -lcrypto"
180 | fi
181 |
182 | if [ $NPP_MYSQL -eq 1 ]
183 | then
184 | NPP_LIBS_APP="${NPP_LIBS_APP} -lmysqlclient"
185 | NPP_LIBS_SVC="${NPP_LIBS_SVC} -lmysqlclient"
186 | fi
187 |
188 | NPP_LIBS_APP="${NPP_LIBS_APP} -lz"
189 |
190 | if [ $NPP_VERBOSE -eq 1 ]
191 | then
192 | echo "NPP_LIBS_APP=${NPP_LIBS_APP}"
193 | echo "NPP_LIBS_SVC=${NPP_LIBS_SVC}"
194 | echo "NPP_LIBS_UPDATE=${NPP_LIBS_UPDATE}"
195 | fi
196 |
197 |
198 | # ----------------------------------------------------------------------------
199 | # Compile
200 |
201 | NPP_APP_NAME=$(get_quoted_value "NPP_APP_NAME")
202 |
203 | if [ ! -z "$NPP_APP_NAME" ]
204 | then
205 | echo Building ${NPP_APP_NAME}...
206 | else
207 | echo Building application...
208 | fi
209 |
210 | echo Making npp_app...
211 |
212 | g++ $NPP_M_MODULES_APP \
213 | -D NPP_APP \
214 | $NPP_INCLUDE \
215 | $NPP_LIBS_APP \
216 | -O3 \
217 | -o ../bin/npp_app
218 |
219 |
220 | if [ $? -ne 0 ] # error
221 | then
222 | exit 1
223 | fi
224 |
225 |
226 | if [ $NPP_ASYNC -eq 1 ]
227 | then
228 | echo Making npp_svc...
229 |
230 | g++ $NPP_M_MODULES_SVC \
231 | -D NPP_SVC \
232 | $NPP_INCLUDE \
233 | $NPP_LIBS_SVC \
234 | -O3 \
235 | -o ../bin/npp_svc
236 | fi
237 |
238 |
239 | if [ "$1" = "all" ]
240 | then
241 | echo Making npp_watcher...
242 |
243 | gcc ../lib/npp_watcher.c \
244 | ../lib/npp_lib.c \
245 | -D NPP_WATCHER \
246 | $NPP_INCLUDE \
247 | -O3 \
248 | -o ../bin/npp_watcher
249 |
250 |
251 | echo Making npp_update...
252 |
253 | gcc ../lib/npp_update.c \
254 | ../lib/npp_lib.c \
255 | -D NPP_UPDATE \
256 | $NPP_INCLUDE \
257 | $NPP_LIBS_UPDATE \
258 | -O3 \
259 | -o ../bin/npp_update
260 | fi
261 |
--------------------------------------------------------------------------------
/lib/Cusers_groups.cpp:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:15:25, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #include "Cusers_groups.h"
9 |
10 |
11 | bool Cusers_groups::slots_[CDB_MAX_INSTANCES]={0};
12 |
13 |
14 | /* ---------------------------------------------------------------------------
15 | Constructor
16 | --------------------------------------------------------------------------- */
17 | Cusers_groups::Cusers_groups()
18 | {
19 | setInstance(slots_);
20 |
21 | table_ = "users_groups";
22 |
23 | columnList_ = "id,"
24 | "name,"
25 | "about,"
26 | "auth_level";
27 |
28 | if ( !(s_=mysql_stmt_init(dbConn_)) )
29 | ThrowSQL("mysql_stmt_init");
30 | if ( !(sc_=mysql_stmt_init(dbConn_)) )
31 | ThrowSQL("mysql_stmt_init");
32 | if ( !(sGet_=mysql_stmt_init(dbConn_)) )
33 | ThrowSQL("mysql_stmt_init");
34 | if ( !(sUpdate_=mysql_stmt_init(dbConn_)) )
35 | ThrowSQL("mysql_stmt_init");
36 | if ( !(sInsert_=mysql_stmt_init(dbConn_)) )
37 | ThrowSQL("mysql_stmt_init");
38 | if ( !(sDelete_=mysql_stmt_init(dbConn_)) )
39 | ThrowSQL("mysql_stmt_init");
40 | if ( !(sSet_=mysql_stmt_init(dbConn_)) )
41 | ThrowSQL("mysql_stmt_init");
42 |
43 | Reset();
44 | }
45 |
46 |
47 | /* ---------------------------------------------------------------------------
48 | Destructor
49 | --------------------------------------------------------------------------- */
50 | Cusers_groups::~Cusers_groups()
51 | {
52 | mysql_stmt_close(s_);
53 | mysql_stmt_close(sGet_);
54 | mysql_stmt_close(sUpdate_);
55 | mysql_stmt_close(sInsert_);
56 | mysql_stmt_close(sDelete_);
57 | mysql_stmt_close(sSet_);
58 |
59 | slots_[instance_] = false;
60 | }
61 |
62 |
63 | /* ---------------------------------------------------------------------------
64 | Get the next record
65 | Return false if end of record set
66 | --------------------------------------------------------------------------- */
67 | bool Cusers_groups::Fetch()
68 | {
69 | int ret;
70 |
71 | ret = mysql_stmt_fetch(s_);
72 |
73 | if ( ret != 0 )
74 | {
75 | Reset();
76 |
77 | if ( ret == 1 || ret == MYSQL_NO_DATA )
78 | return false;
79 | else
80 | {
81 | Cdb::ThrowSQL("Cusers_groups::Fetch | mysql_stmt_fetch");
82 | return false;
83 | }
84 | }
85 |
86 | return true;
87 | }
88 |
89 |
90 | /* ---------------------------------------------------------------------------
91 | Get record by PK
92 | Not Found will return false
93 | --------------------------------------------------------------------------- */
94 | bool Cusers_groups::Get(int arg_id)
95 | {
96 | int ret;
97 |
98 | if ( firstGet_ )
99 | {
100 | char q[CDB_SQLBUF];
101 | sprintf(q, "SELECT id,name,about,auth_level FROM users_groups WHERE id=?");
102 | ret = mysql_stmt_prepare(sGet_, q, strlen(q));
103 | if ( ret != 0 )
104 | Cdb::ThrowSQL("Cusers_groups::Get | mysql_stmt_prepare");
105 | firstGet_ = false;
106 | }
107 |
108 | bindKey(sGet_, arg_id);
109 |
110 | if ( mysql_stmt_execute(sGet_) )
111 | Cdb::ThrowSQL("Cusers_groups::Get | mysql_stmt_execute");
112 |
113 | bindOutput(sGet_);
114 |
115 | if ( mysql_stmt_store_result(sGet_) )
116 | Cdb::ThrowSQL("Cusers_groups::Get | mysql_stmt_store_result");
117 |
118 | ret = mysql_stmt_fetch(sGet_);
119 |
120 | if ( ret != 0 )
121 | {
122 | if ( ret == 1 || ret == MYSQL_NO_DATA )
123 | return false;
124 | else
125 | Cdb::ThrowSQL("Cusers_groups::Get | mysql_stmt_fetch");
126 | }
127 |
128 | return true;
129 | }
130 |
131 |
132 | /* ---------------------------------------------------------------------------
133 | Insert record
134 | --------------------------------------------------------------------------- */
135 | unsigned Cusers_groups::Insert()
136 | {
137 | int ret;
138 |
139 | if ( firstInsert_ )
140 | {
141 | char q[CDB_SQLBUF];
142 | sprintf(q, "INSERT INTO users_groups (name,about,auth_level) VALUES (?,?,?)");
143 | ret = mysql_stmt_prepare(sInsert_, q, strlen(q));
144 | if ( ret != 0 )
145 | Cdb::ThrowSQL("Cusers_groups::Insert | mysql_stmt_prepare");
146 | firstInsert_ = false;
147 | }
148 |
149 | bindInput(sInsert_);
150 |
151 | ret = mysql_stmt_execute(sInsert_);
152 |
153 | if ( ret != 0 )
154 | Cdb::ThrowSQL("Cusers_groups::Insert | mysql_stmt_execute");
155 |
156 | id = mysql_insert_id(dbConn_);
157 |
158 | return id;
159 | }
160 |
161 |
162 | /* ---------------------------------------------------------------------------
163 | Update record by PK
164 | --------------------------------------------------------------------------- */
165 | void Cusers_groups::Update(int arg_id)
166 | {
167 | int ret;
168 |
169 | if ( firstUpdate_ )
170 | {
171 | char q[CDB_SQLBUF];
172 | sprintf(q, "UPDATE users_groups SET name=?,about=?,auth_level=? WHERE id=?");
173 | ret = mysql_stmt_prepare(sUpdate_, q, strlen(q));
174 | if ( ret != 0 )
175 | Cdb::ThrowSQL("Cusers_groups::Update | mysql_stmt_prepare");
176 | firstUpdate_ = false;
177 | }
178 |
179 | bindInput(sUpdate_, true, arg_id);
180 |
181 | ret = mysql_stmt_execute(sUpdate_);
182 |
183 | if ( ret != 0 )
184 | Cdb::ThrowSQL("Cusers_groups::Update | mysql_stmt_execute");
185 | }
186 |
187 |
188 | /* ---------------------------------------------------------------------------
189 | Delete record by PK
190 | --------------------------------------------------------------------------- */
191 | void Cusers_groups::Delete(int arg_id)
192 | {
193 | int ret;
194 |
195 | if ( firstDelete_ )
196 | {
197 | char q[CDB_SQLBUF];
198 | sprintf(q, "DELETE FROM users_groups WHERE id=?");
199 | ret = mysql_stmt_prepare(sDelete_, q, strlen(q));
200 | if ( ret != 0 )
201 | Cdb::ThrowSQL("Cusers_groups::Delete | mysql_stmt_prepare");
202 | firstDelete_ = false;
203 | }
204 |
205 | bindKey(sDelete_, arg_id);
206 |
207 | ret = mysql_stmt_execute(sDelete_);
208 |
209 | if ( ret != 0 )
210 | Cdb::ThrowSQL("Cusers_groups::Delete | mysql_stmt_execute");
211 | }
212 |
213 |
214 | /* ---------------------------------------------------------------------------
215 | Insert or update record by PK
216 | --------------------------------------------------------------------------- */
217 | void Cusers_groups::Set(int arg_id)
218 | {
219 | int ret;
220 |
221 | if ( firstSet_ )
222 | {
223 | char q[CDB_SQLBUF];
224 | sprintf(q, "SELECT id FROM users_groups WHERE id=?");
225 | ret = mysql_stmt_prepare(sSet_, q, strlen(q));
226 | if ( ret != 0 )
227 | Cdb::ThrowSQL("Cusers_groups::Set | mysql_stmt_prepare");
228 | firstSet_ = false;
229 | }
230 |
231 | bindKey(sSet_, arg_id);
232 |
233 | if ( mysql_stmt_execute(sSet_) )
234 | Cdb::ThrowSQL("Cusers_groups::Set | mysql_stmt_execute");
235 |
236 | bindSetOutput();
237 |
238 | if ( mysql_stmt_store_result(sSet_) )
239 | Cdb::ThrowSQL("Cusers_groups::Set | mysql_stmt_store_result");
240 |
241 | ret = mysql_stmt_fetch(sSet_);
242 |
243 | if ( ret == 0 ) /* record existed */
244 | {
245 | Update(arg_id);
246 | }
247 | else if ( ret == 1 || ret == MYSQL_NO_DATA ) /* not found ==> insert new */
248 | {
249 | id = arg_id;
250 |
251 | Insert();
252 | }
253 | else
254 | Cdb::ThrowSQL("Cusers_groups::Set | mysql_stmt_fetch");
255 | }
256 |
257 |
258 | /* ---------------------------------------------------------------------------
259 | Bind key values
260 | --------------------------------------------------------------------------- */
261 | void Cusers_groups::bindKey(MYSQL_STMT *s, int arg_id)
262 | {
263 | k_id_ = arg_id;
264 |
265 | memset(&bndk_, 0, sizeof(bndk_));
266 |
267 | bndk_[0].buffer_type = MYSQL_TYPE_LONG;
268 | bndk_[0].buffer = (char*)&k_id_;
269 |
270 | if ( mysql_stmt_bind_param(s, bndk_) )
271 | Cdb::ThrowSQL("Cusers_groups::bindKey | mysql_stmt_bind_param");
272 | }
273 |
274 |
275 | /* ---------------------------------------------------------------------------
276 | Bind input values
277 | --------------------------------------------------------------------------- */
278 | void Cusers_groups::bindInput(MYSQL_STMT *s, bool withKey, int arg_id)
279 | {
280 | name_len_ = strlen(name);
281 | about_len_ = strlen(about);
282 |
283 | memset(&bndi_, 0, sizeof(bndi_));
284 |
285 | bndi_[0].buffer_type = MYSQL_TYPE_STRING;
286 | bndi_[0].buffer = (char*)name;
287 | bndi_[0].length = &name_len_;
288 |
289 | bndi_[1].buffer_type = MYSQL_TYPE_STRING;
290 | bndi_[1].buffer = (char*)about;
291 | bndi_[1].length = &about_len_;
292 |
293 | bndi_[2].buffer_type = MYSQL_TYPE_TINY;
294 | bndi_[2].buffer = (char*)&auth_level;
295 |
296 | if ( withKey ) /* after WHERE */
297 | {
298 | k_id_ = arg_id;
299 |
300 | bndi_[3].buffer_type = MYSQL_TYPE_LONG;
301 | bndi_[3].buffer = (char*)&k_id_;
302 |
303 | }
304 |
305 | if ( mysql_stmt_bind_param(s, bndi_) )
306 | Cdb::ThrowSQL("Cusers_groups::bindInput | mysql_stmt_bind_param");
307 | }
308 |
309 |
310 | /* ---------------------------------------------------------------------------
311 | Bind output values
312 | --------------------------------------------------------------------------- */
313 | void Cusers_groups::bindOutput(MYSQL_STMT *s)
314 | {
315 | memset(&bndo_, 0, sizeof(bndo_));
316 |
317 | bndo_[0].buffer_type = MYSQL_TYPE_LONG;
318 | bndo_[0].buffer = (char*)&id;
319 | bndo_[0].is_null = &id_is_null_;
320 |
321 | bndo_[1].buffer_type = MYSQL_TYPE_STRING;
322 | bndo_[1].buffer = (char*)name;
323 | bndo_[1].buffer_length = 121;
324 | bndo_[1].is_null = &name_is_null_;
325 |
326 | bndo_[2].buffer_type = MYSQL_TYPE_STRING;
327 | bndo_[2].buffer = (char*)about;
328 | bndo_[2].buffer_length = 251;
329 | bndo_[2].is_null = &about_is_null_;
330 |
331 | bndo_[3].buffer_type = MYSQL_TYPE_TINY;
332 | bndo_[3].buffer = (char*)&auth_level;
333 | bndo_[3].is_null = &auth_level_is_null_;
334 |
335 | if ( mysql_stmt_bind_result(s, bndo_) )
336 | Cdb::ThrowSQL("Cusers_groups::bindOutput | mysql_stmt_bind_result");
337 | }
338 |
339 |
340 | /* ---------------------------------------------------------------------------
341 | Bind output value for Set
342 | --------------------------------------------------------------------------- */
343 | void Cusers_groups::bindSetOutput()
344 | {
345 | static int id; /* to be scrapped anyway */
346 |
347 | memset(&bndso_, 0, sizeof(bndso_));
348 |
349 | bndso_[0].buffer_type = MYSQL_TYPE_LONG;
350 | bndso_[0].buffer = (char*)&id;
351 |
352 | if ( mysql_stmt_bind_result(sSet_, bndso_) )
353 | Cdb::ThrowSQL("Cusers_groups::bindSetOutput | mysql_stmt_bind_result");
354 | }
355 |
356 |
357 | /* ---------------------------------------------------------------------------
358 | Reset (zero) public variables
359 | --------------------------------------------------------------------------- */
360 | void Cusers_groups::Reset()
361 | {
362 | id = 0;
363 | name[0] = EOS;
364 | about[0] = EOS;
365 | auth_level = 0;
366 | }
367 |
--------------------------------------------------------------------------------
/lib/Cusers_avatars.cpp:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-29 20:06:23, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #include "Cusers_avatars.h"
9 |
10 |
11 | bool Cusers_avatars::slots_[CDB_MAX_INSTANCES]={0};
12 |
13 |
14 | /* ---------------------------------------------------------------------------
15 | Constructor
16 | --------------------------------------------------------------------------- */
17 | Cusers_avatars::Cusers_avatars()
18 | {
19 | setInstance(slots_);
20 |
21 | table_ = "users_avatars";
22 |
23 | columnList_ = "user_id,"
24 | "avatar_name,"
25 | "avatar_data,"
26 | "avatar_len";
27 |
28 | if ( !(s_=mysql_stmt_init(dbConn_)) )
29 | ThrowSQL("mysql_stmt_init");
30 | if ( !(sc_=mysql_stmt_init(dbConn_)) )
31 | ThrowSQL("mysql_stmt_init");
32 | if ( !(sGet_=mysql_stmt_init(dbConn_)) )
33 | ThrowSQL("mysql_stmt_init");
34 | if ( !(sUpdate_=mysql_stmt_init(dbConn_)) )
35 | ThrowSQL("mysql_stmt_init");
36 | if ( !(sInsert_=mysql_stmt_init(dbConn_)) )
37 | ThrowSQL("mysql_stmt_init");
38 | if ( !(sDelete_=mysql_stmt_init(dbConn_)) )
39 | ThrowSQL("mysql_stmt_init");
40 | if ( !(sSet_=mysql_stmt_init(dbConn_)) )
41 | ThrowSQL("mysql_stmt_init");
42 |
43 | avatar_data_len = 0;
44 |
45 | Reset();
46 | }
47 |
48 |
49 | /* ---------------------------------------------------------------------------
50 | Destructor
51 | --------------------------------------------------------------------------- */
52 | Cusers_avatars::~Cusers_avatars()
53 | {
54 | mysql_stmt_close(s_);
55 | mysql_stmt_close(sGet_);
56 | mysql_stmt_close(sUpdate_);
57 | mysql_stmt_close(sInsert_);
58 | mysql_stmt_close(sDelete_);
59 | mysql_stmt_close(sSet_);
60 |
61 | slots_[instance_] = false;
62 | }
63 |
64 |
65 | /* ---------------------------------------------------------------------------
66 | Get the next record
67 | Return false if end of record set
68 | --------------------------------------------------------------------------- */
69 | bool Cusers_avatars::Fetch()
70 | {
71 | int ret;
72 |
73 | ret = mysql_stmt_fetch(s_);
74 |
75 | if ( ret != 0 )
76 | {
77 | Reset();
78 |
79 | if ( ret == 1 || ret == MYSQL_NO_DATA )
80 | return false;
81 | else
82 | {
83 | Cdb::ThrowSQL("Cusers_avatars::Fetch | mysql_stmt_fetch");
84 | return false;
85 | }
86 | }
87 |
88 | genDTStrings();
89 |
90 | return true;
91 | }
92 |
93 |
94 | /* ---------------------------------------------------------------------------
95 | Get record by PK
96 | Not Found will return false
97 | --------------------------------------------------------------------------- */
98 | bool Cusers_avatars::Get(int arg_user_id)
99 | {
100 | int ret;
101 |
102 | if ( firstGet_ )
103 | {
104 | char q[CDB_SQLBUF];
105 | sprintf(q, "SELECT user_id,avatar_name,avatar_data,avatar_len FROM users_avatars WHERE user_id=?");
106 | ret = mysql_stmt_prepare(sGet_, q, strlen(q));
107 | if ( ret != 0 )
108 | Cdb::ThrowSQL("Cusers_avatars::Get | mysql_stmt_prepare");
109 | firstGet_ = false;
110 | }
111 |
112 | bindKey(sGet_, arg_user_id);
113 |
114 | if ( mysql_stmt_execute(sGet_) )
115 | Cdb::ThrowSQL("Cusers_avatars::Get | mysql_stmt_execute");
116 |
117 | bindOutput(sGet_);
118 |
119 | if ( mysql_stmt_store_result(sGet_) )
120 | Cdb::ThrowSQL("Cusers_avatars::Get | mysql_stmt_store_result");
121 |
122 | ret = mysql_stmt_fetch(sGet_);
123 |
124 | if ( ret != 0 )
125 | {
126 | if ( ret == 1 || ret == MYSQL_NO_DATA )
127 | return false;
128 | else
129 | Cdb::ThrowSQL("Cusers_avatars::Get | mysql_stmt_fetch");
130 | }
131 |
132 | genDTStrings();
133 |
134 | return true;
135 | }
136 |
137 |
138 | /* ---------------------------------------------------------------------------
139 | Insert record
140 | --------------------------------------------------------------------------- */
141 | unsigned Cusers_avatars::Insert()
142 | {
143 | int ret;
144 |
145 | if ( firstInsert_ )
146 | {
147 | char q[CDB_SQLBUF];
148 | sprintf(q, "INSERT INTO users_avatars (user_id,avatar_name,avatar_data,avatar_len) VALUES (?,?,?,?)");
149 | ret = mysql_stmt_prepare(sInsert_, q, strlen(q));
150 | if ( ret != 0 )
151 | Cdb::ThrowSQL("Cusers_avatars::Insert | mysql_stmt_prepare");
152 | firstInsert_ = false;
153 | }
154 |
155 | bindInput(sInsert_);
156 |
157 | ret = mysql_stmt_execute(sInsert_);
158 |
159 | if ( ret != 0 )
160 | Cdb::ThrowSQL("Cusers_avatars::Insert | mysql_stmt_execute");
161 |
162 | return mysql_insert_id(dbConn_);
163 | }
164 |
165 |
166 | /* ---------------------------------------------------------------------------
167 | Update record by PK
168 | --------------------------------------------------------------------------- */
169 | void Cusers_avatars::Update(int arg_user_id)
170 | {
171 | int ret;
172 |
173 | if ( firstUpdate_ )
174 | {
175 | char q[CDB_SQLBUF];
176 | sprintf(q, "UPDATE users_avatars SET user_id=?,avatar_name=?,avatar_data=?,avatar_len=? WHERE user_id=?");
177 | ret = mysql_stmt_prepare(sUpdate_, q, strlen(q));
178 | if ( ret != 0 )
179 | Cdb::ThrowSQL("Cusers_avatars::Update | mysql_stmt_prepare");
180 | firstUpdate_ = false;
181 | }
182 |
183 | bindInput(sUpdate_, true, arg_user_id);
184 |
185 | ret = mysql_stmt_execute(sUpdate_);
186 |
187 | if ( ret != 0 )
188 | Cdb::ThrowSQL("Cusers_avatars::Update | mysql_stmt_execute");
189 | }
190 |
191 |
192 | /* ---------------------------------------------------------------------------
193 | Delete record by PK
194 | --------------------------------------------------------------------------- */
195 | void Cusers_avatars::Delete(int arg_user_id)
196 | {
197 | int ret;
198 |
199 | if ( firstDelete_ )
200 | {
201 | char q[CDB_SQLBUF];
202 | sprintf(q, "DELETE FROM users_avatars WHERE user_id=?");
203 | ret = mysql_stmt_prepare(sDelete_, q, strlen(q));
204 | if ( ret != 0 )
205 | Cdb::ThrowSQL("Cusers_avatars::Delete | mysql_stmt_prepare");
206 | firstDelete_ = false;
207 | }
208 |
209 | bindKey(sDelete_, arg_user_id);
210 |
211 | ret = mysql_stmt_execute(sDelete_);
212 |
213 | if ( ret != 0 )
214 | Cdb::ThrowSQL("Cusers_avatars::Delete | mysql_stmt_execute");
215 | }
216 |
217 |
218 | /* ---------------------------------------------------------------------------
219 | Insert or update record by PK
220 | --------------------------------------------------------------------------- */
221 | void Cusers_avatars::Set(int arg_user_id)
222 | {
223 | int ret;
224 |
225 | if ( firstSet_ )
226 | {
227 | char q[CDB_SQLBUF];
228 | sprintf(q, "SELECT user_id FROM users_avatars WHERE user_id=?");
229 | ret = mysql_stmt_prepare(sSet_, q, strlen(q));
230 | if ( ret != 0 )
231 | Cdb::ThrowSQL("Cusers_avatars::Set | mysql_stmt_prepare");
232 | firstSet_ = false;
233 | }
234 |
235 | bindKey(sSet_, arg_user_id);
236 |
237 | if ( mysql_stmt_execute(sSet_) )
238 | Cdb::ThrowSQL("Cusers_avatars::Set | mysql_stmt_execute");
239 |
240 | bindSetOutput();
241 |
242 | if ( mysql_stmt_store_result(sSet_) )
243 | Cdb::ThrowSQL("Cusers_avatars::Set | mysql_stmt_store_result");
244 |
245 | ret = mysql_stmt_fetch(sSet_);
246 |
247 | if ( ret == 0 ) /* record existed */
248 | {
249 | Update(arg_user_id);
250 | }
251 | else if ( ret == 1 || ret == MYSQL_NO_DATA ) /* not found ==> insert new */
252 | {
253 | user_id = arg_user_id;
254 |
255 | Insert();
256 | }
257 | else
258 | Cdb::ThrowSQL("Cusers_avatars::Set | mysql_stmt_fetch");
259 | }
260 |
261 |
262 | /* ---------------------------------------------------------------------------
263 | Bind key values
264 | --------------------------------------------------------------------------- */
265 | void Cusers_avatars::bindKey(MYSQL_STMT *s, int arg_user_id)
266 | {
267 | k_user_id_ = arg_user_id;
268 |
269 | memset(&bndk_, 0, sizeof(bndk_));
270 |
271 | bndk_[0].buffer_type = MYSQL_TYPE_LONG;
272 | bndk_[0].buffer = (char*)&k_user_id_;
273 |
274 | if ( mysql_stmt_bind_param(s, bndk_) )
275 | Cdb::ThrowSQL("Cusers_avatars::bindKey | mysql_stmt_bind_param");
276 | }
277 |
278 |
279 | /* ---------------------------------------------------------------------------
280 | Bind input values
281 | --------------------------------------------------------------------------- */
282 | void Cusers_avatars::bindInput(MYSQL_STMT *s, bool withKey, int arg_user_id)
283 | {
284 | avatar_name_len_ = strlen(avatar_name);
285 |
286 |
287 | memset(&bndi_, 0, sizeof(bndi_));
288 |
289 | bndi_[0].buffer_type = MYSQL_TYPE_LONG;
290 | bndi_[0].buffer = (char*)&user_id;
291 |
292 | bndi_[1].buffer_type = MYSQL_TYPE_STRING;
293 | bndi_[1].buffer = (char*)avatar_name;
294 | bndi_[1].length = &avatar_name_len_;
295 |
296 | bndi_[2].buffer_type = MYSQL_TYPE_BLOB;
297 | bndi_[2].buffer = (char*)avatar_data;
298 | bndi_[2].length = &avatar_data_len;
299 |
300 | bndi_[3].buffer_type = MYSQL_TYPE_LONG;
301 | bndi_[3].buffer = (char*)&avatar_len;
302 |
303 | if ( withKey ) /* after WHERE */
304 | {
305 | k_user_id_ = arg_user_id;
306 |
307 | bndi_[4].buffer_type = MYSQL_TYPE_LONG;
308 | bndi_[4].buffer = (char*)&k_user_id_;
309 |
310 | }
311 |
312 | if ( mysql_stmt_bind_param(s, bndi_) )
313 | Cdb::ThrowSQL("Cusers_avatars::bindInput | mysql_stmt_bind_param");
314 | }
315 |
316 |
317 | /* ---------------------------------------------------------------------------
318 | Bind output values
319 | --------------------------------------------------------------------------- */
320 | void Cusers_avatars::bindOutput(MYSQL_STMT *s)
321 | {
322 | memset(&bndo_, 0, sizeof(bndo_));
323 |
324 | bndo_[0].buffer_type = MYSQL_TYPE_LONG;
325 | bndo_[0].buffer = (char*)&user_id;
326 | bndo_[0].is_null = &user_id_is_null_;
327 |
328 | bndo_[1].buffer_type = MYSQL_TYPE_STRING;
329 | bndo_[1].buffer = (char*)avatar_name;
330 | bndo_[1].buffer_length = 121;
331 | bndo_[1].is_null = &avatar_name_is_null_;
332 |
333 | bndo_[2].buffer_type = MYSQL_TYPE_BLOB;
334 | bndo_[2].buffer = (char*)avatar_data;
335 | bndo_[2].buffer_length = 65536;
336 | bndo_[2].length = &avatar_data_len;
337 | bndo_[2].is_null = &avatar_data_is_null_;
338 |
339 | bndo_[3].buffer_type = MYSQL_TYPE_LONG;
340 | bndo_[3].buffer = (char*)&avatar_len;
341 | bndo_[3].is_null = &avatar_len_is_null_;
342 |
343 | if ( mysql_stmt_bind_result(s, bndo_) )
344 | Cdb::ThrowSQL("Cusers_avatars::bindOutput | mysql_stmt_bind_result");
345 | }
346 |
347 |
348 | /* ---------------------------------------------------------------------------
349 | Bind output value for Set
350 | --------------------------------------------------------------------------- */
351 | void Cusers_avatars::bindSetOutput()
352 | {
353 | static int user_id; /* to be scrapped anyway */
354 |
355 | memset(&bndso_, 0, sizeof(bndso_));
356 |
357 | bndso_[0].buffer_type = MYSQL_TYPE_LONG;
358 | bndso_[0].buffer = (char*)&user_id;
359 |
360 | if ( mysql_stmt_bind_result(sSet_, bndso_) )
361 | Cdb::ThrowSQL("Cusers_avatars::bindSetOutput | mysql_stmt_bind_result");
362 | }
363 |
364 |
365 | /* ---------------------------------------------------------------------------
366 | Generate date-time strings
367 | --------------------------------------------------------------------------- */
368 | void Cusers_avatars::genDTStrings()
369 | {
370 | }
371 |
372 |
373 | /* ---------------------------------------------------------------------------
374 | Reset (zero) public variables
375 | --------------------------------------------------------------------------- */
376 | void Cusers_avatars::Reset()
377 | {
378 | user_id = 0;
379 | avatar_name[0] = EOS;
380 | avatar_data[0] = EOS;
381 | avatar_len = 0;
382 | }
383 |
--------------------------------------------------------------------------------
/lib/Cusers_settings.cpp:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:16:04, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #include "Cusers_settings.h"
9 |
10 |
11 | bool Cusers_settings::slots_[CDB_MAX_INSTANCES]={0};
12 |
13 |
14 | /* ---------------------------------------------------------------------------
15 | Constructor
16 | --------------------------------------------------------------------------- */
17 | Cusers_settings::Cusers_settings()
18 | {
19 | setInstance(slots_);
20 |
21 | table_ = "users_settings";
22 |
23 | columnList_ = "user_id,"
24 | "us_key,"
25 | "us_val";
26 |
27 | if ( !(s_=mysql_stmt_init(dbConn_)) )
28 | ThrowSQL("mysql_stmt_init");
29 | if ( !(sc_=mysql_stmt_init(dbConn_)) )
30 | ThrowSQL("mysql_stmt_init");
31 | if ( !(sGet_=mysql_stmt_init(dbConn_)) )
32 | ThrowSQL("mysql_stmt_init");
33 | if ( !(sUpdate_=mysql_stmt_init(dbConn_)) )
34 | ThrowSQL("mysql_stmt_init");
35 | if ( !(sInsert_=mysql_stmt_init(dbConn_)) )
36 | ThrowSQL("mysql_stmt_init");
37 | if ( !(sDelete_=mysql_stmt_init(dbConn_)) )
38 | ThrowSQL("mysql_stmt_init");
39 | if ( !(sSet_=mysql_stmt_init(dbConn_)) )
40 | ThrowSQL("mysql_stmt_init");
41 |
42 | Reset();
43 | }
44 |
45 |
46 | /* ---------------------------------------------------------------------------
47 | Destructor
48 | --------------------------------------------------------------------------- */
49 | Cusers_settings::~Cusers_settings()
50 | {
51 | mysql_stmt_close(s_);
52 | mysql_stmt_close(sGet_);
53 | mysql_stmt_close(sUpdate_);
54 | mysql_stmt_close(sInsert_);
55 | mysql_stmt_close(sDelete_);
56 | mysql_stmt_close(sSet_);
57 |
58 | slots_[instance_] = false;
59 | }
60 |
61 |
62 | /* ---------------------------------------------------------------------------
63 | Get the next record
64 | Return false if end of record set
65 | --------------------------------------------------------------------------- */
66 | bool Cusers_settings::Fetch()
67 | {
68 | int ret;
69 |
70 | ret = mysql_stmt_fetch(s_);
71 |
72 | if ( ret != 0 )
73 | {
74 | Reset();
75 |
76 | if ( ret == 1 || ret == MYSQL_NO_DATA )
77 | return false;
78 | else
79 | {
80 | Cdb::ThrowSQL("Cusers_settings::Fetch | mysql_stmt_fetch");
81 | return false;
82 | }
83 | }
84 |
85 | return true;
86 | }
87 |
88 |
89 | /* ---------------------------------------------------------------------------
90 | Get record by PK
91 | Not Found will return false
92 | --------------------------------------------------------------------------- */
93 | bool Cusers_settings::Get(int arg_user_id, const std::string& arg_us_key)
94 | {
95 | int ret;
96 |
97 | if ( firstGet_ )
98 | {
99 | char q[CDB_SQLBUF];
100 | sprintf(q, "SELECT user_id,us_key,us_val FROM users_settings WHERE user_id=? AND us_key=?");
101 | ret = mysql_stmt_prepare(sGet_, q, strlen(q));
102 | if ( ret != 0 )
103 | Cdb::ThrowSQL("Cusers_settings::Get | mysql_stmt_prepare");
104 | firstGet_ = false;
105 | }
106 |
107 | bindKey(sGet_, arg_user_id, arg_us_key);
108 |
109 | if ( mysql_stmt_execute(sGet_) )
110 | Cdb::ThrowSQL("Cusers_settings::Get | mysql_stmt_execute");
111 |
112 | bindOutput(sGet_);
113 |
114 | if ( mysql_stmt_store_result(sGet_) )
115 | Cdb::ThrowSQL("Cusers_settings::Get | mysql_stmt_store_result");
116 |
117 | ret = mysql_stmt_fetch(sGet_);
118 |
119 | if ( ret != 0 )
120 | {
121 | if ( ret == 1 || ret == MYSQL_NO_DATA )
122 | return false;
123 | else
124 | Cdb::ThrowSQL("Cusers_settings::Get | mysql_stmt_fetch");
125 | }
126 |
127 | return true;
128 | }
129 |
130 |
131 | /* ---------------------------------------------------------------------------
132 | Insert record
133 | --------------------------------------------------------------------------- */
134 | unsigned Cusers_settings::Insert()
135 | {
136 | int ret;
137 |
138 | if ( firstInsert_ )
139 | {
140 | char q[CDB_SQLBUF];
141 | sprintf(q, "INSERT INTO users_settings (user_id,us_key,us_val) VALUES (?,?,?)");
142 | ret = mysql_stmt_prepare(sInsert_, q, strlen(q));
143 | if ( ret != 0 )
144 | Cdb::ThrowSQL("Cusers_settings::Insert | mysql_stmt_prepare");
145 | firstInsert_ = false;
146 | }
147 |
148 | bindInput(sInsert_);
149 |
150 | ret = mysql_stmt_execute(sInsert_);
151 |
152 | if ( ret != 0 )
153 | Cdb::ThrowSQL("Cusers_settings::Insert | mysql_stmt_execute");
154 |
155 | return mysql_insert_id(dbConn_);
156 | }
157 |
158 |
159 | /* ---------------------------------------------------------------------------
160 | Update record by PK
161 | --------------------------------------------------------------------------- */
162 | void Cusers_settings::Update(int arg_user_id, const std::string& arg_us_key)
163 | {
164 | int ret;
165 |
166 | if ( firstUpdate_ )
167 | {
168 | char q[CDB_SQLBUF];
169 | sprintf(q, "UPDATE users_settings SET user_id=?,us_key=?,us_val=? WHERE user_id=? AND us_key=?");
170 | ret = mysql_stmt_prepare(sUpdate_, q, strlen(q));
171 | if ( ret != 0 )
172 | Cdb::ThrowSQL("Cusers_settings::Update | mysql_stmt_prepare");
173 | firstUpdate_ = false;
174 | }
175 |
176 | bindInput(sUpdate_, true, arg_user_id, arg_us_key);
177 |
178 | ret = mysql_stmt_execute(sUpdate_);
179 |
180 | if ( ret != 0 )
181 | Cdb::ThrowSQL("Cusers_settings::Update | mysql_stmt_execute");
182 | }
183 |
184 |
185 | /* ---------------------------------------------------------------------------
186 | Delete record by PK
187 | --------------------------------------------------------------------------- */
188 | void Cusers_settings::Delete(int arg_user_id, const std::string& arg_us_key)
189 | {
190 | int ret;
191 |
192 | if ( firstDelete_ )
193 | {
194 | char q[CDB_SQLBUF];
195 | sprintf(q, "DELETE FROM users_settings WHERE user_id=? AND us_key=?");
196 | ret = mysql_stmt_prepare(sDelete_, q, strlen(q));
197 | if ( ret != 0 )
198 | Cdb::ThrowSQL("Cusers_settings::Delete | mysql_stmt_prepare");
199 | firstDelete_ = false;
200 | }
201 |
202 | bindKey(sDelete_, arg_user_id, arg_us_key);
203 |
204 | ret = mysql_stmt_execute(sDelete_);
205 |
206 | if ( ret != 0 )
207 | Cdb::ThrowSQL("Cusers_settings::Delete | mysql_stmt_execute");
208 | }
209 |
210 |
211 | /* ---------------------------------------------------------------------------
212 | Insert or update record by PK
213 | --------------------------------------------------------------------------- */
214 | void Cusers_settings::Set(int arg_user_id, const std::string& arg_us_key)
215 | {
216 | int ret;
217 |
218 | if ( firstSet_ )
219 | {
220 | char q[CDB_SQLBUF];
221 | sprintf(q, "SELECT user_id FROM users_settings WHERE user_id=? AND us_key=?");
222 | ret = mysql_stmt_prepare(sSet_, q, strlen(q));
223 | if ( ret != 0 )
224 | Cdb::ThrowSQL("Cusers_settings::Set | mysql_stmt_prepare");
225 | firstSet_ = false;
226 | }
227 |
228 | bindKey(sSet_, arg_user_id, arg_us_key);
229 |
230 | if ( mysql_stmt_execute(sSet_) )
231 | Cdb::ThrowSQL("Cusers_settings::Set | mysql_stmt_execute");
232 |
233 | bindSetOutput();
234 |
235 | if ( mysql_stmt_store_result(sSet_) )
236 | Cdb::ThrowSQL("Cusers_settings::Set | mysql_stmt_store_result");
237 |
238 | ret = mysql_stmt_fetch(sSet_);
239 |
240 | if ( ret == 0 ) /* record existed */
241 | {
242 | Update(arg_user_id, arg_us_key);
243 | }
244 | else if ( ret == 1 || ret == MYSQL_NO_DATA ) /* not found ==> insert new */
245 | {
246 | user_id = arg_user_id;
247 | strncpy(us_key, arg_us_key.c_str(), 30);
248 | us_key[30] = EOS;
249 |
250 | Insert();
251 | }
252 | else
253 | Cdb::ThrowSQL("Cusers_settings::Set | mysql_stmt_fetch");
254 | }
255 |
256 |
257 | /* ---------------------------------------------------------------------------
258 | Bind key values
259 | --------------------------------------------------------------------------- */
260 | void Cusers_settings::bindKey(MYSQL_STMT *s, int arg_user_id, const std::string& arg_us_key)
261 | {
262 | k_user_id_ = arg_user_id;
263 | strncpy(k_us_key_, arg_us_key.c_str(), 30);
264 | k_us_key_[30] = EOS;
265 |
266 | k_us_key_len_ = strlen(k_us_key_);
267 |
268 | memset(&bndk_, 0, sizeof(bndk_));
269 |
270 | bndk_[0].buffer_type = MYSQL_TYPE_LONG;
271 | bndk_[0].buffer = (char*)&k_user_id_;
272 |
273 | bndk_[1].buffer_type = MYSQL_TYPE_STRING;
274 | bndk_[1].buffer = (char*)k_us_key_;
275 | bndk_[1].length = &k_us_key_len_;
276 |
277 | if ( mysql_stmt_bind_param(s, bndk_) )
278 | Cdb::ThrowSQL("Cusers_settings::bindKey | mysql_stmt_bind_param");
279 | }
280 |
281 |
282 | /* ---------------------------------------------------------------------------
283 | Bind input values
284 | --------------------------------------------------------------------------- */
285 | void Cusers_settings::bindInput(MYSQL_STMT *s, bool withKey, int arg_user_id, const std::string& arg_us_key)
286 | {
287 | us_key_len_ = strlen(us_key);
288 | us_val_len_ = strlen(us_val);
289 |
290 | memset(&bndi_, 0, sizeof(bndi_));
291 |
292 | bndi_[0].buffer_type = MYSQL_TYPE_LONG;
293 | bndi_[0].buffer = (char*)&user_id;
294 |
295 | bndi_[1].buffer_type = MYSQL_TYPE_STRING;
296 | bndi_[1].buffer = (char*)us_key;
297 | bndi_[1].length = &us_key_len_;
298 |
299 | bndi_[2].buffer_type = MYSQL_TYPE_STRING;
300 | bndi_[2].buffer = (char*)us_val;
301 | bndi_[2].length = &us_val_len_;
302 |
303 | if ( withKey ) /* after WHERE */
304 | {
305 | k_user_id_ = arg_user_id;
306 | strncpy(k_us_key_, arg_us_key.c_str(), 30);
307 | k_us_key_[30] = EOS;
308 |
309 | k_us_key_len_ = strlen(k_us_key_);
310 |
311 | bndi_[3].buffer_type = MYSQL_TYPE_LONG;
312 | bndi_[3].buffer = (char*)&k_user_id_;
313 |
314 | bndi_[4].buffer_type = MYSQL_TYPE_STRING;
315 | bndi_[4].buffer = (char*)k_us_key_;
316 | bndi_[4].length = &k_us_key_len_;
317 |
318 | }
319 |
320 | if ( mysql_stmt_bind_param(s, bndi_) )
321 | Cdb::ThrowSQL("Cusers_settings::bindInput | mysql_stmt_bind_param");
322 | }
323 |
324 |
325 | /* ---------------------------------------------------------------------------
326 | Bind output values
327 | --------------------------------------------------------------------------- */
328 | void Cusers_settings::bindOutput(MYSQL_STMT *s)
329 | {
330 | memset(&bndo_, 0, sizeof(bndo_));
331 |
332 | bndo_[0].buffer_type = MYSQL_TYPE_LONG;
333 | bndo_[0].buffer = (char*)&user_id;
334 | bndo_[0].is_null = &user_id_is_null_;
335 |
336 | bndo_[1].buffer_type = MYSQL_TYPE_STRING;
337 | bndo_[1].buffer = (char*)us_key;
338 | bndo_[1].buffer_length = 31;
339 | bndo_[1].is_null = &us_key_is_null_;
340 |
341 | bndo_[2].buffer_type = MYSQL_TYPE_STRING;
342 | bndo_[2].buffer = (char*)us_val;
343 | bndo_[2].buffer_length = 251;
344 | bndo_[2].is_null = &us_val_is_null_;
345 |
346 | if ( mysql_stmt_bind_result(s, bndo_) )
347 | Cdb::ThrowSQL("Cusers_settings::bindOutput | mysql_stmt_bind_result");
348 | }
349 |
350 |
351 | /* ---------------------------------------------------------------------------
352 | Bind output value for Set
353 | --------------------------------------------------------------------------- */
354 | void Cusers_settings::bindSetOutput()
355 | {
356 | static int user_id; /* to be scrapped anyway */
357 |
358 | memset(&bndso_, 0, sizeof(bndso_));
359 |
360 | bndso_[0].buffer_type = MYSQL_TYPE_LONG;
361 | bndso_[0].buffer = (char*)&user_id;
362 |
363 | if ( mysql_stmt_bind_result(sSet_, bndso_) )
364 | Cdb::ThrowSQL("Cusers_settings::bindSetOutput | mysql_stmt_bind_result");
365 | }
366 |
367 |
368 | /* ---------------------------------------------------------------------------
369 | Reset (zero) public variables
370 | --------------------------------------------------------------------------- */
371 | void Cusers_settings::Reset()
372 | {
373 | user_id = 0;
374 | us_key[0] = EOS;
375 | us_val[0] = EOS;
376 | }
377 |
--------------------------------------------------------------------------------
/lib/Cusers_p_resets.cpp:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:16:49, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #include "Cusers_p_resets.h"
9 |
10 |
11 | bool Cusers_p_resets::slots_[CDB_MAX_INSTANCES]={0};
12 |
13 |
14 | /* ---------------------------------------------------------------------------
15 | Constructor
16 | --------------------------------------------------------------------------- */
17 | Cusers_p_resets::Cusers_p_resets()
18 | {
19 | setInstance(slots_);
20 |
21 | table_ = "users_p_resets";
22 |
23 | columnList_ = "linkkey,"
24 | "user_id,"
25 | "created,"
26 | "tries";
27 |
28 | if ( !(s_=mysql_stmt_init(dbConn_)) )
29 | ThrowSQL("mysql_stmt_init");
30 | if ( !(sc_=mysql_stmt_init(dbConn_)) )
31 | ThrowSQL("mysql_stmt_init");
32 | if ( !(sGet_=mysql_stmt_init(dbConn_)) )
33 | ThrowSQL("mysql_stmt_init");
34 | if ( !(sUpdate_=mysql_stmt_init(dbConn_)) )
35 | ThrowSQL("mysql_stmt_init");
36 | if ( !(sInsert_=mysql_stmt_init(dbConn_)) )
37 | ThrowSQL("mysql_stmt_init");
38 | if ( !(sDelete_=mysql_stmt_init(dbConn_)) )
39 | ThrowSQL("mysql_stmt_init");
40 | if ( !(sSet_=mysql_stmt_init(dbConn_)) )
41 | ThrowSQL("mysql_stmt_init");
42 |
43 | Reset();
44 | }
45 |
46 |
47 | /* ---------------------------------------------------------------------------
48 | Destructor
49 | --------------------------------------------------------------------------- */
50 | Cusers_p_resets::~Cusers_p_resets()
51 | {
52 | mysql_stmt_close(s_);
53 | mysql_stmt_close(sGet_);
54 | mysql_stmt_close(sUpdate_);
55 | mysql_stmt_close(sInsert_);
56 | mysql_stmt_close(sDelete_);
57 | mysql_stmt_close(sSet_);
58 |
59 | slots_[instance_] = false;
60 | }
61 |
62 |
63 | /* ---------------------------------------------------------------------------
64 | Get the next record
65 | Return false if end of record set
66 | --------------------------------------------------------------------------- */
67 | bool Cusers_p_resets::Fetch()
68 | {
69 | int ret;
70 |
71 | ret = mysql_stmt_fetch(s_);
72 |
73 | if ( ret != 0 )
74 | {
75 | Reset();
76 |
77 | if ( ret == 1 || ret == MYSQL_NO_DATA )
78 | return false;
79 | else
80 | {
81 | Cdb::ThrowSQL("Cusers_p_resets::Fetch | mysql_stmt_fetch");
82 | return false;
83 | }
84 | }
85 |
86 | genDTStrings();
87 |
88 | return true;
89 | }
90 |
91 |
92 | /* ---------------------------------------------------------------------------
93 | Get record by PK
94 | Not Found will return false
95 | --------------------------------------------------------------------------- */
96 | bool Cusers_p_resets::Get(const std::string& arg_linkkey)
97 | {
98 | int ret;
99 |
100 | if ( firstGet_ )
101 | {
102 | char q[CDB_SQLBUF];
103 | sprintf(q, "SELECT linkkey,user_id,created,tries FROM users_p_resets WHERE linkkey=BINARY ?");
104 | ret = mysql_stmt_prepare(sGet_, q, strlen(q));
105 | if ( ret != 0 )
106 | Cdb::ThrowSQL("Cusers_p_resets::Get | mysql_stmt_prepare");
107 | firstGet_ = false;
108 | }
109 |
110 | bindKey(sGet_, arg_linkkey);
111 |
112 | if ( mysql_stmt_execute(sGet_) )
113 | Cdb::ThrowSQL("Cusers_p_resets::Get | mysql_stmt_execute");
114 |
115 | bindOutput(sGet_);
116 |
117 | if ( mysql_stmt_store_result(sGet_) )
118 | Cdb::ThrowSQL("Cusers_p_resets::Get | mysql_stmt_store_result");
119 |
120 | ret = mysql_stmt_fetch(sGet_);
121 |
122 | if ( ret != 0 )
123 | {
124 | if ( ret == 1 || ret == MYSQL_NO_DATA )
125 | return false;
126 | else
127 | Cdb::ThrowSQL("Cusers_p_resets::Get | mysql_stmt_fetch");
128 | }
129 |
130 | genDTStrings();
131 |
132 | return true;
133 | }
134 |
135 |
136 | /* ---------------------------------------------------------------------------
137 | Insert record
138 | --------------------------------------------------------------------------- */
139 | unsigned Cusers_p_resets::Insert()
140 | {
141 | int ret;
142 |
143 | if ( firstInsert_ )
144 | {
145 | char q[CDB_SQLBUF];
146 | sprintf(q, "INSERT INTO users_p_resets (linkkey,user_id,created,tries) VALUES (?,?,?,?)");
147 | ret = mysql_stmt_prepare(sInsert_, q, strlen(q));
148 | if ( ret != 0 )
149 | Cdb::ThrowSQL("Cusers_p_resets::Insert | mysql_stmt_prepare");
150 | firstInsert_ = false;
151 | }
152 |
153 | bindInput(sInsert_);
154 |
155 | ret = mysql_stmt_execute(sInsert_);
156 |
157 | if ( ret != 0 )
158 | Cdb::ThrowSQL("Cusers_p_resets::Insert | mysql_stmt_execute");
159 |
160 | return mysql_insert_id(dbConn_);
161 | }
162 |
163 |
164 | /* ---------------------------------------------------------------------------
165 | Update record by PK
166 | --------------------------------------------------------------------------- */
167 | void Cusers_p_resets::Update(const std::string& arg_linkkey)
168 | {
169 | int ret;
170 |
171 | if ( firstUpdate_ )
172 | {
173 | char q[CDB_SQLBUF];
174 | sprintf(q, "UPDATE users_p_resets SET linkkey=?,user_id=?,created=?,tries=? WHERE linkkey=BINARY ?");
175 | ret = mysql_stmt_prepare(sUpdate_, q, strlen(q));
176 | if ( ret != 0 )
177 | Cdb::ThrowSQL("Cusers_p_resets::Update | mysql_stmt_prepare");
178 | firstUpdate_ = false;
179 | }
180 |
181 | bindInput(sUpdate_, true, arg_linkkey);
182 |
183 | ret = mysql_stmt_execute(sUpdate_);
184 |
185 | if ( ret != 0 )
186 | Cdb::ThrowSQL("Cusers_p_resets::Update | mysql_stmt_execute");
187 | }
188 |
189 |
190 | /* ---------------------------------------------------------------------------
191 | Delete record by PK
192 | --------------------------------------------------------------------------- */
193 | void Cusers_p_resets::Delete(const std::string& arg_linkkey)
194 | {
195 | int ret;
196 |
197 | if ( firstDelete_ )
198 | {
199 | char q[CDB_SQLBUF];
200 | sprintf(q, "DELETE FROM users_p_resets WHERE linkkey=BINARY ?");
201 | ret = mysql_stmt_prepare(sDelete_, q, strlen(q));
202 | if ( ret != 0 )
203 | Cdb::ThrowSQL("Cusers_p_resets::Delete | mysql_stmt_prepare");
204 | firstDelete_ = false;
205 | }
206 |
207 | bindKey(sDelete_, arg_linkkey);
208 |
209 | ret = mysql_stmt_execute(sDelete_);
210 |
211 | if ( ret != 0 )
212 | Cdb::ThrowSQL("Cusers_p_resets::Delete | mysql_stmt_execute");
213 | }
214 |
215 |
216 | /* ---------------------------------------------------------------------------
217 | Insert or update record by PK
218 | --------------------------------------------------------------------------- */
219 | void Cusers_p_resets::Set(const std::string& arg_linkkey)
220 | {
221 | int ret;
222 |
223 | if ( firstSet_ )
224 | {
225 | char q[CDB_SQLBUF];
226 | sprintf(q, "SELECT linkkey FROM users_p_resets WHERE linkkey=BINARY ?");
227 | ret = mysql_stmt_prepare(sSet_, q, strlen(q));
228 | if ( ret != 0 )
229 | Cdb::ThrowSQL("Cusers_p_resets::Set | mysql_stmt_prepare");
230 | firstSet_ = false;
231 | }
232 |
233 | bindKey(sSet_, arg_linkkey);
234 |
235 | if ( mysql_stmt_execute(sSet_) )
236 | Cdb::ThrowSQL("Cusers_p_resets::Set | mysql_stmt_execute");
237 |
238 | bindSetOutput();
239 |
240 | if ( mysql_stmt_store_result(sSet_) )
241 | Cdb::ThrowSQL("Cusers_p_resets::Set | mysql_stmt_store_result");
242 |
243 | ret = mysql_stmt_fetch(sSet_);
244 |
245 | if ( ret == 0 ) /* record existed */
246 | {
247 | Update(arg_linkkey);
248 | }
249 | else if ( ret == 1 || ret == MYSQL_NO_DATA ) /* not found ==> insert new */
250 | {
251 | strncpy(linkkey, arg_linkkey.c_str(), 20);
252 | linkkey[20] = EOS;
253 |
254 | Insert();
255 | }
256 | else
257 | Cdb::ThrowSQL("Cusers_p_resets::Set | mysql_stmt_fetch");
258 | }
259 |
260 |
261 | /* ---------------------------------------------------------------------------
262 | Bind key values
263 | --------------------------------------------------------------------------- */
264 | void Cusers_p_resets::bindKey(MYSQL_STMT *s, const std::string& arg_linkkey)
265 | {
266 | strncpy(k_linkkey_, arg_linkkey.c_str(), 20);
267 | k_linkkey_[20] = EOS;
268 |
269 | k_linkkey_len_ = strlen(k_linkkey_);
270 |
271 | memset(&bndk_, 0, sizeof(bndk_));
272 |
273 | bndk_[0].buffer_type = MYSQL_TYPE_STRING;
274 | bndk_[0].buffer = (char*)k_linkkey_;
275 | bndk_[0].length = &k_linkkey_len_;
276 |
277 | if ( mysql_stmt_bind_param(s, bndk_) )
278 | Cdb::ThrowSQL("Cusers_p_resets::bindKey | mysql_stmt_bind_param");
279 | }
280 |
281 |
282 | /* ---------------------------------------------------------------------------
283 | Bind input values
284 | --------------------------------------------------------------------------- */
285 | void Cusers_p_resets::bindInput(MYSQL_STMT *s, bool withKey, const std::string& arg_linkkey)
286 | {
287 | linkkey_len_ = strlen(linkkey);
288 |
289 | set_datetime(&t_created_, created);
290 |
291 | memset(&bndi_, 0, sizeof(bndi_));
292 |
293 | bndi_[0].buffer_type = MYSQL_TYPE_STRING;
294 | bndi_[0].buffer = (char*)linkkey;
295 | bndi_[0].length = &linkkey_len_;
296 |
297 | bndi_[1].buffer_type = MYSQL_TYPE_LONG;
298 | bndi_[1].buffer = (char*)&user_id;
299 |
300 | bndi_[2].buffer_type = MYSQL_TYPE_DATETIME;
301 | bndi_[2].buffer = (char*)&t_created_;
302 |
303 | bndi_[3].buffer_type = MYSQL_TYPE_SHORT;
304 | bndi_[3].buffer = (char*)&tries;
305 |
306 | if ( withKey ) /* after WHERE */
307 | {
308 | strncpy(k_linkkey_, arg_linkkey.c_str(), 20);
309 | k_linkkey_[20] = EOS;
310 |
311 | k_linkkey_len_ = strlen(k_linkkey_);
312 |
313 | bndi_[4].buffer_type = MYSQL_TYPE_STRING;
314 | bndi_[4].buffer = (char*)k_linkkey_;
315 | bndi_[4].length = &k_linkkey_len_;
316 |
317 | }
318 |
319 | if ( mysql_stmt_bind_param(s, bndi_) )
320 | Cdb::ThrowSQL("Cusers_p_resets::bindInput | mysql_stmt_bind_param");
321 | }
322 |
323 |
324 | /* ---------------------------------------------------------------------------
325 | Bind output values
326 | --------------------------------------------------------------------------- */
327 | void Cusers_p_resets::bindOutput(MYSQL_STMT *s)
328 | {
329 | memset(&bndo_, 0, sizeof(bndo_));
330 |
331 | bndo_[0].buffer_type = MYSQL_TYPE_STRING;
332 | bndo_[0].buffer = (char*)linkkey;
333 | bndo_[0].buffer_length = 21;
334 | bndo_[0].is_null = &linkkey_is_null_;
335 |
336 | bndo_[1].buffer_type = MYSQL_TYPE_LONG;
337 | bndo_[1].buffer = (char*)&user_id;
338 | bndo_[1].is_null = &user_id_is_null_;
339 |
340 | bndo_[2].buffer_type = MYSQL_TYPE_DATETIME;
341 | bndo_[2].buffer = (char*)&t_created_;
342 | bndo_[2].is_null = &created_is_null_;
343 |
344 | bndo_[3].buffer_type = MYSQL_TYPE_SHORT;
345 | bndo_[3].buffer = (char*)&tries;
346 | bndo_[3].is_null = &tries_is_null_;
347 |
348 | if ( mysql_stmt_bind_result(s, bndo_) )
349 | Cdb::ThrowSQL("Cusers_p_resets::bindOutput | mysql_stmt_bind_result");
350 | }
351 |
352 |
353 | /* ---------------------------------------------------------------------------
354 | Bind output value for Set
355 | --------------------------------------------------------------------------- */
356 | void Cusers_p_resets::bindSetOutput()
357 | {
358 | static USERS_P_RESETS_LINKKEY linkkey; /* to be scrapped anyway */
359 |
360 | memset(&bndso_, 0, sizeof(bndso_));
361 |
362 | bndso_[0].buffer_type = MYSQL_TYPE_STRING;
363 | bndso_[0].buffer = (char*)linkkey;
364 | bndso_[0].buffer_length = 21;
365 |
366 | if ( mysql_stmt_bind_result(sSet_, bndso_) )
367 | Cdb::ThrowSQL("Cusers_p_resets::bindSetOutput | mysql_stmt_bind_result");
368 | }
369 |
370 |
371 | /* ---------------------------------------------------------------------------
372 | Generate date-time strings
373 | --------------------------------------------------------------------------- */
374 | void Cusers_p_resets::genDTStrings()
375 | {
376 | if ( created_is_null_ )
377 | created[0] = EOS;
378 | else
379 | sprintf(created, "%04d-%02d-%02d %02d:%02d:%02d", t_created_.year, t_created_.month, t_created_.day, t_created_.hour, t_created_.minute, t_created_.second);
380 |
381 | }
382 |
383 |
384 | /* ---------------------------------------------------------------------------
385 | Reset (zero) public variables
386 | --------------------------------------------------------------------------- */
387 | void Cusers_p_resets::Reset()
388 | {
389 | linkkey[0] = EOS;
390 | user_id = 0;
391 | created[0] = EOS;
392 | tries = 0;
393 | }
394 |
--------------------------------------------------------------------------------
/lib/Cusers_messages.cpp:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:17:27, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #include "Cusers_messages.h"
9 |
10 |
11 | bool Cusers_messages::slots_[CDB_MAX_INSTANCES]={0};
12 |
13 |
14 | /* ---------------------------------------------------------------------------
15 | Constructor
16 | --------------------------------------------------------------------------- */
17 | Cusers_messages::Cusers_messages()
18 | {
19 | setInstance(slots_);
20 |
21 | table_ = "users_messages";
22 |
23 | columnList_ = "user_id,"
24 | "msg_id,"
25 | "email,"
26 | "message,"
27 | "created";
28 |
29 | if ( !(s_=mysql_stmt_init(dbConn_)) )
30 | ThrowSQL("mysql_stmt_init");
31 | if ( !(sc_=mysql_stmt_init(dbConn_)) )
32 | ThrowSQL("mysql_stmt_init");
33 | if ( !(sGet_=mysql_stmt_init(dbConn_)) )
34 | ThrowSQL("mysql_stmt_init");
35 | if ( !(sUpdate_=mysql_stmt_init(dbConn_)) )
36 | ThrowSQL("mysql_stmt_init");
37 | if ( !(sInsert_=mysql_stmt_init(dbConn_)) )
38 | ThrowSQL("mysql_stmt_init");
39 | if ( !(sDelete_=mysql_stmt_init(dbConn_)) )
40 | ThrowSQL("mysql_stmt_init");
41 | if ( !(sSet_=mysql_stmt_init(dbConn_)) )
42 | ThrowSQL("mysql_stmt_init");
43 |
44 | Reset();
45 | }
46 |
47 |
48 | /* ---------------------------------------------------------------------------
49 | Destructor
50 | --------------------------------------------------------------------------- */
51 | Cusers_messages::~Cusers_messages()
52 | {
53 | mysql_stmt_close(s_);
54 | mysql_stmt_close(sGet_);
55 | mysql_stmt_close(sUpdate_);
56 | mysql_stmt_close(sInsert_);
57 | mysql_stmt_close(sDelete_);
58 | mysql_stmt_close(sSet_);
59 |
60 | slots_[instance_] = false;
61 | }
62 |
63 |
64 | /* ---------------------------------------------------------------------------
65 | Get the next record
66 | Return false if end of record set
67 | --------------------------------------------------------------------------- */
68 | bool Cusers_messages::Fetch()
69 | {
70 | int ret;
71 |
72 | ret = mysql_stmt_fetch(s_);
73 |
74 | if ( ret != 0 )
75 | {
76 | Reset();
77 |
78 | if ( ret == 1 || ret == MYSQL_NO_DATA )
79 | return false;
80 | else
81 | {
82 | Cdb::ThrowSQL("Cusers_messages::Fetch | mysql_stmt_fetch");
83 | return false;
84 | }
85 | }
86 |
87 | genDTStrings();
88 |
89 | return true;
90 | }
91 |
92 |
93 | /* ---------------------------------------------------------------------------
94 | Get record by PK
95 | Not Found will return false
96 | --------------------------------------------------------------------------- */
97 | bool Cusers_messages::Get(int arg_user_id, int arg_msg_id)
98 | {
99 | int ret;
100 |
101 | if ( firstGet_ )
102 | {
103 | char q[CDB_SQLBUF];
104 | sprintf(q, "SELECT user_id,msg_id,email,message,created FROM users_messages WHERE user_id=? AND msg_id=?");
105 | ret = mysql_stmt_prepare(sGet_, q, strlen(q));
106 | if ( ret != 0 )
107 | Cdb::ThrowSQL("Cusers_messages::Get | mysql_stmt_prepare");
108 | firstGet_ = false;
109 | }
110 |
111 | bindKey(sGet_, arg_user_id, arg_msg_id);
112 |
113 | if ( mysql_stmt_execute(sGet_) )
114 | Cdb::ThrowSQL("Cusers_messages::Get | mysql_stmt_execute");
115 |
116 | bindOutput(sGet_);
117 |
118 | if ( mysql_stmt_store_result(sGet_) )
119 | Cdb::ThrowSQL("Cusers_messages::Get | mysql_stmt_store_result");
120 |
121 | ret = mysql_stmt_fetch(sGet_);
122 |
123 | if ( ret != 0 )
124 | {
125 | if ( ret == 1 || ret == MYSQL_NO_DATA )
126 | return false;
127 | else
128 | Cdb::ThrowSQL("Cusers_messages::Get | mysql_stmt_fetch");
129 | }
130 |
131 | genDTStrings();
132 |
133 | return true;
134 | }
135 |
136 |
137 | /* ---------------------------------------------------------------------------
138 | Insert record
139 | --------------------------------------------------------------------------- */
140 | unsigned Cusers_messages::Insert()
141 | {
142 | int ret;
143 |
144 | if ( firstInsert_ )
145 | {
146 | char q[CDB_SQLBUF];
147 | sprintf(q, "INSERT INTO users_messages (user_id,msg_id,email,message,created) VALUES (?,?,?,?,?)");
148 | ret = mysql_stmt_prepare(sInsert_, q, strlen(q));
149 | if ( ret != 0 )
150 | Cdb::ThrowSQL("Cusers_messages::Insert | mysql_stmt_prepare");
151 | firstInsert_ = false;
152 | }
153 |
154 | bindInput(sInsert_);
155 |
156 | ret = mysql_stmt_execute(sInsert_);
157 |
158 | if ( ret != 0 )
159 | Cdb::ThrowSQL("Cusers_messages::Insert | mysql_stmt_execute");
160 |
161 | return mysql_insert_id(dbConn_);
162 | }
163 |
164 |
165 | /* ---------------------------------------------------------------------------
166 | Update record by PK
167 | --------------------------------------------------------------------------- */
168 | void Cusers_messages::Update(int arg_user_id, int arg_msg_id)
169 | {
170 | int ret;
171 |
172 | if ( firstUpdate_ )
173 | {
174 | char q[CDB_SQLBUF];
175 | sprintf(q, "UPDATE users_messages SET user_id=?,msg_id=?,email=?,message=?,created=? WHERE user_id=? AND msg_id=?");
176 | ret = mysql_stmt_prepare(sUpdate_, q, strlen(q));
177 | if ( ret != 0 )
178 | Cdb::ThrowSQL("Cusers_messages::Update | mysql_stmt_prepare");
179 | firstUpdate_ = false;
180 | }
181 |
182 | bindInput(sUpdate_, true, arg_user_id, arg_msg_id);
183 |
184 | ret = mysql_stmt_execute(sUpdate_);
185 |
186 | if ( ret != 0 )
187 | Cdb::ThrowSQL("Cusers_messages::Update | mysql_stmt_execute");
188 | }
189 |
190 |
191 | /* ---------------------------------------------------------------------------
192 | Delete record by PK
193 | --------------------------------------------------------------------------- */
194 | void Cusers_messages::Delete(int arg_user_id, int arg_msg_id)
195 | {
196 | int ret;
197 |
198 | if ( firstDelete_ )
199 | {
200 | char q[CDB_SQLBUF];
201 | sprintf(q, "DELETE FROM users_messages WHERE user_id=? AND msg_id=?");
202 | ret = mysql_stmt_prepare(sDelete_, q, strlen(q));
203 | if ( ret != 0 )
204 | Cdb::ThrowSQL("Cusers_messages::Delete | mysql_stmt_prepare");
205 | firstDelete_ = false;
206 | }
207 |
208 | bindKey(sDelete_, arg_user_id, arg_msg_id);
209 |
210 | ret = mysql_stmt_execute(sDelete_);
211 |
212 | if ( ret != 0 )
213 | Cdb::ThrowSQL("Cusers_messages::Delete | mysql_stmt_execute");
214 | }
215 |
216 |
217 | /* ---------------------------------------------------------------------------
218 | Insert or update record by PK
219 | --------------------------------------------------------------------------- */
220 | void Cusers_messages::Set(int arg_user_id, int arg_msg_id)
221 | {
222 | int ret;
223 |
224 | if ( firstSet_ )
225 | {
226 | char q[CDB_SQLBUF];
227 | sprintf(q, "SELECT user_id FROM users_messages WHERE user_id=? AND msg_id=?");
228 | ret = mysql_stmt_prepare(sSet_, q, strlen(q));
229 | if ( ret != 0 )
230 | Cdb::ThrowSQL("Cusers_messages::Set | mysql_stmt_prepare");
231 | firstSet_ = false;
232 | }
233 |
234 | bindKey(sSet_, arg_user_id, arg_msg_id);
235 |
236 | if ( mysql_stmt_execute(sSet_) )
237 | Cdb::ThrowSQL("Cusers_messages::Set | mysql_stmt_execute");
238 |
239 | bindSetOutput();
240 |
241 | if ( mysql_stmt_store_result(sSet_) )
242 | Cdb::ThrowSQL("Cusers_messages::Set | mysql_stmt_store_result");
243 |
244 | ret = mysql_stmt_fetch(sSet_);
245 |
246 | if ( ret == 0 ) /* record existed */
247 | {
248 | Update(arg_user_id, arg_msg_id);
249 | }
250 | else if ( ret == 1 || ret == MYSQL_NO_DATA ) /* not found ==> insert new */
251 | {
252 | user_id = arg_user_id;
253 | msg_id = arg_msg_id;
254 |
255 | Insert();
256 | }
257 | else
258 | Cdb::ThrowSQL("Cusers_messages::Set | mysql_stmt_fetch");
259 | }
260 |
261 |
262 | /* ---------------------------------------------------------------------------
263 | Bind key values
264 | --------------------------------------------------------------------------- */
265 | void Cusers_messages::bindKey(MYSQL_STMT *s, int arg_user_id, int arg_msg_id)
266 | {
267 | k_user_id_ = arg_user_id;
268 | k_msg_id_ = arg_msg_id;
269 |
270 | memset(&bndk_, 0, sizeof(bndk_));
271 |
272 | bndk_[0].buffer_type = MYSQL_TYPE_LONG;
273 | bndk_[0].buffer = (char*)&k_user_id_;
274 |
275 | bndk_[1].buffer_type = MYSQL_TYPE_LONG;
276 | bndk_[1].buffer = (char*)&k_msg_id_;
277 |
278 | if ( mysql_stmt_bind_param(s, bndk_) )
279 | Cdb::ThrowSQL("Cusers_messages::bindKey | mysql_stmt_bind_param");
280 | }
281 |
282 |
283 | /* ---------------------------------------------------------------------------
284 | Bind input values
285 | --------------------------------------------------------------------------- */
286 | void Cusers_messages::bindInput(MYSQL_STMT *s, bool withKey, int arg_user_id, int arg_msg_id)
287 | {
288 | email_len_ = strlen(email);
289 | message_len_ = strlen(message);
290 |
291 | set_datetime(&t_created_, created);
292 |
293 | memset(&bndi_, 0, sizeof(bndi_));
294 |
295 | bndi_[0].buffer_type = MYSQL_TYPE_LONG;
296 | bndi_[0].buffer = (char*)&user_id;
297 |
298 | bndi_[1].buffer_type = MYSQL_TYPE_LONG;
299 | bndi_[1].buffer = (char*)&msg_id;
300 |
301 | bndi_[2].buffer_type = MYSQL_TYPE_STRING;
302 | bndi_[2].buffer = (char*)email;
303 | bndi_[2].length = &email_len_;
304 |
305 | bndi_[3].buffer_type = MYSQL_TYPE_STRING;
306 | bndi_[3].buffer = (char*)message;
307 | bndi_[3].length = &message_len_;
308 |
309 | bndi_[4].buffer_type = MYSQL_TYPE_DATETIME;
310 | bndi_[4].buffer = (char*)&t_created_;
311 |
312 | if ( withKey ) /* after WHERE */
313 | {
314 | k_user_id_ = arg_user_id;
315 | k_msg_id_ = arg_msg_id;
316 |
317 | bndi_[5].buffer_type = MYSQL_TYPE_LONG;
318 | bndi_[5].buffer = (char*)&k_user_id_;
319 |
320 | bndi_[6].buffer_type = MYSQL_TYPE_LONG;
321 | bndi_[6].buffer = (char*)&k_msg_id_;
322 |
323 | }
324 |
325 | if ( mysql_stmt_bind_param(s, bndi_) )
326 | Cdb::ThrowSQL("Cusers_messages::bindInput | mysql_stmt_bind_param");
327 | }
328 |
329 |
330 | /* ---------------------------------------------------------------------------
331 | Bind output values
332 | --------------------------------------------------------------------------- */
333 | void Cusers_messages::bindOutput(MYSQL_STMT *s)
334 | {
335 | memset(&bndo_, 0, sizeof(bndo_));
336 |
337 | bndo_[0].buffer_type = MYSQL_TYPE_LONG;
338 | bndo_[0].buffer = (char*)&user_id;
339 | bndo_[0].is_null = &user_id_is_null_;
340 |
341 | bndo_[1].buffer_type = MYSQL_TYPE_LONG;
342 | bndo_[1].buffer = (char*)&msg_id;
343 | bndo_[1].is_null = &msg_id_is_null_;
344 |
345 | bndo_[2].buffer_type = MYSQL_TYPE_STRING;
346 | bndo_[2].buffer = (char*)email;
347 | bndo_[2].buffer_length = 121;
348 | bndo_[2].is_null = &email_is_null_;
349 |
350 | bndo_[3].buffer_type = MYSQL_TYPE_STRING;
351 | bndo_[3].buffer = (char*)message;
352 | bndo_[3].buffer_length = 65536;
353 | bndo_[3].is_null = &message_is_null_;
354 |
355 | bndo_[4].buffer_type = MYSQL_TYPE_DATETIME;
356 | bndo_[4].buffer = (char*)&t_created_;
357 | bndo_[4].is_null = &created_is_null_;
358 |
359 | if ( mysql_stmt_bind_result(s, bndo_) )
360 | Cdb::ThrowSQL("Cusers_messages::bindOutput | mysql_stmt_bind_result");
361 | }
362 |
363 |
364 | /* ---------------------------------------------------------------------------
365 | Bind output value for Set
366 | --------------------------------------------------------------------------- */
367 | void Cusers_messages::bindSetOutput()
368 | {
369 | static int user_id; /* to be scrapped anyway */
370 |
371 | memset(&bndso_, 0, sizeof(bndso_));
372 |
373 | bndso_[0].buffer_type = MYSQL_TYPE_LONG;
374 | bndso_[0].buffer = (char*)&user_id;
375 |
376 | if ( mysql_stmt_bind_result(sSet_, bndso_) )
377 | Cdb::ThrowSQL("Cusers_messages::bindSetOutput | mysql_stmt_bind_result");
378 | }
379 |
380 |
381 | /* ---------------------------------------------------------------------------
382 | Generate date-time strings
383 | --------------------------------------------------------------------------- */
384 | void Cusers_messages::genDTStrings()
385 | {
386 | if ( created_is_null_ )
387 | created[0] = EOS;
388 | else
389 | sprintf(created, "%04d-%02d-%02d %02d:%02d:%02d", t_created_.year, t_created_.month, t_created_.day, t_created_.hour, t_created_.minute, t_created_.second);
390 |
391 | }
392 |
393 |
394 | /* ---------------------------------------------------------------------------
395 | Reset (zero) public variables
396 | --------------------------------------------------------------------------- */
397 | void Cusers_messages::Reset()
398 | {
399 | user_id = 0;
400 | msg_id = 0;
401 | email[0] = EOS;
402 | message[0] = EOS;
403 | created[0] = EOS;
404 | }
405 |
--------------------------------------------------------------------------------
/lib/Cusers_activations.cpp:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 15:16:31, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #include "Cusers_activations.h"
9 |
10 |
11 | bool Cusers_activations::slots_[CDB_MAX_INSTANCES]={0};
12 |
13 |
14 | /* ---------------------------------------------------------------------------
15 | Constructor
16 | --------------------------------------------------------------------------- */
17 | Cusers_activations::Cusers_activations()
18 | {
19 | setInstance(slots_);
20 |
21 | table_ = "users_activations";
22 |
23 | columnList_ = "linkkey,"
24 | "user_id,"
25 | "created,"
26 | "activated";
27 |
28 | if ( !(s_=mysql_stmt_init(dbConn_)) )
29 | ThrowSQL("mysql_stmt_init");
30 | if ( !(sc_=mysql_stmt_init(dbConn_)) )
31 | ThrowSQL("mysql_stmt_init");
32 | if ( !(sGet_=mysql_stmt_init(dbConn_)) )
33 | ThrowSQL("mysql_stmt_init");
34 | if ( !(sUpdate_=mysql_stmt_init(dbConn_)) )
35 | ThrowSQL("mysql_stmt_init");
36 | if ( !(sInsert_=mysql_stmt_init(dbConn_)) )
37 | ThrowSQL("mysql_stmt_init");
38 | if ( !(sDelete_=mysql_stmt_init(dbConn_)) )
39 | ThrowSQL("mysql_stmt_init");
40 | if ( !(sSet_=mysql_stmt_init(dbConn_)) )
41 | ThrowSQL("mysql_stmt_init");
42 |
43 | Reset();
44 | }
45 |
46 |
47 | /* ---------------------------------------------------------------------------
48 | Destructor
49 | --------------------------------------------------------------------------- */
50 | Cusers_activations::~Cusers_activations()
51 | {
52 | mysql_stmt_close(s_);
53 | mysql_stmt_close(sGet_);
54 | mysql_stmt_close(sUpdate_);
55 | mysql_stmt_close(sInsert_);
56 | mysql_stmt_close(sDelete_);
57 | mysql_stmt_close(sSet_);
58 |
59 | slots_[instance_] = false;
60 | }
61 |
62 |
63 | /* ---------------------------------------------------------------------------
64 | Get the next record
65 | Return false if end of record set
66 | --------------------------------------------------------------------------- */
67 | bool Cusers_activations::Fetch()
68 | {
69 | int ret;
70 |
71 | ret = mysql_stmt_fetch(s_);
72 |
73 | if ( ret != 0 )
74 | {
75 | Reset();
76 |
77 | if ( ret == 1 || ret == MYSQL_NO_DATA )
78 | return false;
79 | else
80 | {
81 | Cdb::ThrowSQL("Cusers_activations::Fetch | mysql_stmt_fetch");
82 | return false;
83 | }
84 | }
85 |
86 | genDTStrings();
87 |
88 | return true;
89 | }
90 |
91 |
92 | /* ---------------------------------------------------------------------------
93 | Get record by PK
94 | Not Found will return false
95 | --------------------------------------------------------------------------- */
96 | bool Cusers_activations::Get(const std::string& arg_linkkey)
97 | {
98 | int ret;
99 |
100 | if ( firstGet_ )
101 | {
102 | char q[CDB_SQLBUF];
103 | sprintf(q, "SELECT linkkey,user_id,created,activated FROM users_activations WHERE linkkey=BINARY ?");
104 | ret = mysql_stmt_prepare(sGet_, q, strlen(q));
105 | if ( ret != 0 )
106 | Cdb::ThrowSQL("Cusers_activations::Get | mysql_stmt_prepare");
107 | firstGet_ = false;
108 | }
109 |
110 | bindKey(sGet_, arg_linkkey);
111 |
112 | if ( mysql_stmt_execute(sGet_) )
113 | Cdb::ThrowSQL("Cusers_activations::Get | mysql_stmt_execute");
114 |
115 | bindOutput(sGet_);
116 |
117 | if ( mysql_stmt_store_result(sGet_) )
118 | Cdb::ThrowSQL("Cusers_activations::Get | mysql_stmt_store_result");
119 |
120 | ret = mysql_stmt_fetch(sGet_);
121 |
122 | if ( ret != 0 )
123 | {
124 | if ( ret == 1 || ret == MYSQL_NO_DATA )
125 | return false;
126 | else
127 | Cdb::ThrowSQL("Cusers_activations::Get | mysql_stmt_fetch");
128 | }
129 |
130 | genDTStrings();
131 |
132 | return true;
133 | }
134 |
135 |
136 | /* ---------------------------------------------------------------------------
137 | Insert record
138 | --------------------------------------------------------------------------- */
139 | unsigned Cusers_activations::Insert()
140 | {
141 | int ret;
142 |
143 | if ( firstInsert_ )
144 | {
145 | char q[CDB_SQLBUF];
146 | sprintf(q, "INSERT INTO users_activations (linkkey,user_id,created,activated) VALUES (?,?,?,?)");
147 | ret = mysql_stmt_prepare(sInsert_, q, strlen(q));
148 | if ( ret != 0 )
149 | Cdb::ThrowSQL("Cusers_activations::Insert | mysql_stmt_prepare");
150 | firstInsert_ = false;
151 | }
152 |
153 | bindInput(sInsert_);
154 |
155 | ret = mysql_stmt_execute(sInsert_);
156 |
157 | if ( ret != 0 )
158 | Cdb::ThrowSQL("Cusers_activations::Insert | mysql_stmt_execute");
159 |
160 | return mysql_insert_id(dbConn_);
161 | }
162 |
163 |
164 | /* ---------------------------------------------------------------------------
165 | Update record by PK
166 | --------------------------------------------------------------------------- */
167 | void Cusers_activations::Update(const std::string& arg_linkkey)
168 | {
169 | int ret;
170 |
171 | if ( firstUpdate_ )
172 | {
173 | char q[CDB_SQLBUF];
174 | sprintf(q, "UPDATE users_activations SET linkkey=?,user_id=?,created=?,activated=? WHERE linkkey=BINARY ?");
175 | ret = mysql_stmt_prepare(sUpdate_, q, strlen(q));
176 | if ( ret != 0 )
177 | Cdb::ThrowSQL("Cusers_activations::Update | mysql_stmt_prepare");
178 | firstUpdate_ = false;
179 | }
180 |
181 | bindInput(sUpdate_, true, arg_linkkey);
182 |
183 | ret = mysql_stmt_execute(sUpdate_);
184 |
185 | if ( ret != 0 )
186 | Cdb::ThrowSQL("Cusers_activations::Update | mysql_stmt_execute");
187 | }
188 |
189 |
190 | /* ---------------------------------------------------------------------------
191 | Delete record by PK
192 | --------------------------------------------------------------------------- */
193 | void Cusers_activations::Delete(const std::string& arg_linkkey)
194 | {
195 | int ret;
196 |
197 | if ( firstDelete_ )
198 | {
199 | char q[CDB_SQLBUF];
200 | sprintf(q, "DELETE FROM users_activations WHERE linkkey=BINARY ?");
201 | ret = mysql_stmt_prepare(sDelete_, q, strlen(q));
202 | if ( ret != 0 )
203 | Cdb::ThrowSQL("Cusers_activations::Delete | mysql_stmt_prepare");
204 | firstDelete_ = false;
205 | }
206 |
207 | bindKey(sDelete_, arg_linkkey);
208 |
209 | ret = mysql_stmt_execute(sDelete_);
210 |
211 | if ( ret != 0 )
212 | Cdb::ThrowSQL("Cusers_activations::Delete | mysql_stmt_execute");
213 | }
214 |
215 |
216 | /* ---------------------------------------------------------------------------
217 | Insert or update record by PK
218 | --------------------------------------------------------------------------- */
219 | void Cusers_activations::Set(const std::string& arg_linkkey)
220 | {
221 | int ret;
222 |
223 | if ( firstSet_ )
224 | {
225 | char q[CDB_SQLBUF];
226 | sprintf(q, "SELECT linkkey FROM users_activations WHERE linkkey=BINARY ?");
227 | ret = mysql_stmt_prepare(sSet_, q, strlen(q));
228 | if ( ret != 0 )
229 | Cdb::ThrowSQL("Cusers_activations::Set | mysql_stmt_prepare");
230 | firstSet_ = false;
231 | }
232 |
233 | bindKey(sSet_, arg_linkkey);
234 |
235 | if ( mysql_stmt_execute(sSet_) )
236 | Cdb::ThrowSQL("Cusers_activations::Set | mysql_stmt_execute");
237 |
238 | bindSetOutput();
239 |
240 | if ( mysql_stmt_store_result(sSet_) )
241 | Cdb::ThrowSQL("Cusers_activations::Set | mysql_stmt_store_result");
242 |
243 | ret = mysql_stmt_fetch(sSet_);
244 |
245 | if ( ret == 0 ) /* record existed */
246 | {
247 | Update(arg_linkkey);
248 | }
249 | else if ( ret == 1 || ret == MYSQL_NO_DATA ) /* not found ==> insert new */
250 | {
251 | strncpy(linkkey, arg_linkkey.c_str(), 20);
252 | linkkey[20] = EOS;
253 |
254 | Insert();
255 | }
256 | else
257 | Cdb::ThrowSQL("Cusers_activations::Set | mysql_stmt_fetch");
258 | }
259 |
260 |
261 | /* ---------------------------------------------------------------------------
262 | Bind key values
263 | --------------------------------------------------------------------------- */
264 | void Cusers_activations::bindKey(MYSQL_STMT *s, const std::string& arg_linkkey)
265 | {
266 | strncpy(k_linkkey_, arg_linkkey.c_str(), 20);
267 | k_linkkey_[20] = EOS;
268 |
269 | k_linkkey_len_ = strlen(k_linkkey_);
270 |
271 | memset(&bndk_, 0, sizeof(bndk_));
272 |
273 | bndk_[0].buffer_type = MYSQL_TYPE_STRING;
274 | bndk_[0].buffer = (char*)k_linkkey_;
275 | bndk_[0].length = &k_linkkey_len_;
276 |
277 | if ( mysql_stmt_bind_param(s, bndk_) )
278 | Cdb::ThrowSQL("Cusers_activations::bindKey | mysql_stmt_bind_param");
279 | }
280 |
281 |
282 | /* ---------------------------------------------------------------------------
283 | Bind input values
284 | --------------------------------------------------------------------------- */
285 | void Cusers_activations::bindInput(MYSQL_STMT *s, bool withKey, const std::string& arg_linkkey)
286 | {
287 | linkkey_len_ = strlen(linkkey);
288 |
289 | set_datetime(&t_created_, created);
290 | set_datetime(&t_activated_, activated);
291 |
292 | memset(&bndi_, 0, sizeof(bndi_));
293 |
294 | bndi_[0].buffer_type = MYSQL_TYPE_STRING;
295 | bndi_[0].buffer = (char*)linkkey;
296 | bndi_[0].length = &linkkey_len_;
297 |
298 | bndi_[1].buffer_type = MYSQL_TYPE_LONG;
299 | bndi_[1].buffer = (char*)&user_id;
300 |
301 | bndi_[2].buffer_type = MYSQL_TYPE_DATETIME;
302 | bndi_[2].buffer = (char*)&t_created_;
303 |
304 | bndi_[3].buffer_type = MYSQL_TYPE_DATETIME;
305 | bndi_[3].buffer = (char*)&t_activated_;
306 |
307 | if ( withKey ) /* after WHERE */
308 | {
309 | strncpy(k_linkkey_, arg_linkkey.c_str(), 20);
310 | k_linkkey_[20] = EOS;
311 |
312 | k_linkkey_len_ = strlen(k_linkkey_);
313 |
314 | bndi_[4].buffer_type = MYSQL_TYPE_STRING;
315 | bndi_[4].buffer = (char*)k_linkkey_;
316 | bndi_[4].length = &k_linkkey_len_;
317 |
318 | }
319 |
320 | if ( mysql_stmt_bind_param(s, bndi_) )
321 | Cdb::ThrowSQL("Cusers_activations::bindInput | mysql_stmt_bind_param");
322 | }
323 |
324 |
325 | /* ---------------------------------------------------------------------------
326 | Bind output values
327 | --------------------------------------------------------------------------- */
328 | void Cusers_activations::bindOutput(MYSQL_STMT *s)
329 | {
330 | memset(&bndo_, 0, sizeof(bndo_));
331 |
332 | bndo_[0].buffer_type = MYSQL_TYPE_STRING;
333 | bndo_[0].buffer = (char*)linkkey;
334 | bndo_[0].buffer_length = 21;
335 | bndo_[0].is_null = &linkkey_is_null_;
336 |
337 | bndo_[1].buffer_type = MYSQL_TYPE_LONG;
338 | bndo_[1].buffer = (char*)&user_id;
339 | bndo_[1].is_null = &user_id_is_null_;
340 |
341 | bndo_[2].buffer_type = MYSQL_TYPE_DATETIME;
342 | bndo_[2].buffer = (char*)&t_created_;
343 | bndo_[2].is_null = &created_is_null_;
344 |
345 | bndo_[3].buffer_type = MYSQL_TYPE_DATETIME;
346 | bndo_[3].buffer = (char*)&t_activated_;
347 | bndo_[3].is_null = &activated_is_null_;
348 |
349 | if ( mysql_stmt_bind_result(s, bndo_) )
350 | Cdb::ThrowSQL("Cusers_activations::bindOutput | mysql_stmt_bind_result");
351 | }
352 |
353 |
354 | /* ---------------------------------------------------------------------------
355 | Bind output value for Set
356 | --------------------------------------------------------------------------- */
357 | void Cusers_activations::bindSetOutput()
358 | {
359 | static USERS_ACTIVATIONS_LINKKEY linkkey; /* to be scrapped anyway */
360 |
361 | memset(&bndso_, 0, sizeof(bndso_));
362 |
363 | bndso_[0].buffer_type = MYSQL_TYPE_STRING;
364 | bndso_[0].buffer = (char*)linkkey;
365 | bndso_[0].buffer_length = 21;
366 |
367 | if ( mysql_stmt_bind_result(sSet_, bndso_) )
368 | Cdb::ThrowSQL("Cusers_activations::bindSetOutput | mysql_stmt_bind_result");
369 | }
370 |
371 |
372 | /* ---------------------------------------------------------------------------
373 | Generate date-time strings
374 | --------------------------------------------------------------------------- */
375 | void Cusers_activations::genDTStrings()
376 | {
377 | if ( created_is_null_ )
378 | created[0] = EOS;
379 | else
380 | sprintf(created, "%04d-%02d-%02d %02d:%02d:%02d", t_created_.year, t_created_.month, t_created_.day, t_created_.hour, t_created_.minute, t_created_.second);
381 |
382 | if ( activated_is_null_ )
383 | activated[0] = EOS;
384 | else
385 | sprintf(activated, "%04d-%02d-%02d %02d:%02d:%02d", t_activated_.year, t_activated_.month, t_activated_.day, t_activated_.hour, t_activated_.minute, t_activated_.second);
386 | }
387 |
388 |
389 | /* ---------------------------------------------------------------------------
390 | Reset (zero) public variables
391 | --------------------------------------------------------------------------- */
392 | void Cusers_activations::Reset()
393 | {
394 | linkkey[0] = EOS;
395 | user_id = 0;
396 | created[0] = EOS;
397 | activated[0] = EOS;
398 | }
399 |
--------------------------------------------------------------------------------
/lib/Cusers_logins.cpp:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-28 14:28:27, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #include "Cusers_logins.h"
9 |
10 |
11 | bool Cusers_logins::slots_[CDB_MAX_INSTANCES]={0};
12 |
13 |
14 | /* ---------------------------------------------------------------------------
15 | Constructor
16 | --------------------------------------------------------------------------- */
17 | Cusers_logins::Cusers_logins()
18 | {
19 | setInstance(slots_);
20 |
21 | table_ = "users_logins";
22 |
23 | columnList_ = "sessid,"
24 | "uagent,"
25 | "ip,"
26 | "user_id,"
27 | "csrft,"
28 | "created,"
29 | "last_used";
30 |
31 | if ( !(s_=mysql_stmt_init(dbConn_)) )
32 | ThrowSQL("mysql_stmt_init");
33 | if ( !(sc_=mysql_stmt_init(dbConn_)) )
34 | ThrowSQL("mysql_stmt_init");
35 | if ( !(sGet_=mysql_stmt_init(dbConn_)) )
36 | ThrowSQL("mysql_stmt_init");
37 | if ( !(sUpdate_=mysql_stmt_init(dbConn_)) )
38 | ThrowSQL("mysql_stmt_init");
39 | if ( !(sInsert_=mysql_stmt_init(dbConn_)) )
40 | ThrowSQL("mysql_stmt_init");
41 | if ( !(sDelete_=mysql_stmt_init(dbConn_)) )
42 | ThrowSQL("mysql_stmt_init");
43 | if ( !(sSet_=mysql_stmt_init(dbConn_)) )
44 | ThrowSQL("mysql_stmt_init");
45 |
46 | Reset();
47 | }
48 |
49 |
50 | /* ---------------------------------------------------------------------------
51 | Destructor
52 | --------------------------------------------------------------------------- */
53 | Cusers_logins::~Cusers_logins()
54 | {
55 | mysql_stmt_close(s_);
56 | mysql_stmt_close(sGet_);
57 | mysql_stmt_close(sUpdate_);
58 | mysql_stmt_close(sInsert_);
59 | mysql_stmt_close(sDelete_);
60 | mysql_stmt_close(sSet_);
61 |
62 | slots_[instance_] = false;
63 | }
64 |
65 |
66 | /* ---------------------------------------------------------------------------
67 | Get the next record
68 | Return false if end of record set
69 | --------------------------------------------------------------------------- */
70 | bool Cusers_logins::Fetch()
71 | {
72 | int ret;
73 |
74 | ret = mysql_stmt_fetch(s_);
75 |
76 | if ( ret != 0 )
77 | {
78 | Reset();
79 |
80 | if ( ret == 1 || ret == MYSQL_NO_DATA )
81 | return false;
82 | else
83 | {
84 | Cdb::ThrowSQL("Cusers_logins::Fetch | mysql_stmt_fetch");
85 | return false;
86 | }
87 | }
88 |
89 | genDTStrings();
90 |
91 | return true;
92 | }
93 |
94 |
95 | /* ---------------------------------------------------------------------------
96 | Get record by PK
97 | Not Found will return false
98 | --------------------------------------------------------------------------- */
99 | bool Cusers_logins::Get(const std::string& arg_sessid)
100 | {
101 | int ret;
102 |
103 | if ( firstGet_ )
104 | {
105 | char q[CDB_SQLBUF];
106 | sprintf(q, "SELECT sessid,uagent,ip,user_id,csrft,created,last_used FROM users_logins WHERE sessid=BINARY ?");
107 | ret = mysql_stmt_prepare(sGet_, q, strlen(q));
108 | if ( ret != 0 )
109 | Cdb::ThrowSQL("Cusers_logins::Get | mysql_stmt_prepare");
110 | firstGet_ = false;
111 | }
112 |
113 | bindKey(sGet_, arg_sessid);
114 |
115 | if ( mysql_stmt_execute(sGet_) )
116 | Cdb::ThrowSQL("Cusers_logins::Get | mysql_stmt_execute");
117 |
118 | bindOutput(sGet_);
119 |
120 | if ( mysql_stmt_store_result(sGet_) )
121 | Cdb::ThrowSQL("Cusers_logins::Get | mysql_stmt_store_result");
122 |
123 | ret = mysql_stmt_fetch(sGet_);
124 |
125 | if ( ret != 0 )
126 | {
127 | if ( ret == 1 || ret == MYSQL_NO_DATA )
128 | return false;
129 | else
130 | Cdb::ThrowSQL("Cusers_logins::Get | mysql_stmt_fetch");
131 | }
132 |
133 | genDTStrings();
134 |
135 | return true;
136 | }
137 |
138 |
139 | /* ---------------------------------------------------------------------------
140 | Insert record
141 | --------------------------------------------------------------------------- */
142 | unsigned Cusers_logins::Insert()
143 | {
144 | int ret;
145 |
146 | if ( firstInsert_ )
147 | {
148 | char q[CDB_SQLBUF];
149 | sprintf(q, "INSERT INTO users_logins (sessid,uagent,ip,user_id,csrft,created,last_used) VALUES (?,?,?,?,?,?,?)");
150 | ret = mysql_stmt_prepare(sInsert_, q, strlen(q));
151 | if ( ret != 0 )
152 | Cdb::ThrowSQL("Cusers_logins::Insert | mysql_stmt_prepare");
153 | firstInsert_ = false;
154 | }
155 |
156 | bindInput(sInsert_);
157 |
158 | ret = mysql_stmt_execute(sInsert_);
159 |
160 | if ( ret != 0 )
161 | Cdb::ThrowSQL("Cusers_logins::Insert | mysql_stmt_execute");
162 |
163 | return mysql_insert_id(dbConn_);
164 | }
165 |
166 |
167 | /* ---------------------------------------------------------------------------
168 | Update record by PK
169 | --------------------------------------------------------------------------- */
170 | void Cusers_logins::Update(const std::string& arg_sessid)
171 | {
172 | int ret;
173 |
174 | if ( firstUpdate_ )
175 | {
176 | char q[CDB_SQLBUF];
177 | sprintf(q, "UPDATE users_logins SET sessid=?,uagent=?,ip=?,user_id=?,csrft=?,created=?,last_used=? WHERE sessid=BINARY ?");
178 | ret = mysql_stmt_prepare(sUpdate_, q, strlen(q));
179 | if ( ret != 0 )
180 | Cdb::ThrowSQL("Cusers_logins::Update | mysql_stmt_prepare");
181 | firstUpdate_ = false;
182 | }
183 |
184 | bindInput(sUpdate_, true, arg_sessid);
185 |
186 | ret = mysql_stmt_execute(sUpdate_);
187 |
188 | if ( ret != 0 )
189 | Cdb::ThrowSQL("Cusers_logins::Update | mysql_stmt_execute");
190 | }
191 |
192 |
193 | /* ---------------------------------------------------------------------------
194 | Delete record by PK
195 | --------------------------------------------------------------------------- */
196 | void Cusers_logins::Delete(const std::string& arg_sessid)
197 | {
198 | int ret;
199 |
200 | if ( firstDelete_ )
201 | {
202 | char q[CDB_SQLBUF];
203 | sprintf(q, "DELETE FROM users_logins WHERE sessid=BINARY ?");
204 | ret = mysql_stmt_prepare(sDelete_, q, strlen(q));
205 | if ( ret != 0 )
206 | Cdb::ThrowSQL("Cusers_logins::Delete | mysql_stmt_prepare");
207 | firstDelete_ = false;
208 | }
209 |
210 | bindKey(sDelete_, arg_sessid);
211 |
212 | ret = mysql_stmt_execute(sDelete_);
213 |
214 | if ( ret != 0 )
215 | Cdb::ThrowSQL("Cusers_logins::Delete | mysql_stmt_execute");
216 | }
217 |
218 |
219 | /* ---------------------------------------------------------------------------
220 | Insert or update record by PK
221 | --------------------------------------------------------------------------- */
222 | void Cusers_logins::Set(const std::string& arg_sessid)
223 | {
224 | int ret;
225 |
226 | if ( firstSet_ )
227 | {
228 | char q[CDB_SQLBUF];
229 | sprintf(q, "SELECT sessid FROM users_logins WHERE sessid=BINARY ?");
230 | ret = mysql_stmt_prepare(sSet_, q, strlen(q));
231 | if ( ret != 0 )
232 | Cdb::ThrowSQL("Cusers_logins::Set | mysql_stmt_prepare");
233 | firstSet_ = false;
234 | }
235 |
236 | bindKey(sSet_, arg_sessid);
237 |
238 | if ( mysql_stmt_execute(sSet_) )
239 | Cdb::ThrowSQL("Cusers_logins::Set | mysql_stmt_execute");
240 |
241 | bindSetOutput();
242 |
243 | if ( mysql_stmt_store_result(sSet_) )
244 | Cdb::ThrowSQL("Cusers_logins::Set | mysql_stmt_store_result");
245 |
246 | ret = mysql_stmt_fetch(sSet_);
247 |
248 | if ( ret == 0 ) /* record existed */
249 | {
250 | Update(arg_sessid);
251 | }
252 | else if ( ret == 1 || ret == MYSQL_NO_DATA ) /* not found ==> insert new */
253 | {
254 | strncpy(sessid, arg_sessid.c_str(), 15);
255 | sessid[15] = EOS;
256 |
257 | Insert();
258 | }
259 | else
260 | Cdb::ThrowSQL("Cusers_logins::Set | mysql_stmt_fetch");
261 | }
262 |
263 |
264 | /* ---------------------------------------------------------------------------
265 | Bind key values
266 | --------------------------------------------------------------------------- */
267 | void Cusers_logins::bindKey(MYSQL_STMT *s, const std::string& arg_sessid)
268 | {
269 | strncpy(k_sessid_, arg_sessid.c_str(), 15);
270 | k_sessid_[15] = EOS;
271 |
272 | k_sessid_len_ = strlen(k_sessid_);
273 |
274 | memset(&bndk_, 0, sizeof(bndk_));
275 |
276 | bndk_[0].buffer_type = MYSQL_TYPE_STRING;
277 | bndk_[0].buffer = (char*)k_sessid_;
278 | bndk_[0].length = &k_sessid_len_;
279 |
280 | if ( mysql_stmt_bind_param(s, bndk_) )
281 | Cdb::ThrowSQL("Cusers_logins::bindKey | mysql_stmt_bind_param");
282 | }
283 |
284 |
285 | /* ---------------------------------------------------------------------------
286 | Bind input values
287 | --------------------------------------------------------------------------- */
288 | void Cusers_logins::bindInput(MYSQL_STMT *s, bool withKey, const std::string& arg_sessid)
289 | {
290 | sessid_len_ = strlen(sessid);
291 | uagent_len_ = strlen(uagent);
292 | ip_len_ = strlen(ip);
293 | csrft_len_ = strlen(csrft);
294 |
295 | set_datetime(&t_created_, created);
296 | set_datetime(&t_last_used_, last_used);
297 |
298 | memset(&bndi_, 0, sizeof(bndi_));
299 |
300 | bndi_[0].buffer_type = MYSQL_TYPE_STRING;
301 | bndi_[0].buffer = (char*)sessid;
302 | bndi_[0].length = &sessid_len_;
303 |
304 | bndi_[1].buffer_type = MYSQL_TYPE_STRING;
305 | bndi_[1].buffer = (char*)uagent;
306 | bndi_[1].length = &uagent_len_;
307 |
308 | bndi_[2].buffer_type = MYSQL_TYPE_STRING;
309 | bndi_[2].buffer = (char*)ip;
310 | bndi_[2].length = &ip_len_;
311 |
312 | bndi_[3].buffer_type = MYSQL_TYPE_LONG;
313 | bndi_[3].buffer = (char*)&user_id;
314 |
315 | bndi_[4].buffer_type = MYSQL_TYPE_STRING;
316 | bndi_[4].buffer = (char*)csrft;
317 | bndi_[4].length = &csrft_len_;
318 |
319 | bndi_[5].buffer_type = MYSQL_TYPE_DATETIME;
320 | bndi_[5].buffer = (char*)&t_created_;
321 |
322 | bndi_[6].buffer_type = MYSQL_TYPE_DATETIME;
323 | bndi_[6].buffer = (char*)&t_last_used_;
324 |
325 | if ( withKey ) /* after WHERE */
326 | {
327 | strncpy(k_sessid_, arg_sessid.c_str(), 15);
328 | k_sessid_[15] = EOS;
329 |
330 | k_sessid_len_ = strlen(k_sessid_);
331 |
332 | bndi_[7].buffer_type = MYSQL_TYPE_STRING;
333 | bndi_[7].buffer = (char*)k_sessid_;
334 | bndi_[7].length = &k_sessid_len_;
335 |
336 | }
337 |
338 | if ( mysql_stmt_bind_param(s, bndi_) )
339 | Cdb::ThrowSQL("Cusers_logins::bindInput | mysql_stmt_bind_param");
340 | }
341 |
342 |
343 | /* ---------------------------------------------------------------------------
344 | Bind output values
345 | --------------------------------------------------------------------------- */
346 | void Cusers_logins::bindOutput(MYSQL_STMT *s)
347 | {
348 | memset(&bndo_, 0, sizeof(bndo_));
349 |
350 | bndo_[0].buffer_type = MYSQL_TYPE_STRING;
351 | bndo_[0].buffer = (char*)sessid;
352 | bndo_[0].buffer_length = 16;
353 | bndo_[0].is_null = &sessid_is_null_;
354 |
355 | bndo_[1].buffer_type = MYSQL_TYPE_STRING;
356 | bndo_[1].buffer = (char*)uagent;
357 | bndo_[1].buffer_length = 251;
358 | bndo_[1].is_null = &uagent_is_null_;
359 |
360 | bndo_[2].buffer_type = MYSQL_TYPE_STRING;
361 | bndo_[2].buffer = (char*)ip;
362 | bndo_[2].buffer_length = 46;
363 | bndo_[2].is_null = &ip_is_null_;
364 |
365 | bndo_[3].buffer_type = MYSQL_TYPE_LONG;
366 | bndo_[3].buffer = (char*)&user_id;
367 | bndo_[3].is_null = &user_id_is_null_;
368 |
369 | bndo_[4].buffer_type = MYSQL_TYPE_STRING;
370 | bndo_[4].buffer = (char*)csrft;
371 | bndo_[4].buffer_length = 8;
372 | bndo_[4].is_null = &csrft_is_null_;
373 |
374 | bndo_[5].buffer_type = MYSQL_TYPE_DATETIME;
375 | bndo_[5].buffer = (char*)&t_created_;
376 | bndo_[5].is_null = &created_is_null_;
377 |
378 | bndo_[6].buffer_type = MYSQL_TYPE_DATETIME;
379 | bndo_[6].buffer = (char*)&t_last_used_;
380 | bndo_[6].is_null = &last_used_is_null_;
381 |
382 | if ( mysql_stmt_bind_result(s, bndo_) )
383 | Cdb::ThrowSQL("Cusers_logins::bindOutput | mysql_stmt_bind_result");
384 | }
385 |
386 |
387 | /* ---------------------------------------------------------------------------
388 | Bind output value for Set
389 | --------------------------------------------------------------------------- */
390 | void Cusers_logins::bindSetOutput()
391 | {
392 | static USERS_LOGINS_SESSID sessid; /* to be scrapped anyway */
393 |
394 | memset(&bndso_, 0, sizeof(bndso_));
395 |
396 | bndso_[0].buffer_type = MYSQL_TYPE_STRING;
397 | bndso_[0].buffer = (char*)sessid;
398 | bndso_[0].buffer_length = 16;
399 |
400 | if ( mysql_stmt_bind_result(sSet_, bndso_) )
401 | Cdb::ThrowSQL("Cusers_logins::bindSetOutput | mysql_stmt_bind_result");
402 | }
403 |
404 |
405 | /* ---------------------------------------------------------------------------
406 | Generate date-time strings
407 | --------------------------------------------------------------------------- */
408 | void Cusers_logins::genDTStrings()
409 | {
410 | if ( created_is_null_ )
411 | created[0] = EOS;
412 | else
413 | sprintf(created, "%04d-%02d-%02d %02d:%02d:%02d", t_created_.year, t_created_.month, t_created_.day, t_created_.hour, t_created_.minute, t_created_.second);
414 |
415 | if ( last_used_is_null_ )
416 | last_used[0] = EOS;
417 | else
418 | sprintf(last_used, "%04d-%02d-%02d %02d:%02d:%02d", t_last_used_.year, t_last_used_.month, t_last_used_.day, t_last_used_.hour, t_last_used_.minute, t_last_used_.second);
419 | }
420 |
421 |
422 | /* ---------------------------------------------------------------------------
423 | Reset (zero) public variables
424 | --------------------------------------------------------------------------- */
425 | void Cusers_logins::Reset()
426 | {
427 | sessid[0] = EOS;
428 | uagent[0] = EOS;
429 | ip[0] = EOS;
430 | user_id = 0;
431 | csrft[0] = EOS;
432 | created[0] = EOS;
433 | last_used[0] = EOS;
434 | }
435 |
--------------------------------------------------------------------------------
/lib/npp_usr.h:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------------------
2 |
3 | MIT License
4 |
5 | Copyright (c) 2020-2022 Jurek Muszynski (rekmus)
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
25 | -----------------------------------------------------------------------------
26 |
27 | Node++ Web App Engine
28 | Logged in users' functions
29 | nodepp.org
30 |
31 | -------------------------------------------------------------------------- */
32 |
33 | #ifndef NPP_USR_H
34 | #define NPP_USR_H
35 |
36 |
37 | /* --------------------------------------------------------------------------
38 | macros
39 | -------------------------------------------------------------------------- */
40 |
41 | #define NPP_PASSWD_HASH_BUFLEN 45 /* SHA256 digest in base64 + EOS */
42 |
43 |
44 | #define NPP_DB_UAGENT_LEN 250 /* User-Agent length stored in ulogins table */
45 | #define NPP_PASSWD_RESET_KEY_LEN 20 /* password reset key length */
46 |
47 |
48 | /* user status */
49 |
50 | #define USER_STATUS_INACTIVE (char)0
51 | #define USER_STATUS_ACTIVE (char)1
52 | #define USER_STATUS_LOCKED (char)2
53 | #define USER_STATUS_PASSWORD_CHANGE (char)3
54 | #define USER_STATUS_DELETED (char)9
55 |
56 |
57 | #define NPP_COMMON_PASSWORDS_FILE "passwords.txt"
58 |
59 |
60 |
61 | /* APP-configurable */
62 |
63 | #ifndef NPP_MIN_USERNAME_LEN
64 | #define NPP_MIN_USERNAME_LEN 2 /* minimum user name length */
65 | #endif
66 |
67 | #ifndef NPP_MIN_PASSWORD_LEN
68 | #define NPP_MIN_PASSWORD_LEN 5 /* minimum password length */
69 | #endif
70 |
71 | #ifndef MAX_ULA_BEFORE_FIRST_SLOW /* maximum unsuccessful login attempts before slowing down to 1 per minute */
72 | #define MAX_ULA_BEFORE_FIRST_SLOW 10
73 | #endif
74 |
75 | #ifndef MAX_ULA_BEFORE_SECOND_SLOW /* maximum unsuccessful login attempts before slowing down to 1 per hour */
76 | #define MAX_ULA_BEFORE_SECOND_SLOW 25
77 | #endif
78 |
79 | #ifndef MAX_ULA_BEFORE_THIRD_SLOW /* maximum unsuccessful login attempts before slowing down to 1 per day */
80 | #define MAX_ULA_BEFORE_THIRD_SLOW 100
81 | #endif
82 |
83 | #ifndef MAX_ULA_BEFORE_LOCK /* maximum unsuccessful login attempts before user lockout */
84 | #define MAX_ULA_BEFORE_LOCK 1000
85 | #endif
86 |
87 | #ifndef NPP_DEFAULT_USER_AUTH_LEVEL
88 | #define NPP_DEFAULT_USER_AUTH_LEVEL AUTH_LEVEL_USER /* default new user authorization level */
89 | #endif
90 |
91 | #ifndef NPP_USER_ACTIVATION_HOURS
92 | #define NPP_USER_ACTIVATION_HOURS 48 /* activate user account within */
93 | #endif
94 |
95 | #ifndef NPP_USER_KEEP_LOGGED_DAYS
96 | #define NPP_USER_KEEP_LOGGED_DAYS 30 /* ls cookie validity period */
97 | #endif
98 |
99 | #ifndef NPP_AUTH_SESSION_TIMEOUT
100 | #define NPP_AUTH_SESSION_TIMEOUT 1800 /* authenticated session timeout in seconds (120 for tests / 1800 live) */
101 | #endif /* (it's really how long it stays in cache) */
102 |
103 |
104 | #ifndef REFUSE_10_COMMON_PASSWORDS
105 | #ifndef REFUSE_100_COMMON_PASSWORDS
106 | #ifndef REFUSE_1000_COMMON_PASSWORDS
107 | #ifndef REFUSE_10000_COMMON_PASSWORDS
108 | #ifndef DONT_REFUSE_COMMON_PASSWORDS
109 | #define DONT_REFUSE_COMMON_PASSWORDS
110 | #endif
111 | #endif
112 | #endif
113 | #endif
114 | #endif
115 |
116 | /* passwords' peppers */
117 |
118 | #ifndef NPP_PEPPER_01
119 | #define NPP_PEPPER_01 "abcde"
120 | #endif
121 | #ifndef NPP_PEPPER_02
122 | #define NPP_PEPPER_02 "fghij"
123 | #endif
124 | #ifndef NPP_PEPPER_03
125 | #define NPP_PEPPER_03 "klmno"
126 | #endif
127 | #ifndef NPP_PEPPER_04
128 | #define NPP_PEPPER_04 "pqrst"
129 | #endif
130 | #ifndef NPP_PEPPER_05
131 | #define NPP_PEPPER_05 "uvwxy"
132 | #endif
133 |
134 |
135 | /* Node++ engine errors are 0 ... 99 */
136 |
137 | /* ------------------------------------- */
138 | /* errors -- red */
139 |
140 | /* login */
141 | #define ERR_INVALID_LOGIN 101
142 | #define ERR_USERNAME_TOO_SHORT 102
143 | #define ERR_USERNAME_CHARS 103
144 | #define ERR_USERNAME_TAKEN 104
145 | /* ------------------------------------- */
146 | #define ERR_MAX_USR_LOGIN_ERROR 110
147 | /* ------------------------------------- */
148 | /* email */
149 | #define ERR_EMAIL_EMPTY 111
150 | #define ERR_EMAIL_FORMAT 112
151 | #define ERR_EMAIL_FORMAT_OR_EMPTY 113
152 | #define ERR_EMAIL_TAKEN 114
153 | /* ------------------------------------- */
154 | #define ERR_MAX_USR_EMAIL_ERROR 120
155 | /* ------------------------------------- */
156 | /* password */
157 | #define ERR_INVALID_PASSWORD 121
158 | #define ERR_PASSWORD_TOO_SHORT 122
159 | #define ERR_IN_10_COMMON_PASSWORDS 123
160 | #define ERR_IN_100_COMMON_PASSWORDS 124
161 | #define ERR_IN_1000_COMMON_PASSWORDS 125
162 | #define ERR_IN_10000_COMMON_PASSWORDS 126
163 | /* ------------------------------------- */
164 | #define ERR_MAX_USR_PASSWORD_ERROR 130
165 | /* ------------------------------------- */
166 | /* repeat password */
167 | #define ERR_PASSWORD_DIFFERENT 131
168 | /* ------------------------------------- */
169 | #define ERR_MAX_USR_REPEAT_PASSWORD_ERROR 140
170 | /* ------------------------------------- */
171 | /* old password */
172 | #define ERR_OLD_PASSWORD 141
173 | /* ------------------------------------- */
174 | #define ERR_MAX_USR_OLD_PASSWORD_ERROR 150
175 | /* ------------------------------------- */
176 | /* session / link / other */
177 | #define ERR_SESSION_EXPIRED 151
178 | #define ERR_LINK_BROKEN 152
179 | #define ERR_LINK_MAY_BE_EXPIRED 153
180 | #define ERR_LINK_EXPIRED 154
181 | #define ERR_LINK_TOO_MANY_TRIES 155
182 | #define ERR_ROBOT 156
183 | #define ERR_WEBSITE_FIRST_LETTER 157
184 | #define ERR_NOT_ACTIVATED 158
185 | /* ------------------------------------- */
186 | #define ERR_MAX_USR_ERROR 199
187 | /* ------------------------------------- */
188 |
189 | /* ------------------------------------- */
190 | /* warnings -- yellow */
191 |
192 | #define WAR_NO_EMAIL 201
193 | #define WAR_BEFORE_DELETE 202
194 | #define WAR_ULA_FIRST 203
195 | #define WAR_ULA_SECOND 204
196 | #define WAR_ULA_THIRD 205
197 | #define WAR_PASSWORD_CHANGE 206
198 | /* ------------------------------------- */
199 | #define WAR_MAX_USR_WARNING 299
200 | /* ------------------------------------- */
201 |
202 | /* ------------------------------------- */
203 | /* messages -- green */
204 |
205 | #define MSG_WELCOME_NO_ACTIVATION 301
206 | #define MSG_WELCOME_NEED_ACTIVATION 302
207 | #define MSG_WELCOME_AFTER_ACTIVATION 303
208 | #define MSG_USER_LOGGED_OUT 304
209 | #define MSG_CHANGES_SAVED 305
210 | #define MSG_REQUEST_SENT 306
211 | #define MSG_PASSWORD_CHANGED 307
212 | #define MSG_MESSAGE_SENT 308
213 | #define MSG_PROVIDE_FEEDBACK 309
214 | #define MSG_FEEDBACK_SENT 310
215 | #define MSG_USER_ALREADY_ACTIVATED 311
216 | #define MSG_ACCOUNT_DELETED 312
217 | /* ------------------------------------- */
218 | #define MSG_MAX_USR_MESSAGE 399
219 | /* ------------------------------------- */
220 |
221 |
222 | #define MSG_CAT_USR_LOGIN "msgLogin"
223 | #define MSG_CAT_USR_EMAIL "msgEmail"
224 | #define MSG_CAT_USR_PASSWORD "msgPassword"
225 | #define MSG_CAT_USR_REPEAT_PASSWORD "msgPasswordRepeat"
226 | #define MSG_CAT_USR_OLD_PASSWORD "msgPasswordOld"
227 |
228 |
229 | /* user authentication */
230 |
231 | #ifndef NPP_USERS_BY_EMAIL
232 | #ifndef NPP_USERS_BY_LOGIN
233 | #define NPP_USERS_BY_LOGIN
234 | #endif
235 | #endif
236 |
237 |
238 | #define NPP_MAX_AVATAR_SIZE 65536 /* MySQL's BLOB size */
239 |
240 |
241 | #define SET_USER_STR(key, val) npp_usr_set_str(ci, key, val)
242 | #define SET_USR_STR(key, val) npp_usr_set_str(ci, key, val)
243 |
244 | #define GET_USER_STR(key, val) npp_usr_get_str(ci, key, val)
245 | #define GET_USR_STR(key, val) npp_usr_get_str(ci, key, val)
246 |
247 | #define SET_USER_INT(key, val) npp_usr_set_int(ci, key, val)
248 | #define SET_USR_INT(key, val) npp_usr_set_int(ci, key, val)
249 |
250 | #define GET_USER_INT(key, val) npp_usr_get_int(ci, key, val)
251 | #define GET_USR_INT(key, val) npp_usr_get_int(ci, key, val)
252 |
253 |
254 | /*
255 | Brute-force ls cookie attack protection.
256 | It essentially defines how many different IPs can take part in a botnet attack.
257 | */
258 |
259 | #ifdef NPP_MEM_TINY
260 | #define FAILED_LOGIN_CNT_SIZE 100
261 | #elif defined NPP_MEM_MEDIUM
262 | #define FAILED_LOGIN_CNT_SIZE 1000
263 | #elif defined NPP_MEM_LARGE
264 | #define FAILED_LOGIN_CNT_SIZE 10000
265 | #elif defined NPP_MEM_XLARGE
266 | #define FAILED_LOGIN_CNT_SIZE 10000
267 | #elif defined NPP_MEM_XXLARGE
268 | #define FAILED_LOGIN_CNT_SIZE 100000
269 | #elif defined NPP_MEM_XXXLARGE
270 | #define FAILED_LOGIN_CNT_SIZE 100000
271 | #elif defined NPP_MEM_XXXXLARGE
272 | #define FAILED_LOGIN_CNT_SIZE 100000
273 | #else /* NPP_MEM_SMALL -- default */
274 | #define FAILED_LOGIN_CNT_SIZE 1000
275 | #endif
276 |
277 |
278 |
279 | /* --------------------------------------------------------------------------
280 | structures
281 | -------------------------------------------------------------------------- */
282 |
283 | typedef struct {
284 | char ip[INET_ADDRSTRLEN];
285 | int cnt;
286 | time_t when;
287 | } failed_login_cnt_t;
288 |
289 |
290 |
291 | /* --------------------------------------------------------------------------
292 | prototypes
293 | -------------------------------------------------------------------------- */
294 |
295 | #ifdef NPP_CPP_STRINGS
296 | char *npp_usr_name(const char *login, const char *email, const char *name, int user_id);
297 | char *npp_usr_name(const std::string& login, const std::string& email, const std::string& name, int user_id);
298 |
299 | int npp_usr_get_str(int ci, const std::string& us_key, char *us_val);
300 | int npp_usr_get_str(int ci, const std::string& us_key, std::string& us_val);
301 | #endif
302 |
303 |
304 | #ifdef __cplusplus
305 | extern "C" {
306 | #endif
307 |
308 | int npp_usr_login(int ci);
309 |
310 | #ifdef NPP_CPP_STRINGS
311 | int npp_usr_password_quality(const std::string& passwd);
312 | #else
313 | int npp_usr_password_quality(const char *passwd);
314 | #endif
315 |
316 | int npp_usr_create_account(int ci);
317 |
318 | #ifdef NPP_CPP_STRINGS
319 | int npp_usr_add_user(int ci, bool use_qs, const std::string& login, const std::string& email, const std::string& name, const std::string& passwd, const std::string& phone, const std::string& lang, const std::string& about, char group_id, char auth_level, char status);
320 | #else
321 | int npp_usr_add_user(int ci, bool use_qs, const char *login, const char *email, const char *name, const char *passwd, const char *phone, const char *lang, const char *about, char group_id, char auth_level, char status);
322 | #endif
323 |
324 | int npp_usr_send_message(int ci);
325 | int npp_usr_save_account(int ci);
326 | int npp_usr_email_registered(int ci);
327 |
328 | #ifndef NPP_CPP_STRINGS
329 | char *npp_usr_name(const char *login, const char *email, const char *name, int user_id);
330 | #endif
331 |
332 | int npp_usr_send_passwd_reset_email(int ci);
333 |
334 | #ifdef NPP_CPP_STRINGS
335 | int npp_usr_verify_passwd_reset_key(int ci, const std::string& linkkey, int *user_id);
336 | #else
337 | int npp_usr_verify_passwd_reset_key(int ci, const char *linkkey, int *user_id);
338 | #endif
339 |
340 | int npp_usr_activate(int ci);
341 | int npp_usr_save_avatar(int ci, int user_id);
342 | int npp_usr_get_avatar(int ci, int user_id);
343 | int npp_usr_change_password(int ci);
344 | int npp_usr_reset_password(int ci);
345 | void npp_usr_logout(int ci);
346 |
347 | #ifdef NPP_CPP_STRINGS
348 | int npp_usr_set_str(int ci, const std::string& us_key, const std::string& us_val);
349 | #else
350 | int npp_usr_set_str(int ci, const char *us_key, const char *us_val);
351 | #endif
352 |
353 | #ifndef NPP_CPP_STRINGS
354 | int npp_usr_get_str(int ci, const char *us_key, char *us_val);
355 | #endif
356 |
357 | #ifdef NPP_CPP_STRINGS
358 | int npp_usr_set_int(int ci, const std::string& us_key, int us_val);
359 | #else
360 | int npp_usr_set_int(int ci, const char *us_key, int us_val);
361 | #endif
362 |
363 | #ifdef NPP_CPP_STRINGS
364 | int npp_usr_get_int(int ci, const std::string& us_key, int *us_val);
365 | #else
366 | int npp_usr_get_int(int ci, const char *us_key, int *us_val);
367 | #endif
368 |
369 | /* for the engine */
370 |
371 | void libusr_init(void);
372 | int libusr_luses_ok(int ci);
373 | void libusr_luses_close_timeouted(void);
374 | void libusr_luses_save_csrft(void);
375 | void libusr_luses_downgrade(int si, int ci, bool usr_logout);
376 |
377 | #ifdef __cplusplus
378 | } // extern "C"
379 | #endif
380 |
381 |
382 | #endif /* NPP_USR_H */
383 |
--------------------------------------------------------------------------------
/lib/Cusers.cpp:
--------------------------------------------------------------------------------
1 | /* ---------------------------------------------------------------------------
2 | Table access class
3 | Generated on nodepp.org on 2022-03-29 20:05:41, generator v.2.0.1
4 | Using C-style strings
5 | Using exceptions
6 | --------------------------------------------------------------------------- */
7 |
8 | #include "Cusers.h"
9 |
10 |
11 | bool Cusers::slots_[CDB_MAX_INSTANCES]={0};
12 |
13 |
14 | /* ---------------------------------------------------------------------------
15 | Constructor
16 | --------------------------------------------------------------------------- */
17 | Cusers::Cusers()
18 | {
19 | setInstance(slots_);
20 |
21 | table_ = "users";
22 |
23 | columnList_ = "id,"
24 | "login,"
25 | "login_u,"
26 | "email,"
27 | "email_u,"
28 | "name,"
29 | "phone,"
30 | "passwd1,"
31 | "passwd2,"
32 | "lang,"
33 | "about,"
34 | "group_id,"
35 | "auth_level,"
36 | "status,"
37 | "created,"
38 | "last_login,"
39 | "visits,"
40 | "ula_cnt,"
41 | "ula_time";
42 |
43 | if ( !(s_=mysql_stmt_init(dbConn_)) )
44 | ThrowSQL("mysql_stmt_init");
45 | if ( !(sc_=mysql_stmt_init(dbConn_)) )
46 | ThrowSQL("mysql_stmt_init");
47 | if ( !(sGet_=mysql_stmt_init(dbConn_)) )
48 | ThrowSQL("mysql_stmt_init");
49 | if ( !(sUpdate_=mysql_stmt_init(dbConn_)) )
50 | ThrowSQL("mysql_stmt_init");
51 | if ( !(sInsert_=mysql_stmt_init(dbConn_)) )
52 | ThrowSQL("mysql_stmt_init");
53 | if ( !(sDelete_=mysql_stmt_init(dbConn_)) )
54 | ThrowSQL("mysql_stmt_init");
55 | if ( !(sSet_=mysql_stmt_init(dbConn_)) )
56 | ThrowSQL("mysql_stmt_init");
57 |
58 | Reset();
59 | }
60 |
61 |
62 | /* ---------------------------------------------------------------------------
63 | Destructor
64 | --------------------------------------------------------------------------- */
65 | Cusers::~Cusers()
66 | {
67 | mysql_stmt_close(s_);
68 | mysql_stmt_close(sGet_);
69 | mysql_stmt_close(sUpdate_);
70 | mysql_stmt_close(sInsert_);
71 | mysql_stmt_close(sDelete_);
72 | mysql_stmt_close(sSet_);
73 |
74 | slots_[instance_] = false;
75 | }
76 |
77 |
78 | /* ---------------------------------------------------------------------------
79 | Get the next record
80 | Return false if end of record set
81 | --------------------------------------------------------------------------- */
82 | bool Cusers::Fetch()
83 | {
84 | int ret;
85 |
86 | ret = mysql_stmt_fetch(s_);
87 |
88 | if ( ret != 0 )
89 | {
90 | Reset();
91 |
92 | if ( ret == 1 || ret == MYSQL_NO_DATA )
93 | return false;
94 | else
95 | {
96 | Cdb::ThrowSQL("Cusers::Fetch | mysql_stmt_fetch");
97 | return false;
98 | }
99 | }
100 |
101 | genDTStrings();
102 |
103 | return true;
104 | }
105 |
106 |
107 | /* ---------------------------------------------------------------------------
108 | Get record by PK
109 | Not Found will return false
110 | --------------------------------------------------------------------------- */
111 | bool Cusers::Get(int arg_id)
112 | {
113 | int ret;
114 |
115 | if ( firstGet_ )
116 | {
117 | char q[CDB_SQLBUF];
118 | sprintf(q, "SELECT id,login,login_u,email,email_u,name,phone,passwd1,passwd2,lang,about,group_id,auth_level,status,created,last_login,visits,ula_cnt,ula_time FROM users WHERE id=?");
119 | ret = mysql_stmt_prepare(sGet_, q, strlen(q));
120 | if ( ret != 0 )
121 | Cdb::ThrowSQL("Cusers::Get | mysql_stmt_prepare");
122 | firstGet_ = false;
123 | }
124 |
125 | bindKey(sGet_, arg_id);
126 |
127 | if ( mysql_stmt_execute(sGet_) )
128 | Cdb::ThrowSQL("Cusers::Get | mysql_stmt_execute");
129 |
130 | bindOutput(sGet_);
131 |
132 | if ( mysql_stmt_store_result(sGet_) )
133 | Cdb::ThrowSQL("Cusers::Get | mysql_stmt_store_result");
134 |
135 | ret = mysql_stmt_fetch(sGet_);
136 |
137 | if ( ret != 0 )
138 | {
139 | if ( ret == 1 || ret == MYSQL_NO_DATA )
140 | return false;
141 | else
142 | Cdb::ThrowSQL("Cusers::Get | mysql_stmt_fetch");
143 | }
144 |
145 | genDTStrings();
146 |
147 | return true;
148 | }
149 |
150 |
151 | /* ---------------------------------------------------------------------------
152 | Insert record
153 | --------------------------------------------------------------------------- */
154 | unsigned Cusers::Insert()
155 | {
156 | int ret;
157 |
158 | if ( firstInsert_ )
159 | {
160 | char q[CDB_SQLBUF];
161 | sprintf(q, "INSERT INTO users (login,login_u,email,email_u,name,phone,passwd1,passwd2,lang,about,group_id,auth_level,status,created,last_login,visits,ula_cnt,ula_time) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
162 | ret = mysql_stmt_prepare(sInsert_, q, strlen(q));
163 | if ( ret != 0 )
164 | Cdb::ThrowSQL("Cusers::Insert | mysql_stmt_prepare");
165 | firstInsert_ = false;
166 | }
167 |
168 | bindInput(sInsert_);
169 |
170 | ret = mysql_stmt_execute(sInsert_);
171 |
172 | if ( ret != 0 )
173 | Cdb::ThrowSQL("Cusers::Insert | mysql_stmt_execute");
174 |
175 | id = mysql_insert_id(dbConn_);
176 |
177 | return id;
178 | }
179 |
180 |
181 | /* ---------------------------------------------------------------------------
182 | Update record by PK
183 | --------------------------------------------------------------------------- */
184 | void Cusers::Update(int arg_id)
185 | {
186 | int ret;
187 |
188 | if ( firstUpdate_ )
189 | {
190 | char q[CDB_SQLBUF];
191 | sprintf(q, "UPDATE users SET login=?,login_u=?,email=?,email_u=?,name=?,phone=?,passwd1=?,passwd2=?,lang=?,about=?,group_id=?,auth_level=?,status=?,created=?,last_login=?,visits=?,ula_cnt=?,ula_time=? WHERE id=?");
192 | ret = mysql_stmt_prepare(sUpdate_, q, strlen(q));
193 | if ( ret != 0 )
194 | Cdb::ThrowSQL("Cusers::Update | mysql_stmt_prepare");
195 | firstUpdate_ = false;
196 | }
197 |
198 | bindInput(sUpdate_, true, arg_id);
199 |
200 | ret = mysql_stmt_execute(sUpdate_);
201 |
202 | if ( ret != 0 )
203 | Cdb::ThrowSQL("Cusers::Update | mysql_stmt_execute");
204 | }
205 |
206 |
207 | /* ---------------------------------------------------------------------------
208 | Delete record by PK
209 | --------------------------------------------------------------------------- */
210 | void Cusers::Delete(int arg_id)
211 | {
212 | int ret;
213 |
214 | if ( firstDelete_ )
215 | {
216 | char q[CDB_SQLBUF];
217 | sprintf(q, "DELETE FROM users WHERE id=?");
218 | ret = mysql_stmt_prepare(sDelete_, q, strlen(q));
219 | if ( ret != 0 )
220 | Cdb::ThrowSQL("Cusers::Delete | mysql_stmt_prepare");
221 | firstDelete_ = false;
222 | }
223 |
224 | bindKey(sDelete_, arg_id);
225 |
226 | ret = mysql_stmt_execute(sDelete_);
227 |
228 | if ( ret != 0 )
229 | Cdb::ThrowSQL("Cusers::Delete | mysql_stmt_execute");
230 | }
231 |
232 |
233 | /* ---------------------------------------------------------------------------
234 | Insert or update record by PK
235 | --------------------------------------------------------------------------- */
236 | void Cusers::Set(int arg_id)
237 | {
238 | int ret;
239 |
240 | if ( firstSet_ )
241 | {
242 | char q[CDB_SQLBUF];
243 | sprintf(q, "SELECT id FROM users WHERE id=?");
244 | ret = mysql_stmt_prepare(sSet_, q, strlen(q));
245 | if ( ret != 0 )
246 | Cdb::ThrowSQL("Cusers::Set | mysql_stmt_prepare");
247 | firstSet_ = false;
248 | }
249 |
250 | bindKey(sSet_, arg_id);
251 |
252 | if ( mysql_stmt_execute(sSet_) )
253 | Cdb::ThrowSQL("Cusers::Set | mysql_stmt_execute");
254 |
255 | bindSetOutput();
256 |
257 | if ( mysql_stmt_store_result(sSet_) )
258 | Cdb::ThrowSQL("Cusers::Set | mysql_stmt_store_result");
259 |
260 | ret = mysql_stmt_fetch(sSet_);
261 |
262 | if ( ret == 0 ) /* record existed */
263 | {
264 | Update(arg_id);
265 | }
266 | else if ( ret == 1 || ret == MYSQL_NO_DATA ) /* not found ==> insert new */
267 | {
268 | id = arg_id;
269 |
270 | Insert();
271 | }
272 | else
273 | Cdb::ThrowSQL("Cusers::Set | mysql_stmt_fetch");
274 | }
275 |
276 |
277 | /* ---------------------------------------------------------------------------
278 | Bind key values
279 | --------------------------------------------------------------------------- */
280 | void Cusers::bindKey(MYSQL_STMT *s, int arg_id)
281 | {
282 | k_id_ = arg_id;
283 |
284 | memset(&bndk_, 0, sizeof(bndk_));
285 |
286 | bndk_[0].buffer_type = MYSQL_TYPE_LONG;
287 | bndk_[0].buffer = (char*)&k_id_;
288 |
289 | if ( mysql_stmt_bind_param(s, bndk_) )
290 | Cdb::ThrowSQL("Cusers::bindKey | mysql_stmt_bind_param");
291 | }
292 |
293 |
294 | /* ---------------------------------------------------------------------------
295 | Bind input values
296 | --------------------------------------------------------------------------- */
297 | void Cusers::bindInput(MYSQL_STMT *s, bool withKey, int arg_id)
298 | {
299 | login_len_ = strlen(login);
300 | login_u_len_ = strlen(login_u);
301 | email_len_ = strlen(email);
302 | email_u_len_ = strlen(email_u);
303 | name_len_ = strlen(name);
304 | phone_len_ = strlen(phone);
305 | passwd1_len_ = strlen(passwd1);
306 | passwd2_len_ = strlen(passwd2);
307 | lang_len_ = strlen(lang);
308 | about_len_ = strlen(about);
309 |
310 | set_datetime(&t_created_, created);
311 | set_datetime(&t_last_login_, last_login);
312 | set_datetime(&t_ula_time_, ula_time);
313 |
314 | memset(&bndi_, 0, sizeof(bndi_));
315 |
316 | bndi_[0].buffer_type = MYSQL_TYPE_STRING;
317 | bndi_[0].buffer = (char*)login;
318 | bndi_[0].length = &login_len_;
319 |
320 | bndi_[1].buffer_type = MYSQL_TYPE_STRING;
321 | bndi_[1].buffer = (char*)login_u;
322 | bndi_[1].length = &login_u_len_;
323 |
324 | bndi_[2].buffer_type = MYSQL_TYPE_STRING;
325 | bndi_[2].buffer = (char*)email;
326 | bndi_[2].length = &email_len_;
327 |
328 | bndi_[3].buffer_type = MYSQL_TYPE_STRING;
329 | bndi_[3].buffer = (char*)email_u;
330 | bndi_[3].length = &email_u_len_;
331 |
332 | bndi_[4].buffer_type = MYSQL_TYPE_STRING;
333 | bndi_[4].buffer = (char*)name;
334 | bndi_[4].length = &name_len_;
335 |
336 | bndi_[5].buffer_type = MYSQL_TYPE_STRING;
337 | bndi_[5].buffer = (char*)phone;
338 | bndi_[5].length = &phone_len_;
339 |
340 | bndi_[6].buffer_type = MYSQL_TYPE_STRING;
341 | bndi_[6].buffer = (char*)passwd1;
342 | bndi_[6].length = &passwd1_len_;
343 |
344 | bndi_[7].buffer_type = MYSQL_TYPE_STRING;
345 | bndi_[7].buffer = (char*)passwd2;
346 | bndi_[7].length = &passwd2_len_;
347 |
348 | bndi_[8].buffer_type = MYSQL_TYPE_STRING;
349 | bndi_[8].buffer = (char*)lang;
350 | bndi_[8].length = &lang_len_;
351 |
352 | bndi_[9].buffer_type = MYSQL_TYPE_STRING;
353 | bndi_[9].buffer = (char*)about;
354 | bndi_[9].length = &about_len_;
355 |
356 | bndi_[10].buffer_type = MYSQL_TYPE_LONG;
357 | bndi_[10].buffer = (char*)&group_id;
358 |
359 | bndi_[11].buffer_type = MYSQL_TYPE_TINY;
360 | bndi_[11].buffer = (char*)&auth_level;
361 |
362 | bndi_[12].buffer_type = MYSQL_TYPE_TINY;
363 | bndi_[12].buffer = (char*)&status;
364 |
365 | bndi_[13].buffer_type = MYSQL_TYPE_DATETIME;
366 | bndi_[13].buffer = (char*)&t_created_;
367 |
368 | bndi_[14].buffer_type = MYSQL_TYPE_DATETIME;
369 | bndi_[14].buffer = (char*)&t_last_login_;
370 |
371 | bndi_[15].buffer_type = MYSQL_TYPE_LONG;
372 | bndi_[15].buffer = (char*)&visits;
373 |
374 | bndi_[16].buffer_type = MYSQL_TYPE_LONG;
375 | bndi_[16].buffer = (char*)&ula_cnt;
376 |
377 | bndi_[17].buffer_type = MYSQL_TYPE_DATETIME;
378 | bndi_[17].buffer = (char*)&t_ula_time_;
379 |
380 | if ( withKey ) /* after WHERE */
381 | {
382 | k_id_ = arg_id;
383 |
384 | bndi_[18].buffer_type = MYSQL_TYPE_LONG;
385 | bndi_[18].buffer = (char*)&k_id_;
386 |
387 | }
388 |
389 | if ( mysql_stmt_bind_param(s, bndi_) )
390 | Cdb::ThrowSQL("Cusers::bindInput | mysql_stmt_bind_param");
391 | }
392 |
393 |
394 | /* ---------------------------------------------------------------------------
395 | Bind output values
396 | --------------------------------------------------------------------------- */
397 | void Cusers::bindOutput(MYSQL_STMT *s)
398 | {
399 | memset(&bndo_, 0, sizeof(bndo_));
400 |
401 | bndo_[0].buffer_type = MYSQL_TYPE_LONG;
402 | bndo_[0].buffer = (char*)&id;
403 | bndo_[0].is_null = &id_is_null_;
404 |
405 | bndo_[1].buffer_type = MYSQL_TYPE_STRING;
406 | bndo_[1].buffer = (char*)login;
407 | bndo_[1].buffer_length = 31;
408 | bndo_[1].is_null = &login_is_null_;
409 |
410 | bndo_[2].buffer_type = MYSQL_TYPE_STRING;
411 | bndo_[2].buffer = (char*)login_u;
412 | bndo_[2].buffer_length = 31;
413 | bndo_[2].is_null = &login_u_is_null_;
414 |
415 | bndo_[3].buffer_type = MYSQL_TYPE_STRING;
416 | bndo_[3].buffer = (char*)email;
417 | bndo_[3].buffer_length = 121;
418 | bndo_[3].is_null = &email_is_null_;
419 |
420 | bndo_[4].buffer_type = MYSQL_TYPE_STRING;
421 | bndo_[4].buffer = (char*)email_u;
422 | bndo_[4].buffer_length = 121;
423 | bndo_[4].is_null = &email_u_is_null_;
424 |
425 | bndo_[5].buffer_type = MYSQL_TYPE_STRING;
426 | bndo_[5].buffer = (char*)name;
427 | bndo_[5].buffer_length = 121;
428 | bndo_[5].is_null = &name_is_null_;
429 |
430 | bndo_[6].buffer_type = MYSQL_TYPE_STRING;
431 | bndo_[6].buffer = (char*)phone;
432 | bndo_[6].buffer_length = 31;
433 | bndo_[6].is_null = &phone_is_null_;
434 |
435 | bndo_[7].buffer_type = MYSQL_TYPE_STRING;
436 | bndo_[7].buffer = (char*)passwd1;
437 | bndo_[7].buffer_length = 45;
438 | bndo_[7].is_null = &passwd1_is_null_;
439 |
440 | bndo_[8].buffer_type = MYSQL_TYPE_STRING;
441 | bndo_[8].buffer = (char*)passwd2;
442 | bndo_[8].buffer_length = 45;
443 | bndo_[8].is_null = &passwd2_is_null_;
444 |
445 | bndo_[9].buffer_type = MYSQL_TYPE_STRING;
446 | bndo_[9].buffer = (char*)lang;
447 | bndo_[9].buffer_length = 6;
448 | bndo_[9].is_null = &lang_is_null_;
449 |
450 | bndo_[10].buffer_type = MYSQL_TYPE_STRING;
451 | bndo_[10].buffer = (char*)about;
452 | bndo_[10].buffer_length = 251;
453 | bndo_[10].is_null = &about_is_null_;
454 |
455 | bndo_[11].buffer_type = MYSQL_TYPE_LONG;
456 | bndo_[11].buffer = (char*)&group_id;
457 | bndo_[11].is_null = &group_id_is_null_;
458 |
459 | bndo_[12].buffer_type = MYSQL_TYPE_TINY;
460 | bndo_[12].buffer = (char*)&auth_level;
461 | bndo_[12].is_null = &auth_level_is_null_;
462 |
463 | bndo_[13].buffer_type = MYSQL_TYPE_TINY;
464 | bndo_[13].buffer = (char*)&status;
465 | bndo_[13].is_null = &status_is_null_;
466 |
467 | bndo_[14].buffer_type = MYSQL_TYPE_DATETIME;
468 | bndo_[14].buffer = (char*)&t_created_;
469 | bndo_[14].is_null = &created_is_null_;
470 |
471 | bndo_[15].buffer_type = MYSQL_TYPE_DATETIME;
472 | bndo_[15].buffer = (char*)&t_last_login_;
473 | bndo_[15].is_null = &last_login_is_null_;
474 |
475 | bndo_[16].buffer_type = MYSQL_TYPE_LONG;
476 | bndo_[16].buffer = (char*)&visits;
477 | bndo_[16].is_null = &visits_is_null_;
478 |
479 | bndo_[17].buffer_type = MYSQL_TYPE_LONG;
480 | bndo_[17].buffer = (char*)&ula_cnt;
481 | bndo_[17].is_null = &ula_cnt_is_null_;
482 |
483 | bndo_[18].buffer_type = MYSQL_TYPE_DATETIME;
484 | bndo_[18].buffer = (char*)&t_ula_time_;
485 | bndo_[18].is_null = &ula_time_is_null_;
486 |
487 | if ( mysql_stmt_bind_result(s, bndo_) )
488 | Cdb::ThrowSQL("Cusers::bindOutput | mysql_stmt_bind_result");
489 | }
490 |
491 |
492 | /* ---------------------------------------------------------------------------
493 | Bind output value for Set
494 | --------------------------------------------------------------------------- */
495 | void Cusers::bindSetOutput()
496 | {
497 | static int id; /* to be scrapped anyway */
498 |
499 | memset(&bndso_, 0, sizeof(bndso_));
500 |
501 | bndso_[0].buffer_type = MYSQL_TYPE_LONG;
502 | bndso_[0].buffer = (char*)&id;
503 |
504 | if ( mysql_stmt_bind_result(sSet_, bndso_) )
505 | Cdb::ThrowSQL("Cusers::bindSetOutput | mysql_stmt_bind_result");
506 | }
507 |
508 |
509 | /* ---------------------------------------------------------------------------
510 | Generate date-time strings
511 | --------------------------------------------------------------------------- */
512 | void Cusers::genDTStrings()
513 | {
514 | if ( created_is_null_ )
515 | created[0] = EOS;
516 | else
517 | sprintf(created, "%04d-%02d-%02d %02d:%02d:%02d", t_created_.year, t_created_.month, t_created_.day, t_created_.hour, t_created_.minute, t_created_.second);
518 |
519 | if ( last_login_is_null_ )
520 | last_login[0] = EOS;
521 | else
522 | sprintf(last_login, "%04d-%02d-%02d %02d:%02d:%02d", t_last_login_.year, t_last_login_.month, t_last_login_.day, t_last_login_.hour, t_last_login_.minute, t_last_login_.second);
523 |
524 | if ( ula_time_is_null_ )
525 | ula_time[0] = EOS;
526 | else
527 | sprintf(ula_time, "%04d-%02d-%02d %02d:%02d:%02d", t_ula_time_.year, t_ula_time_.month, t_ula_time_.day, t_ula_time_.hour, t_ula_time_.minute, t_ula_time_.second);
528 |
529 | }
530 |
531 |
532 | /* ---------------------------------------------------------------------------
533 | Reset (zero) public variables
534 | --------------------------------------------------------------------------- */
535 | void Cusers::Reset()
536 | {
537 | id = 0;
538 | login[0] = EOS;
539 | login_u[0] = EOS;
540 | email[0] = EOS;
541 | email_u[0] = EOS;
542 | name[0] = EOS;
543 | phone[0] = EOS;
544 | passwd1[0] = EOS;
545 | passwd2[0] = EOS;
546 | lang[0] = EOS;
547 | about[0] = EOS;
548 | group_id = 0;
549 | auth_level = 0;
550 | status = 0;
551 | created[0] = EOS;
552 | last_login[0] = EOS;
553 | visits = 0;
554 | ula_cnt = 0;
555 | ula_time[0] = EOS;
556 | }
557 |
--------------------------------------------------------------------------------
/lib/npp_update.c:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------------------
2 |
3 | MIT License
4 |
5 | Copyright (c) 2020-2022 Jurek Muszynski (rekmus)
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
25 | -----------------------------------------------------------------------------
26 |
27 | Node++ Web App Engine
28 | Update Node++ lib
29 | nodepp.org
30 |
31 | -------------------------------------------------------------------------- */
32 |
33 |
34 | #include "npp.h"
35 | #include
36 |
37 |
38 | static bool M_force_update=FALSE;
39 | static bool M_test=FALSE;
40 | static bool M_update=FALSE;
41 |
42 | static int M_local_major=0;
43 | static int M_local_minor=0;
44 | static int M_local_patch=0;
45 |
46 | static int M_latest_major=0;
47 | static int M_latest_minor=0;
48 | static int M_latest_patch=0;
49 |
50 | static JSON M_j={0};
51 |
52 |
53 | /* --------------------------------------------------------------------------
54 | Parse command line
55 | -------------------------------------------------------------------------- */
56 | static int parse_command_line(int argc, char *argv[])
57 | {
58 | int c;
59 |
60 | while ( (c=getopt(argc, argv, "ftu")) != -1 )
61 | switch (c)
62 | {
63 | case 'f':
64 | M_force_update = TRUE;
65 | break;
66 | case 't':
67 | // M_test = TRUE;
68 | break;
69 | case 'u':
70 | M_update = TRUE;
71 | break;
72 | case '?':
73 | if ( optopt == 'c' )
74 | fprintf(stderr, "Option -%c requires an argument.\n", optopt);
75 | else if ( isprint(optopt) )
76 | fprintf(stderr, "Unknown option `-%c'.\n", optopt);
77 | else
78 | fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
79 | return FAIL;
80 | default:
81 | return FAIL;
82 | }
83 |
84 | return OK;
85 | }
86 |
87 |
88 | /* --------------------------------------------------------------------------
89 | Parse version string
90 | -------------------------------------------------------------------------- */
91 | static int parse_verstr(const char *str, int *major, int *minor, int *patch)
92 | {
93 | sscanf(str, "%d.%d.%d", major, minor, patch);
94 | DDBG("%d %d %d", *major, *minor, *patch);
95 | return OK;
96 | }
97 |
98 |
99 | /* --------------------------------------------------------------------------
100 | Check local Node++ version
101 | -------------------------------------------------------------------------- */
102 | static int check_local_version()
103 | {
104 | int ret=OK;
105 |
106 | DDBG("Opening npp.h...");
107 |
108 | char npp_h[512];
109 |
110 | #ifdef _WIN32
111 | sprintf(npp_h, "%s\\lib\\npp.h", G_appdir);
112 | HANDLE fd;
113 | #else /* Linux */
114 | sprintf(npp_h, "%s/lib/npp.h", G_appdir);
115 | FILE *fd;
116 | #endif
117 | int fsize;
118 |
119 | #ifdef _WIN32
120 |
121 | fd = CreateFile(TEXT(npp_h), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
122 |
123 | if ( fd == INVALID_HANDLE_VALUE )
124 | {
125 | ERR("Couldn't open npp.h");
126 | return FAIL;
127 | }
128 |
129 | /* 64-bit integers complicated by Microsoft... */
130 |
131 | LARGE_INTEGER li_fsize;
132 |
133 | if ( !GetFileSizeEx(fd, &li_fsize) )
134 | {
135 | ERR("Couldn't read npp.h's size");
136 | CloseHandle(fd);
137 | return FAIL;
138 | }
139 |
140 | fsize = li_fsize.QuadPart;
141 |
142 | #else /* Linux */
143 |
144 | if ( NULL == (fd=fopen(npp_h, "r")) )
145 | {
146 | ERR("Couldn't open npp.h");
147 | return FAIL;
148 | }
149 |
150 | fseek(fd, 0, SEEK_END); /* determine the file size */
151 |
152 | fsize = ftell(fd);
153 |
154 | rewind(fd);
155 |
156 | #endif
157 |
158 | /* read file into the buffer */
159 |
160 | char *data;
161 |
162 | if ( !(data=(char*)malloc(fsize+1)) )
163 | {
164 | ERR("Couldn't allocate %lld bytes for buffer", fsize+1);
165 | #ifdef _WIN32
166 | CloseHandle(fd);
167 | #else /* Linux */
168 | fclose(fd);
169 | #endif
170 | return FAIL;
171 | }
172 |
173 | #ifdef _WIN32
174 | DWORD bytes;
175 | if ( !ReadFile(fd, data, fsize, &bytes, NULL) )
176 | #else /* Linux */
177 | if ( fread(data, fsize, 1, fd) != 1 )
178 | #endif
179 | {
180 | ERR("Couldn't read from npp.h");
181 | free(data);
182 | #ifdef _WIN32
183 | CloseHandle(fd);
184 | #else /* Linux */
185 | fclose(fd);
186 | #endif
187 | return FAIL;
188 | }
189 |
190 | #ifdef _WIN32
191 | CloseHandle(fd);
192 | #else /* Linux */
193 | fclose(fd);
194 | #endif
195 |
196 | /* ---------------------------------------------- */
197 |
198 | data[fsize] = EOS;
199 |
200 | /* ---------------------------------------------- */
201 |
202 | char *p_verstr = strstr(data, "NPP_VERSION");
203 |
204 | if ( !p_verstr )
205 | {
206 | ERR("Couldn't find NPP_VERSION in npp.h");
207 | free(data);
208 | return FAIL;
209 | }
210 |
211 | p_verstr += 12;
212 |
213 | int count = p_verstr - data;
214 | char *c=p_verstr;
215 |
216 | while ( *c != '"' && count < fsize )
217 | {
218 | ++c;
219 | ++count;
220 | }
221 |
222 | ++c; /* skip '"' */
223 |
224 | char verstr[32];
225 | int i=0;
226 |
227 | while ( *c != '"' && i < 31 && count < fsize )
228 | {
229 | verstr[i++] = *c++;
230 | ++count;
231 | }
232 |
233 | verstr[i] = EOS;
234 |
235 | DDBG("verstr [%s]", verstr);
236 |
237 | /* ---------------------------------------------- */
238 |
239 | free(data);
240 |
241 | /* ---------------------------------------------- */
242 |
243 | ret = parse_verstr(verstr, &M_local_major, &M_local_minor, &M_local_patch);
244 |
245 | /* ---------------------------------------------- */
246 |
247 | return ret;
248 | }
249 |
250 |
251 | /* --------------------------------------------------------------------------
252 | Check latest Node++ version
253 | -------------------------------------------------------------------------- */
254 | static int check_latest_version()
255 | {
256 | int ret=OK;
257 | char url[1024];
258 | char data[NPP_JSON_BUFSIZE];
259 |
260 | #ifdef NPP_HTTPS
261 | sprintf(url, "https://nodepp.org/api/v2/update_info");
262 | #else
263 | sprintf(url, "http://nodepp.org/api/v2/update_info");
264 | #endif
265 |
266 | if ( !CALL_HTTP(NULL, &data, "GET", url, FALSE) )
267 | {
268 | ERR("Couldn't connect to nodepp.org");
269 | return FAIL;
270 | }
271 | else if ( CALL_HTTP_STATUS != 200 )
272 | {
273 | ERR("Couldn't get update_info from nodepp.org, status = %d", CALL_HTTP_STATUS);
274 | return FAIL;
275 | }
276 |
277 | data[CALL_HTTP_RESPONSE_LEN] = EOS;
278 |
279 | DDBG("data [%s]", data);
280 |
281 | if ( !JSON_FROM_STRING(&M_j, data) )
282 | {
283 | ERR("Couldn't parse response as JSON");
284 | return FAIL;
285 | }
286 |
287 | DBG("parsed pretty: [%s]", JSON_TO_STRING_PRETTY(&M_j));
288 |
289 | char verstr[32];
290 |
291 | #ifdef NPP_JSON_V1
292 | COPY(verstr, JSON_GET_STR(&M_j, "version"), 31);
293 | #else
294 | if ( !JSON_GET_STR(&M_j, "version", verstr, 31) )
295 | {
296 | ERR("Couldn't find version in response");
297 | return FAIL;
298 | }
299 | #endif
300 | ret = parse_verstr(verstr, &M_latest_major, &M_latest_minor, &M_latest_patch);
301 |
302 | return ret;
303 | }
304 |
305 |
306 | /* --------------------------------------------------------------------------
307 | Update
308 | -------------------------------------------------------------------------- */
309 | static int update_lib()
310 | {
311 | ALWAYS("Updating Node++ lib...");
312 |
313 | JSON j_files={0};
314 |
315 | if ( !JSON_GET_ARRAY(&M_j, "files", &j_files) )
316 | {
317 | ERR("Couldn't get file list from the response");
318 | return FAIL;
319 | }
320 |
321 | int cnt=JSON_COUNT(&j_files);
322 |
323 | INF("%d files to update", cnt);
324 |
325 | int i;
326 | char path[NPP_JSON_STR_LEN+1];
327 | char fname[128];
328 | char url[512];
329 | static char data[CALL_HTTP_MAX_RESPONSE_LEN];
330 | FILE *fd;
331 |
332 | for ( i=0; i M_local_major
571 | || (M_latest_major == M_local_major && M_latest_minor > M_local_minor)
572 | || (M_latest_major == M_local_major && M_latest_minor == M_local_minor && M_latest_patch > M_local_patch)) )
573 | {
574 | if ( M_update )
575 | {
576 | if ( M_latest_major > M_local_major && !M_force_update ) /* confirmation required */
577 | {
578 | printf("Major version has changed. It may be incompatible with your app code. Are you sure you want to proceed [y/N]? ");
579 |
580 | int answer = getchar();
581 |
582 | if ( answer != '\n' )
583 | {
584 | int c;
585 | while ( (c=getchar()) != '\n') continue;
586 | DDBG("c = '%c'", c);
587 | }
588 |
589 | DDBG("answer = '%c'", answer);
590 |
591 | if ( answer == 'y' || answer == 'Y' )
592 | ret = update_lib();
593 |
594 | ALWAYS("To remove prompt add -f option to force update");
595 | }
596 | else
597 | ret = update_lib();
598 | }
599 | else /* info only */
600 | {
601 | ALWAYS("Add -u option to update");
602 | }
603 | }
604 | else /* same version */
605 | {
606 | ALWAYS("");
607 | ALWAYS("Nothing to update.");
608 | }
609 | }
610 |
611 | ALWAYS("");
612 | ALWAYS("More info: nodepp.org");
613 | #ifndef _WIN32
614 | ALWAYS("");
615 | #endif
616 |
617 | npp_lib_done();
618 |
619 | if ( ret != OK )
620 | return EXIT_FAILURE;
621 |
622 | return EXIT_SUCCESS;
623 | }
624 |
--------------------------------------------------------------------------------