@ind-rcg/backend 246.1008.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE.md +37 -0
  2. package/README.md +7 -0
  3. package/bin/libsqliteExtension.dll +0 -0
  4. package/bin/libsqliteExtension.dylib +0 -0
  5. package/binding.gyp +21 -0
  6. package/configuration.template.json +24 -0
  7. package/log4js.json +11 -0
  8. package/nativeSrc/PriceEngineWrap.cc +157 -0
  9. package/nativeSrc/PriceEngineWrap.h +24 -0
  10. package/nativeSrc/common/DBAccess/SimpleDBConnection.cpp +800 -0
  11. package/nativeSrc/common/DBAccess/SimpleDBConnection.h +54 -0
  12. package/nativeSrc/common/Libs/cJSON/CHANGELOG.md +428 -0
  13. package/nativeSrc/common/Libs/cJSON/LICENSE +20 -0
  14. package/nativeSrc/common/Libs/cJSON/README.md +571 -0
  15. package/nativeSrc/common/Libs/cJSON/cJSON.c +3110 -0
  16. package/nativeSrc/common/Libs/cJSON/cJSON.h +293 -0
  17. package/nativeSrc/common/Libs/sqlcipher/sqlite3.c +241624 -0
  18. package/nativeSrc/common/Libs/sqlcipher/sqlite3.h +12836 -0
  19. package/nativeSrc/common/Libs/sqlcipher/sqlite3ext.h +701 -0
  20. package/nativeSrc/common/LogAdapter/LogAdapter.cpp +25 -0
  21. package/nativeSrc/common/LogAdapter/LogAdapter.h +20 -0
  22. package/nativeSrc/common/PriceEngine/PriceEngine.cpp +251 -0
  23. package/nativeSrc/common/PriceEngine/PriceEngine.h +67 -0
  24. package/nativeSrc/common/Utils/StringFormat.cpp +905 -0
  25. package/nativeSrc/common/Utils/StringFormat.h +116 -0
  26. package/nativeSrc/common/Utils/miniz/timer.cpp +165 -0
  27. package/nativeSrc/common/Utils/miniz/timer.h +40 -0
  28. package/nativeSrc/common/stdngm.h +92 -0
  29. package/nativeSrc/nativeWrapper.cc +15 -0
  30. package/package.json +70 -0
  31. package/src/argsParser.js +73 -0
  32. package/src/bootstrap.js +156 -0
  33. package/src/fsHelper.js +36 -0
  34. package/src/globalConfig.js +23 -0
  35. package/src/local.js +546 -0
  36. package/src/server.js +64 -0
  37. package/src/sfAttachmentsHandler.js +283 -0
  38. package/src/utils.js +91 -0
  39. package/src/zipHandler.js +153 -0
