143{
144#ifdef __DCL_DEBUG
145
146#endif
147 ListedStringToStringArrayMap& mapQuery = session.
__ctx.__queryMap;
149
150 String strTableID = String::valueOf(
__nTableID);
151 String strDsID = String::valueOf(
__nDsID);
152 String strUserID = String::valueOf(session.
__nUserID);
153
155 int nRows = __nRows;
156
157
158
159
160
161
162
163
164 String strListPage =
getDefault(mapQuery, L
"list");
165 String strListPageEnc;
166 String strWritePage = __strWritePage;
167 String strDetailPage =
__pPage->__strPageID;
168 StringBuilder strThisPage =
__pPage->__strPageID;
169 String strMsg;
170 bool bAddParentToList = false;
171
172 if (strListPage.isEmpty()) {
173 bAddParentToList = __strListPage.contains(L"&msg");
174 strListPage = __strListPage;
175 }
176
178
179 if (!__strMsg.isEmpty())
180 strMsg = __strMsg;
181 else
182 strMsg = String::join(mapQuery[L"msg"], L',', false);
183
184 TextTemplate* pNOTICE = &(*this)[L"NOTICE"];
185 TextTemplate* pSTART = &(*this)[L"START"];
186 TextTemplate* pREPLY = &(*this)[L"REPLY"];
187 TextTemplate& EMPTY = (*this)[L"EMPTY"];
188
189 assign(L
"IS_GUEST", session.
isSysGuest() ? L
"true" : L
"false");
190 assign(L"WRITE", strWritePage);
191 assign(L"LIST", strListPage);
192 EMPTY.assign(L"LIST", strListPage);
193
194 if (strMsg.isEmpty()) {
195 assign(L"EMPTY", EMPTY);
196 return;
197 }
198 strThisPage += L"&msg=" + strMsg;
199
200 String strWhereEx;
201 switch(__nFilter) {
202 default :
203 case FILTER_SELF :
204 strWhereEx = L" AND M.MESSAGE_ID IN (" + strMsg + L")";
205 break;
206 case FILTER_CHILDREN :
207 strWhereEx = L" AND M.PARENT_ID IN (" + strMsg + L")";
208 break;
209 case FILTER_SELF | FILTER_CHILDREN :
210 strWhereEx = L" AND (M.MESSAGE_ID IN (" + strMsg + L") OR M.PARENT_ID IN (L" + strMsg + L"))";
211 break;
212 }
213
215
216 TextTemplate* pPART_LINK = atP(L"PART_LINK");
217 int nUsingRecord = nRows;
218 int nTotalRecord = nUsingRecord;
219 int nTotalPart = 1;
220 if (nCurrentPart != 1 || pPART_LINK) {
222 "SELECT COUNT(*) "
223 "\n FROM DCL_MESSAGE_" + strTableID + L" AS M"
224 "\n WHERE M.DS_ID = " + strDsID + strWhereEx
225 );
227 nTotalRecord = q.
fields()[0].asInteger();
228
229 if (nTotalRecord == 0) {
230 assign(L"EMPTY", EMPTY);
231
233 return;
234 }
235
236 nTotalPart = nTotalRecord / nUsingRecord;
237 if (nTotalRecord % nUsingRecord)
238 nTotalPart++;
239 }
240
241 if (nCurrentPart <= 0 || nCurrentPart > nTotalPart)
242 nCurrentPart = nTotalPart;
243
244 StringBuilder strThisEx = strThisPage;
245 if (nCurrentPart > 1)
246 strThisEx += L"&part=" + String::valueOf(nCurrentPart);
247
248 if (!strListPageEnc.isEmpty())
249 strThisEx += L"&list=" + strListPageEnc;
250
252
253 assign(L"_LIST", strListPageEnc);
254 assign(L"_THIS", strThisEnc);
255
256 StringBuilder strFieldEx;
257 StringBuilder strJoinEx;
258
259 if (__nSubject & SUBJECT_PARENT) {
260 strJoinEx += L"\n LEFT OUTER JOIN DCL_MESSAGE_" + strTableID + L""
261 " AS P\n ON (M.DS_ID = P.DS_ID AND M.PARENT_ID = P.MESSAGE_ID)";
262
263 strFieldEx += L", P.SUBJECT AS P_SUBJECT";
264 }
265 if (__nSubject & SUBJECT_PREV) {
266
267 }
268 if (__nSubject & SUBJECT_NEXT) {
269
270 }
271
272 int nOffset = (nCurrentPart - 1) * nUsingRecord;
273
274 String strSQL = L""
275 "SELECT M.MESSAGE_ID, M.PREV_ID, M.NEXT_ID, M.PARENT_ID, M.REPLY_ID,"
276 "\n M.NCHILD, M.TYPE AS BODY_TYPE,"
277 "\n M.USER_ID, M.SUBJECT, M.BODY_HTML, M.UPDATE_TIME,"
278 "\n M.NREAD, M.NAGREE, M.NDISAGREE, (M.NAGREE + M.NDISAGREE) AS NVOTE,"
279 "\n (M.NAGREE - M.NDISAGREE) AS NDECISION, M.VOTE_END,"
280 "\n U.USER_NAME AS WRITER, R.USER_ID AS R_USER_ID"
281 + strFieldEx.toString() + L""
282 "\n FROM DCL_MESSAGE_" + strTableID + L" AS M"
283 "\n INNER JOIN DCLWC_USER U ON (M.USER_ID = U.USER_ID)"
284 "\n LEFT OUTER JOIN DCL_MESSAGE_R_" + strTableID + L" AS R"
285 "\n ON (M.DS_ID = R.DS_ID AND M.MESSAGE_ID = R.MESSAGE_ID"
286 " AND R.USER_ID = " + strUserID + L")"
287 + strJoinEx.toString() + L""
288 "\n WHERE M.DS_ID = " + strDsID + strWhereEx + L""
289 "\n ORDER BY M.START_ID " + __strSort + L", M.REPLY_ID ASC"
290 "\n LIMIT " + String::valueOf(nUsingRecord) + L""
291 "\n OFFSET " + String::valueOf(nOffset);
292
294
298 assign(L"EMPTY", EMPTY);
299 }
300 else {
301 UpdateLink ul(atP(L"UPDATE_LINK"), strDetailPage, strWritePage, strThisEnc, strListPageEnc);
302 SiblingLink sl(atP(L"SIBLING_LINK"), strDetailPage, strListPageEnc);
303
308 qAttach.prepare(L""
309 "SELECT NO, NDOWNLOAD, FILENAME, TYPE, ICON, CEILING(SIZE / 1024) AS KSIZE"
310 "\n FROM DCL_MESSAGE_A_" + strTableID + L""
311 "\n WHERE DS_ID = " + strDsID + L""
312 "\n AND MESSAGE_ID = :MESSAGE_ID"
313 "\n ORDER BY NO ASC"
314 );
315 qInsert.prepare(L""
316 "INSERT INTO DCL_MESSAGE_R_" + strTableID + L""
317 "\n (DS_ID, MESSAGE_ID, USER_ID, NVOTE, UPDATE_TIME)"
318 "\n VALUES (L" + strDsID + L", :MESSAGE_ID, L" + strUserID
319 + L", 0, CURRENT_TIMESTAMP)"
320 );
321 qUpdate.prepare(L""
322 "UPDATE DCL_MESSAGE_" + strTableID + L""
323 "\n SET NREAD = NREAD + 1"
324 "\n WHERE DS_ID = " + strDsID + L""
325 "\n AND MESSAGE_ID = :MESSAGE_ID"
326 );
327
328 SQLFields& fields = q.
fields();
329 TextTemplate* pDest =
NULL;
331 int nMessageID = fields.
byName(L
"MESSAGE_ID").asInteger();
332 int64_t nReplyID = fields.
byName(L
"REPLY_ID").asInt64();
333 int nUserID = fields.
byName(L
"USER_ID").asInteger();
334 String strMessageID = String::valueOf(nMessageID);
335
336 MessageTree::Position rPos;
337 mt.getPosition(nReplyID, rPos);
338
339 if (pDest)
340 pDest->reset();
341
344 pDest = pNOTICE;
345 else
346 pDest = pSTART;
347 }
348 else
349 pDest = pREPLY;
350
351 pDest->assign(L
"VNO",
VNO());
352 if (bAddParentToList) {
353 StringBuilder str = strListPage + L"=";
354 str += fields.
byName(L
"PARENT_ID").asString();
356
357 pDest->assign(L"LIST", str);
358 sl.assign(pDest, fields, strListPageEnc);
359 }
360 else {
361 pDest->assign(L"LIST", strListPage);
362 sl.assign(pDest, fields);
363 }
364 ul.assign(pDest, fields, session, strMessageID, strListPage, mt, rPos);
365
366
367 pDest->assign(fields, L" ");
368 pDest->assign(L
"UPDATE_DATE", fields.
byName(L
"UPDATE_TIME").asDate().
toString());
369
370 if (__nSubject & SUBJECT_PARENT) {
371 String str;
372 SQLField& field = fields.
byName(L
"P_SUBJECT");
373 if (!field.isNull())
374 str = field.asString();
375 if (str.isEmpty())
376 str = L"제목없음";
377 append(L"P_SUBJECT", str);
378 }
379
380 int nBodyType = fields.
byName(L
"BODY_TYPE").asInteger();
381 if (nBodyType < 0) {
382 StringBuilder strBodyHtml = L"<span style=\"color:red\">(L";
383 if (nBodyType == -1)
384 strBodyHtml += L"글쓴이가 글을 삭제했습니다";
385 else
386 strBodyHtml += L"관리자에 의해 삭제되었습니다.";
387 strBodyHtml += L")</span>";
388
389 pDest->assign(L"SUBJECT", L"삭제됨");
390 pDest->assign(L"BODY_HTML", strBodyHtml);
391 }
392 else {
393 if (fields.
byName(L
"SUBJECT").asString().isEmpty())
394 pDest->assign(L"SUBJECT", L"제목없음");
395 }
396
397 TextTemplate* pATTACH = pDest->atP(L"ATTACH");
398 TextTemplate* pIMAGE = pDest->atP(L"IMAGE");
399 if (pATTACH || pIMAGE) {
400 pDest->assign(L"ATTACH_TITLE", __strAttachTitle);
401
402 qAttach.params()[0].setValue(nMessageID);
403 qAttach.execute();
404 qAttach.fetch();
405 bool bFirst = true;
406 while (!qAttach.eof()) {
407 String strType = qAttach.fields().byName(L"TYPE").asString();
408 if (pATTACH) {
409 pATTACH->assign(L
"SELF",
SELF());
410 pATTACH->assign(L"MESSAGE_ID", strMessageID);
411 pATTACH->assign(qAttach.fields(), String());
412 if (bFirst)
413 pDest->assign(L"ATTACH", *pATTACH);
414 else
415 pDest->append(L"ATTACH", *pATTACH);
416 }
417 if (pIMAGE && strType.compareNoCase(L"image", 5) == 0) {
418 pIMAGE->assign(L
"SELF",
SELF());
419 pIMAGE->assign(L"MESSAGE_ID", strMessageID);
420 pIMAGE->assign(qAttach.fields(), String());
421 if (bFirst)
422 pDest->assign(L"IMAGE", *pIMAGE);
423 else
424 pDest->append(L"IMAGE", *pIMAGE);
425 }
426 bFirst = false;
427 qAttach.fetch();
428 }
429 }
430
432 && fields.
byName(L
"R_USER_ID").isNull()
433 ) {
434 qInsert.params()[0].setValue(nMessageID);
435 qInsert.execute();
436 qUpdate.params()[0].setValue(nMessageID);
437 qUpdate.execute();
438
439 pDest->assign(
440 L"NREAD",
441 String::valueOf(fields.
byName(L
"NREAD").asInteger() + 1)
442 );
443 }
444 append(L"EMPTY", *pDest);
446 }
447 }
448
449 if (pPART_LINK && nTotalPart > 1) {
450 PartLink pl(pPART_LINK, strThisPage, strListPageEnc);
451 pl.assign(this, nTotalPart, nCurrentPart, __nParts);
452 }
453
455}
#define IS_NOTICE_ID(nMessageID)
#define __DCL_ASSERT(expr)
virtual void onPrint(Session &session) __DCL_THROWS1(Exception *)
_CONST SQLField & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
SQLConnection * connection() const
static ByteString encode(const ByteString &_str)