224{
225
226
227
228 ListedStringToStringArrayMap& mapQuery = session.
__ctx.__queryMap;
229 ListedStringToStringArrayMap& mapForm = session.
__ctx.__formMap;
231
232 String strTableID = String::valueOf(
__nTableID);
233 String strDsID = String::valueOf(
__nDsID);
234
235 String strListPage =
getDefault(mapQuery, L
"list");
236
238 StringBuilder strRefresh = L"?page=";
239 if (!strListPage.isEmpty())
240 strRefresh += strListPage;
241 else
242 strRefresh += __strListPage;
243 __pPage->refresh(session, strRefresh);
244 return;
245 }
246
247#define CM_UPDATE 0
248#define CM_INSERT_START 1
249#define CM_INSERT_REPLY 2
250
252 bool bNotice = false;
254
255 String strMessageID =
getDefault(mapQuery, L
"modify");
256 if (strMessageID.isEmpty()) {
257 strMessageID =
getDefault(mapQuery, L
"reply");
258 if (strMessageID.isEmpty() || strMessageID == L"0")
260 else
262 }
263 else
265
268 10,
269 nBodyType
270 );
273
274 if (mapForm.find(L"NOTICE") != mapForm.end()) {
275 bNotice = true;
276
277
278
280 }
281
282 String strSubject =
getDefault(mapForm, L
"SUBJECT");
283 String strBodyOrg =
getDefault(mapForm, L
"BODY_VALUE");
285 String strBodyHtml;
286
287 if (!strSubject.trim().isEmpty()) {
289 }
290
291 switch(nBodyType) {
293 strBodyHtml =
294 __GetLinkInsertedString(
296 strBodyOrg,
297 4,
298 String(),
299 L"<br>"
300 )
301 );
302 break;
304 strBodyHtml =
305 __GetLinkInsertedString(
307 strBodyOrg,
308 4,
309 L"<p>",
310 L"</p>"
311 )
312 );
313 break;
315 strBodyHtml = strBodyOrg.replace_r(L"<[ \t\r\n]*body", L"<div", true);
316 strBodyHtml = strBodyHtml.replace_r(L"/[ \t\r\n]*body", L"/div", true);
318 strBodyHtml,
319 L"!,--,html,head,title,meta,link,script,style,body"
320 ",mapForm,input,button,textarea,select,option"
321 );
322 break;
323 }
324
325 int nAttachNo = 1;
328 "SELECT MESSAGE_ID"
329 "\n FROM DCL_MESSAGE_" + strTableID + L""
330 "\n WHERE DS_ID = " + strDsID + L""
331 "\n AND MESSAGE_ID = " + strMessageID + L""
332 "\n AND USER_ID = " + String::valueOf(session.
__nUserID)
333 );
337 "UPDATE DCL_MESSAGE_" + strTableID + L""
338 "\n SET TYPE = :TYPE, SUBJECT = :SUBJECT"
339 ", BODY_ORG = :BODY_ORG, BODY_PLAIN = :BODY_PLAIN"
340 ", BODY_HTML = :BODY_HTML, UPDATE_TIME = CURRENT_TIMESTAMP"
341 "\n WHERE DS_ID = " + strDsID + L""
342 " AND MESSAGE_ID = " + strMessageID
343 );
344 SQLParams& params = q.
params();
345 params.
byName(L
"TYPE").setValue(nBodyType);
346 params.
byName(L
"SUBJECT").setValue(strSubject);
347 params.
byName(L
"BODY_ORG").setValue(strBodyOrg);
348 params.
byName(L
"BODY_PLAIN").setValue(strBodyPlain);
349 params.
byName(L
"BODY_HTML").setValue(strBodyHtml);
351
352
353 StringArray& vDeleteAttach = mapForm[L"DELETE_ATTACH"];
354 String strEraseAttach = String::join(vDeleteAttach, L',');
355 if (!strEraseAttach.isEmpty()) {
357 "DELETE FROM DCL_MESSAGE_A_" + strTableID + L""
358 "\n WHERE DS_ID = " + strDsID + L""
359 "\n AND MESSAGE_ID = " + strMessageID + L""
360 "\n AND NO IN (L" + strEraseAttach + L")"
361 );
363 for(size_t i = 0; i < vDeleteAttach.size(); i++) {
365 __pPage->site()->strAttachmentDir,
366 strDsID,
367 strMessageID,
368 vDeleteAttach[i]
369 );
372 }
373 }
374 }
375
376
378 "SELECT MAX(NO) FROM DCL_MESSAGE_A_" + strTableID + L""
379 "\n WHERE DS_ID = " + strDsID + L""
380 "\n AND MESSAGE_ID = " + strMessageID
381 );
383 if (!q.
fields()[0].isNull())
384 nAttachNo = q.
fields()[0].asInteger() + 1;
385 }
386
387
388
389
390
391
392
393 }
394 else {
395
396 int nParentID = 0;
397 int nPrevID = 0;
398 int nMessageID, nStartID, nChild = 0;
399 int64_t nReplyID = 1;
400
401 q.
execute(L
"SET AUTOCOMMIT = 0");
404 "SELECT MESSAGE_ID, NOTICE_ID"
405 "\n FROM DCLWC_DATA_SOURCE"
406 "\n WHERE DS_ID = " + strDsID + L""
407 "\n FOR UPDATE"
408 );
410 if (bNotice)
411 nMessageID = nStartID = q.
fields()[1].asInteger();
412 else
413 nMessageID = nStartID = q.
fields()[0].asInteger();
414
417
419 "SELECT MESSAGE_ID, START_ID, REPLY_ID, NCHILD"
420 "\n FROM DCL_MESSAGE_" + strTableID + L""
421 "\n WHERE DS_ID = " + strDsID + L""
422 "\n AND MESSAGE_ID = " + strMessageID
423 );
426
427 }
428
429 nParentID = q.
fields()[0].asInteger();
430 nStartID = q.
fields()[1].asInteger();
431 nReplyID = q.
fields()[2].asInt64();
432 nChild = q.
fields()[3].asInteger();
433
434 MessageTree::Position pos;
435 mt.getPosition(nReplyID, pos);
436 if (nChild == mt.width()
438 ) {
439
440
441
442
443 }
444
445
446
447 int64_t nPrevReplyID = 0;
449 int64_t _r = nReplyID;
450 nReplyID = mt.getChildID(nReplyID, mt.width() - nChild - 1);
451 if (nChild > 0)
452 nPrevReplyID = mt.getChildID(_r, mt.width() - nChild);
453 }
454 else {
455 int64_t _r = nReplyID;
456 nReplyID = mt.getChildID(nReplyID, nChild);
457 if (nChild > 0)
458 nPrevReplyID = mt.getChildID(_r, nChild - 1);
459 }
460
461 if (nChild > 0) {
464 "SELECT MESSAGE_ID FROM DCL_MESSAGE_" + strTableID + L""
465 "\n WHERE DS_ID = " + strDsID + L""
466 "\n AND START_ID = " + String::valueOf(nStartID) + L""
468 );
471 nPrevID = q.
fields()[0].asInteger();
472 }
473 }
474 else {
475 StringBuilder strSQL = L""
476 "SELECT MAX(MESSAGE_ID) FROM DCL_MESSAGE_" + strTableID + L""
477 "\n WHERE DS_ID = " + strDsID + L""
478 "\n AND PARENT_ID = 0";
479 if (!bNotice)
480 strSQL += L" AND MESSAGE_ID <= 2000000000";
481
486 if (!q.
fields()[0].isNull())
487 nPrevID = q.
fields()[0].asInteger();
489 }
490
492 "INSERT INTO DCL_MESSAGE_" + strTableID + L""
493 "\n (DS_ID, MESSAGE_ID, PREV_ID, NEXT_ID, PARENT_ID, START_ID, REPLY_ID,"
494 " TYPE, USER_ID, SUBJECT, BODY_ORG, BODY_PLAIN, BODY_HTML,"
495 " UPDATE_TIME)"
496 "\n VALUES"
497 "\n (:DS_ID, :MESSAGE_ID, :PREV_ID, :NEXT_ID, :PARENT_ID, :START_ID, :REPLY_ID,"
498 " :BODY_TYPE, :USER_ID, :SUBJECT, :BODY_ORG, :BODY_PLAIN, :BODY_HTML,"
499 " CURRENT_TIMESTAMP)"
500 );
501 SQLParams& params = q.
params();
503 params.
byName(L
"MESSAGE_ID").setValue(nMessageID);
505 params.
byName(L
"PREV_ID").setValue(0);
506 params.
byName(L
"NEXT_ID").setValue(nPrevID);
507 }
508 else {
509 params.
byName(L
"PREV_ID").setValue(nPrevID);
510 params.
byName(L
"NEXT_ID").setValue(0);
511 }
512 params.
byName(L
"PARENT_ID").setValue(nParentID);
513 params.
byName(L
"START_ID").setValue(nStartID);
514 params.
byName(L
"REPLY_ID").setValue(nReplyID);
515 params.
byName(L
"BODY_TYPE").setValue(nBodyType);
517 params.
byName(L
"SUBJECT").setValue(strSubject);
518 params.
byName(L
"BODY_ORG").setValue(strBodyOrg);
519 params.
byName(L
"BODY_PLAIN").setValue(strBodyPlain);
520 params.
byName(L
"BODY_HTML").setValue(strBodyHtml);
522
523 if (nPrevID > 0) {
526 "UPDATE DCL_MESSAGE_" + strTableID + L""
527 "\n SET PREV_ID = " + String::valueOf(nMessageID) + L""
528 "\n WHERE DS_ID = " + strDsID + L""
529 "\n AND MESSAGE_ID = " + String::valueOf(nPrevID)
530 );
531 else
533 "UPDATE DCL_MESSAGE_" + strTableID + L""
534 "\n SET NEXT_ID = " + String::valueOf(nMessageID) + L""
535 "\n WHERE DS_ID = " + strDsID + L""
536 "\n AND MESSAGE_ID = " + String::valueOf(nPrevID)
537 );
538 }
539
541 String strChildID;
542 if (nChild == 0)
543 strChildID = L", CHILD_ID = " + String::valueOf(nMessageID);
544
546 "UPDATE DCL_MESSAGE_" + strTableID + L""
547 "\n SET NCHILD = NCHILD + 1" + strChildID + L""
548 "\n WHERE DS_ID = " + strDsID + L""
549 "\n AND MESSAGE_ID = " + strMessageID
550 );
551 }
552
553 if (bNotice)
555 "UPDATE DCLWC_DATA_SOURCE"
556 "\n SET NOTICE_ID = NOTICE_ID + 1"
557 "\n WHERE DS_ID = " + strDsID
558 );
559 else
561 "UPDATE DCLWC_DATA_SOURCE"
562 "\n SET MESSAGE_ID = MESSAGE_ID + 1"
563 "\n WHERE DS_ID = " + strDsID
564 );
566 q.
execute(L
"SET AUTOCOMMIT = 1");
567 strMessageID = String::valueOf(nMessageID);
568 }
569
570
571 StoredHttpFormData& formFile = session.
__ctx.__formFileMap;
573 String strDir =
__pPage->site()->strAttachmentDir + strDsID;
576
577 if (__nThumbnailImageSize > 0) {
578 strDir =
__pPage->site()->strThumbnailDir + strDsID;
581 }
582
584 "INSERT INTO DCL_MESSAGE_A_" + strTableID + L""
585 "\n (DS_ID, MESSAGE_ID, NO, FILENAME, TYPE)"
586 "\n VALUES"
587 "\n (L" + strDsID + L", L" + strMessageID + L""
588 ", :NO, :FILENAME, :TYPE)"
589 );
590 for(
size_t i = 0; i < formFile.
size(); i++) {
591 StoredHttpFormData::FileInfoArray& v = formFile[i];
592 for(size_t j = 0; j < v.size(); j++)
593 {
594 StoredHttpFormData::FileInfo& info = v[j];
595
597 __pPage->site()->strAttachmentDir,
598 strDsID,
599 strMessageID,
600 String::valueOf(nAttachNo)
601 );
603 info.tempFilename,
604 strLocalFileName
605 );
606 if (__nThumbnailImageSize > 0) {
607#if 0
609 strLocalFileName,
610 info.strContentType,
612 __pPage->site()->strThumbnailDir,
613 strDsID,
614 strMessageID,
615 String::valueOf(nAttachNo)
616 ) + L".jpg",
617 __nThumbnailImageSize
618 );
619#endif
620 }
621 q.
params()[0].setValue(nAttachNo);
622 q.
params()[1].setValue(info.filename);
623 q.
params()[2].setValue(info.contentType);
625
626 nAttachNo++;
627 }
628 }
629 }
630
631 StringBuilder strNext =
getDefault(mapQuery, L
"next");
632 if (!strNext.isEmpty())
633 strNext = L"?page=" + strNext.toString();
634 else {
635 strNext = L"?page=" + __strDetailPage;
636 strNext += L"&msg=" + strMessageID;
637 }
638
639 if (!strListPage.isEmpty())
641
642 __pPage->refresh(session, strNext);
643}
__DCL_BEGIN_NAMESPACE String __GetLocalFileName(const String &strAttachDir, const String &strDsID, const String &strMessageID, const String &strAttachNo)
#define BODY_TYPE_PLAIN_P
#define BODY_TYPE_PLAIN_BR
#define __DCL_ASSERT(expr)
#define __DCL_TRACE2(fmt, arg1, arg2)
__DCL_BEGIN_NAMESPACE bool GenThumbnailImage(const char *pszSrcFile, const char *pszContentType, const char *pszThumbnailFile, int nSize)
static void mkdir(const String &_path, int _mode=0755) __DCL_THROWS1(IOException *)
static bool exists(const String &_path)
static void rename(const String &_oldpath, const String &_newpath) __DCL_THROWS1(IOException *)
static void unlink(const String &_path) __DCL_THROWS1(IOException *)
static String strip(const String &_str, const wchar_t *_elementNames)
static String format(const String &_str, int _tab2Space, const String &_beginOfLine, const String &_endOfLine)
static String escape(const String &_str, const wchar_t *_chars)
static String getDefault(ListedStringToStringArrayMap &map, const String &strKey)
String toString(unsigned _base=10) const
SQLParam & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
void prepare(const String &_sql) __DCL_THROWS1(SQLException *)
_CONST SQLParams & params() _CONST
_CONST SQLFields & fields() _CONST
void execute() __DCL_THROWS1(SQLException *)
int64_t affectedRows() const
void fetch() __DCL_THROWS1(SQLException *)
HttpServletContextEx & __ctx
static ByteString encode(const ByteString &_str)