@@ -0,0 +1,25 @@
1
+ /*
2
+ * FILE_HEADER
3
+ */
4
+
5
+ #include "../stdngm.h"
6
+ #include "LogAdapter.h"
7
+ #include "../Utils/StringFormat.h"
8
+
9
+ static std::vector<std::string> logMessages;
10
+
11
+ void LogAdapter::Console(const char *text)
12
+ {
13
+ logMessages.push_back(text);
14
+ }
15
+
16
+ std::vector<std::string> LogAdapter::getInternalLogLines()
17
+ {
18
+ std::vector<std::string>logs = logMessages;
19
+ logMessages.clear();
20
+ return logs;
21
+ }
22
+
23
+ bool LogAdapter::logConsole() { return true; }
24
+ bool LogAdapter::logDebug() { return true; }
25
+ bool LogAdapter::logPerformance() { return true; }
@@ -0,0 +1,20 @@
1
+ /*
2
+ * FILE_HEADER
3
+ */
4
+
5
+ #ifndef NGM_LOG_ADAPTER_H
6
+ #define NGM_LOG_ADAPTER_H
7
+
8
+ #include "../stdngm.h"
9
+
10
+ class LogAdapter {
11
+ public:
12
+ static void Console(const char *text);
13
+ static std::vector<std::string> getInternalLogLines();
14
+
15
+ // same function getting used in mobile side
16
+ static bool logConsole();
17
+ static bool logDebug();
18
+ static bool logPerformance();
19
+ };
20
+ #endif
@@ -0,0 +1,251 @@
1
+ //
2
+ // PriceEngine.cpp
3
+ // NGM
4
+ //
5
+ // Created by Yanbo on 29/05/14.
6
+ /*
7
+ * FILE_HEADER
8
+ */
9
+
10
+ #include "PriceEngine.h"
11
+ #include "../Utils/miniz/timer.h"
12
+ #include "../Utils/StringFormat.h"
13
+ #include "../LogAdapter/LogAdapter.h"
14
+
15
+ char *PriceEngine::conditionSearch(char* jRequest)
16
+ {
17
+ bool bParseReq = false;
18
+ std::string json_req;
19
+ if (jRequest == NULL || strlen(jRequest) == 0) {
20
+ if (LogAdapter::logConsole()) LogAdapter::Console("The condition is empty. Specify valid values and try the request again.");
21
+ return NULL;
22
+ }
23
+
24
+ //check whether request is starting with space or new line
25
+ if(jRequest[0] == ' ' || jRequest[0] == '\n' || jRequest[0] == '\t') {
26
+ if (LogAdapter::logConsole()) LogAdapter::Console("Looks like there is a leading whitespace in the request. Remove the whitespace, then pass the request.");
27
+ return NULL;
28
+ }
29
+
30
+ if (jRequest[0] == '{') {
31
+ json_req = jRequest;
32
+ }
33
+ else if (jRequest[0] == '[') {
34
+ json_req = "{ \"req\" :"; json_req.append(jRequest); json_req.append("}");
35
+ }
36
+ else {
37
+ json_req = "{"; json_req.append(jRequest); json_req.append("}");
38
+ }
39
+ //Parse the request
40
+
41
+ /* Performance optimization done:
42
+ * cJSON is slow when using the index to read an item from an array while iterating it.
43
+ * This is the case because cJSON reads an index by iterating through the array from the beginning.
44
+ * To work around this the "next" pointer of the array item is used to get the next item until there is no next item.
45
+ */
46
+
47
+ m_Request = cJSON_Parse(json_req.c_str());
48
+ if (!m_Request){
49
+ if (LogAdapter::logConsole()) LogAdapter::Console("The JSON input couldn't be parsed. Specify valid search values and try again.");
50
+ return NULL;
51
+ }
52
+ if(m_Request->child == NULL){
53
+ cJSON_Delete(m_Request);
54
+ m_Request = NULL;
55
+ if (LogAdapter::logConsole()) LogAdapter::Console("Something went wrong. Try passing the request again or contact Salesforce Support for help.");
56
+ return NULL;
57
+ }
58
+ cJSON* root = m_Request->child;
59
+ if (root->type == cJSON_Array) {
60
+ cJSON* jsr = cJSON_GetArrayItem(root, 0);
61
+ while (jsr != NULL && jsr->child != NULL) {
62
+ // SearchRequest.
63
+ SearchRequest sr;
64
+ sr.ConditionKey = jsr->child;
65
+ cJSON* jsreq = jsr->child->next;
66
+ if (jsreq->type == cJSON_Array) {
67
+ cJSON* jSSReq = cJSON_GetArrayItem(jsreq, 0);
68
+ while (jSSReq != NULL) {
69
+ //get SR search steps.
70
+ SearchStepsRequest ssReq;
71
+ ssReq.Exclusive = cJSON_GetArrayItem(jSSReq, 1);
72
+ ssReq.KeyType = cJSON_GetArrayItem(jSSReq, 0);
73
+ cJSON* jMergeKeys = cJSON_GetArrayItem(jSSReq, 2);
74
+ if (jMergeKeys->type == cJSON_Array) {
75
+ cJSON* mergedKey = cJSON_GetArrayItem(jMergeKeys, 0);
76
+ while (mergedKey != NULL) {
77
+ if (!bParseReq) bParseReq = true;
78
+ ssReq.MergedKeys.push_back(mergedKey);
79
+ mergedKey = mergedKey->next;
80
+ }
81
+ }
82
+ sr.SearchSteps.push_back(ssReq);
83
+ jSSReq = jSSReq->next;
84
+ }
85
+ }
86
+ m_searchRequests.push_back(sr);
87
+ jsr = jsr->next;
88
+ }
89
+ }
90
+
91
+ if (!bParseReq) {
92
+ if (LogAdapter::logConsole()) LogAdapter::Console("Something went wrong. Try passing the request again or contact Salesforce Support for help.");
93
+ return NULL;
94
+ }
95
+
96
+
97
+ cJSON *m_Results = cJSON_CreateArray();
98
+ cJSON *previous_result = NULL;
99
+
100
+ std::string tableName;
101
+ std::string metaPKeyName;
102
+ std::string keyTypeName;
103
+ std::string mergedKeyName;
104
+ std::string contentName;
105
+ bool isSalesforce = true;
106
+
107
+ if (isSalesforce) {
108
+ tableName = "CP_Pricing_Condition__c";
109
+ metaPKeyName = "Pricing_Condition_Template__c";
110
+ keyTypeName = "Key_Type__c";
111
+ mergedKeyName = "Merged_Key__c";
112
+ contentName = "Content__c";
113
+ } else {
114
+ //CndCpMetaPKey = '00100000006mjc9q' AND CndCpKeyTypePKey = '00100000006mk6tl' AND MergedKey = '00100000006nlp1y'
115
+ tableName = "CndCpMain";
116
+ metaPKeyName = "CndCpMetaPKey";
117
+ keyTypeName = "CndCpKeyTypePKey";
118
+ mergedKeyName = "MergedKey";
119
+ contentName = "Content";
120
+ }
121
+
122
+ //build the SQL statement
123
+ for (int i = 0; i<(int)m_searchRequests.size(); i++) {
124
+ SearchRequest sr = m_searchRequests[i];
125
+ //get table name from contion PKEY.
126
+ std::string sql = "select " + mergedKeyName + ", " + contentName + " from " + tableName + " where " + metaPKeyName + "= ?";
127
+
128
+ bool bSelect = false;
129
+ for (int j = 0; j < (int)sr.SearchSteps.size(); j++) {
130
+ // initialize query and add searchRequest param to query
131
+ cJSON * pQuery = m_conn->CreateJSONQuery();
132
+ cJSON * parameterArray = m_conn->AddJSONQueryItem(pQuery, sql.c_str());
133
+ m_conn->AddJSONQueryItemParam(parameterArray, sr.ConditionKey->valuestring);
134
+
135
+ SearchStepsRequest ssReq = sr.SearchSteps[j];
136
+ std::string sqlStep = " and ";
137
+ sqlStep.append(keyTypeName).append(" = ?");
138
+ m_conn->AddJSONQueryItemParam(parameterArray, ssReq.KeyType->valuestring);
139
+
140
+ timer t;
141
+ t.start();
142
+ std::string sqlMerge = " and " + mergedKeyName + " in (";
143
+ for (int k = 0; k < (int)ssReq.MergedKeys.size(); k++) {
144
+ /*
145
+ std::string sqlMerge = " and (";
146
+ std::string multipleKeys = ssReq.MergedKeys[k]->valuestring;
147
+ int foundPlus = std::string::npos;
148
+ while ((found = multipleKeys.find("+")) != std::string::npos) {
149
+ std::string key = multipleKeys.substr(0, found);
150
+ sqlMerge.append(mergedKeyName).append(" = ").append("'").append(key).append("'");
151
+ sqlMerge.append(" or ");
152
+ multipleKeys = multipleKeys.substr(found + 1);
153
+ }
154
+ sqlMerge.append(mergedKeyName).append(" = ").append("'").append(multipleKeys).append("')");
155
+ */
156
+ //changed by Joshua, Xu, to convert the OR conditions to in clause for better performance in SQLite
157
+ //changed by Joshua, Xu, as "abc+def+gfsds" is considered one key in database
158
+ if (k == 0)
159
+ sqlMerge.append("?");
160
+ else
161
+ sqlMerge.append(", ?");
162
+
163
+ m_conn->AddJSONQueryItemParam(parameterArray, ssReq.MergedKeys[k]->valuestring);
164
+ }
165
+ sqlMerge.append(")");
166
+
167
+ std::string selectSql = sql + sqlStep + sqlMerge;
168
+
169
+ // reassign sql statement
170
+ m_conn->ReplaceJSONSqlStatement(pQuery, selectSql.c_str());
171
+
172
+ cJSON* data = m_conn->universalParameterizedBatch(pQuery, false, false, true);
173
+
174
+ //add executeTime.
175
+ t.stop();
176
+ timer_ticks ticks = t.get_elapsed_us();
177
+ int executeTime = (int)t.ticks_to_ms(ticks) / ssReq.MergedKeys.size();
178
+
179
+ for (int k = 0; k < (int)ssReq.MergedKeys.size(); k++) {
180
+ //put in result list.
181
+ cJSON* result = cJSON_CreateArray();
182
+
183
+ cJSON_AddItemReferenceToArray(result, sr.ConditionKey);
184
+ cJSON_AddItemReferenceToArray(result, ssReq.KeyType);
185
+ // cJSON_AddItemReferenceToArray(result, ssReq.Exclusive);
186
+ cJSON_AddItemReferenceToArray(result, ssReq.MergedKeys[k]);
187
+
188
+ cJSON* cJsonSqlResult = NULL;
189
+ std::string sqlResult;
190
+ std::string mkName;
191
+
192
+ cJSON *queryResult = cJSON_GetArrayItem(data, 0);
193
+ std::string type = cJSON_GetObjectItem(queryResult, "type")->valuestring;
194
+
195
+ if (NULL != queryResult && type == "success") {
196
+ cJSON *result = cJSON_GetObjectItem(queryResult, "result");
197
+ cJSON *rows = cJSON_GetObjectItem(result, "rows");
198
+
199
+ cJSON *currRow = rows->child;
200
+ while (currRow) {
201
+ mkName = cJSON_GetObjectItem(currRow, "Merged_Key__c")->valuestring;
202
+ if (!mkName.compare(ssReq.MergedKeys[k]->valuestring)) {
203
+ sqlResult = cJSON_GetObjectItem(currRow, "Content__c")->valuestring;;
204
+ bSelect = true;
205
+ break;
206
+ }
207
+ currRow = currRow->next;
208
+ }
209
+ }
210
+
211
+ if (sqlResult.length()>0) {
212
+ //Parse the SQL result to JSON
213
+ cJsonSqlResult = cJSON_Parse(sqlResult.c_str());
214
+
215
+ if(!cJsonSqlResult){
216
+ //Parse failed
217
+ m_conn->LogError("PriceEngine", "PriceEngine", "conditionSearch", StringFormat("Error parsing complex pricing condition content to JSON for merged key: %s", mkName.c_str()).c_str());
218
+ }
219
+ }
220
+
221
+ cJSON_AddItemToArray(result, cJSON_CreateNumber((double)executeTime));
222
+ if (cJsonSqlResult) //add sqlResult to resultObj...
223
+ cJSON_AddItemToArray(result, cJsonSqlResult);
224
+
225
+ // Performance optimization done:
226
+ // cJSON is slow when adding an item at the end of an array, especialy if this array has many items.
227
+ // This is the case because cJSON searches the end of the array by iterating through the array from the beginning.
228
+ // To work around this the last item is cached and the new item is added by manually setting the "next" and "prev" pointers.
229
+ //
230
+ if (previous_result == NULL) {
231
+ cJSON_AddItemToArray(m_Results, result);
232
+ } else {
233
+ previous_result->next = result;
234
+ result->prev = previous_result;
235
+ }
236
+ previous_result = result;
237
+ }
238
+
239
+ if (NULL != data)
240
+ delete data;
241
+
242
+ // Check Exclusive
243
+ //int exclusive = ssReq.Exclusive->valueint;
244
+ if (strcmp(ssReq.Exclusive->valuestring, "0") != 0 && (bSelect)) {
245
+ break; //break current search request, continue next search request.
246
+ }
247
+ }
248
+ }
249
+
250
+ return cJSON_PrintUnformatted(m_Results);
251
+ }
@@ -0,0 +1,67 @@
1
+ //
2
+ // PriceEngine.h
3
+ // NGM
4
+ //
5
+ // Created by Yanbo on 29/05/14.
6
+ /*
7
+ * FILE_HEADER
8
+ */
9
+
10
+ #ifndef NGM_PriceEngine_h
11
+ #define NGM_PriceEngine_h
12
+
13
+ #include "../stdngm.h"
14
+ #include <cstdlib>
15
+ #include <vector>
16
+
17
+ #include "../DBAccess/SimpleDBConnection.h"
18
+ #include "../Libs/cJSON/cJSON.h"
19
+
20
+
21
+ using namespace std;
22
+
23
+ typedef struct _SearchStepsRequest {
24
+ cJSON* KeyType; //
25
+ cJSON* Exclusive; //
26
+ vector < cJSON*> MergedKeys; //array of merge Keys.
27
+ }SearchStepsRequest;
28
+
29
+ typedef struct _SearchRequest {
30
+ cJSON* ConditionKey; //name value
31
+ vector <SearchStepsRequest> SearchSteps; //array of SearchSteps.
32
+ }SearchRequest;
33
+
34
+
35
+ class PriceEngine {
36
+ //Input Json array string, output json content array.
37
+ private:
38
+ vector <SearchRequest> m_searchRequests;
39
+ cJSON* m_Results;
40
+ cJSON* m_Request;
41
+ SimpleDBConnection* m_conn;
42
+
43
+ public:
44
+ char* conditionSearch(char* jRequest);
45
+
46
+ PriceEngine()
47
+ {
48
+ m_Results = NULL;
49
+ m_Request = NULL;
50
+ m_conn = NULL;
51
+ }
52
+ ~PriceEngine() {
53
+ if (m_Results) {
54
+ cJSON_Delete(m_Results);
55
+ m_Results = NULL;
56
+ }
57
+ if (m_Request) {
58
+ cJSON_Delete(m_Request);
59
+ m_Request = NULL;
60
+ }
61
+ }
62
+ public:
63
+ void SetDBConnection(SimpleDBConnection* conn) { m_conn = conn; }
64
+ };
65
+
66
+
67
+ #endif