DCL 3.7.4
Loading...
Searching...
No Matches
DataSource.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#ifdef __WINNT__
4#include <windows.h>
5#endif
6
7#include <dcl/SQL.h>
8#include <dcl/TextTemplate.h>
9#include <dcl/URI.h>
10#include <dcl/Html.h>
11
12#include "HtmlPage.h"
13#include "LinkUtility.h"
14#include "MessageTree.h"
15#include "User.h"
16#include "DataSource.h"
17
18#if __DCL_HAVE_THIS_FILE__
19#undef __THIS_FILE__
20static const char_t __THIS_FILE__[] = __T("fastpage/DataSource.cpp");
21#endif
22
23__DCL_BEGIN_NAMESPACE
24
25#define CM_INSERT 1
26#define CM_UPDATE 2
27#define CM_DELETE 3
28
29static const wchar_t* __dsTypeName(int nDsType)
30{
31 switch(nDsType) {
32 case DS_NONE : return L"N/A";
33 case DS_BOARD : return L"게시판";
34 case DS_MENU : return L"메뉴";
35 }
36 return L"Invalid DsType";
37}
38
40
41DataSourceListView::DataSourceListView(HtmlPage* pPage)
42 : HtmlView(pPage)
43{
44 __nParts = DEFAULT_PARTS;
45 __nRows = DEFAULT_ROWS;
46 __nShortComment = DEFAULT_SHORT_STRING;
47 __bNoAsc = false;
48 __bAll = false;
49}
50
51void DataSourceListView::init(SQLFields& fields)
53{
54 HtmlView::init(fields);
55
56 __mapParams.lookup(L"DETAIL", __strDetailPage);
57 __mapParams.lookup(L"WRITE", __strWritePage);
58
59 String rValue;
60
61 if (__mapParams.lookup(L"PARTS", rValue) && !rValue.isEmpty()) {
62 __nParts = Integer::parse(rValue, 10, __nParts);
63 if (__nParts < 5 || __nParts > 20)
64 __nParts = 5;
65 }
66
67 if (__mapParams.lookup(L"ROWS", rValue) && !rValue.isEmpty()) {
68 __nRows = Integer::parse(rValue, 10, __nRows);
69 if (__nRows <= 0)
70 __nRows = 20;
71 }
72
73 if (__mapParams.lookup(L"SHORT_COMMENT", rValue) && !rValue.isEmpty()) {
74 int n = Integer::parse(rValue, 10, __nShortComment);
75 if (n > 0)
76 __nShortComment = n;
77 }
78
79 if (__mapParams.lookup(L"NO", rValue)) {
80 if (!rValue.compareNoCase(L"ASC"))
81 __bNoAsc = true;
82 }
83
84 if (__mapParams.lookup(L"FILTER", rValue)) {
85 if (!rValue.compareNoCase(L"ALL"))
86 __bAll = true;
87 }
88}
89
90void DataSourceListView::onPrint(Session& session)
91{
92// session.__ctx.addHeader(HttpHeader(L"Cache-Control", L"no-cache"));
93
94 SQLQuery& q = session.__query;
95 ListedStringToStringArrayMap& mapQuery = session.__ctx.__queryMap;
96
97 int nCurrentPart = Integer::parse(getDefault(mapQuery, L"part"), 10, 1);
98 int nRows = __nRows;
99
100 String strDetailPage = __strDetailPage;
101 String strWritePage = __strWritePage;
102 String strListPage = getDefault(mapQuery, L"list");
103 String strListPageEnc = URLEncoder::encode(strListPage);
104 StringBuilder strThisPage = __pPage->__strPageID;
105 String strThisPageEnc;
106
107 String strDsType = getDefault(mapQuery, L"type");
108 String strUserID = getDefault(mapQuery, L"user");
109
110 int nUserID = Integer::parse(strUserID, 10, 0);
111 if (nUserID < Session::GUEST_USER_ID) {
112 TextTemplate* pUSER = atP(L"USER");
113 if (pUSER) {
114 q.execute(L""
115 "SELECT USER_ID, USER_NAME"
116 "\n FROM DCL_USER"
117 "\n WHERE -1 < USER_ID"
118 "\n AND USER_ID < " + String::valueOf(Session::GUEST_USER_ID) + L""
119 "\n ORDER BY USER_ID"
120 );
121 q.fetch();
122 while(!q.eof()) {
123 pUSER->assign(q.fields(), L"");
124 append(L"USER", *pUSER);
125 q.fetch();
126 }
127 }
128 }
129
130 StringBuilder strWhere = L"\n WHERE D.DS_ID ";
131 if (__bAll)
132 strWhere += L"> -10";
133 else
134 strWhere += L"> 0";
135
136 if (!strUserID.isEmpty()) {
137 q.execute(L""
138 "SELECT USER_ID, USER_NAME"
139 "\n FROM DCL_USER"
140 "\n WHERE USER_ID = " + String::valueOf(nUserID)
141 );
142 q.fetch();
143 if (!q.eof())
144 assign(q.fields(), L"");
145
146 strWhere += L" AND D.USER_ID = " + strUserID;
147 strThisPage += L"&user=" + strUserID;
148 }
149
150 if (!strDsType.isEmpty()) {
151 strWhere += L" AND D.DS_TYPE = " + strDsType;
152 strThisPage += L"&type=" + strDsType;
153 }
154
155 assign(L"DETAIL", strDetailPage);
156 assign(L"WRITE", strWritePage);
157 assign(L"LIST", strListPage);
158 assign(L"_THIS", URLEncoder::encode(strThisPage));
159 assign(L"USER_ID", strUserID);
160 assign(L"TYPE", strDsType);
161
162 int nUsingRecord = nRows;
163 int nTotalRecord = nUsingRecord;
164 int nTotalPart = 1;
165
166 // nNo를 표시하기 위해서 조건에 만족하는 전체레코드의 개수가 항상 필요하다.
167 q.execute(L""
168 "SELECT COUNT(*) "
169 "\n FROM DCL_DATA_SOURCE AS D"
170 + strWhere.toString()
171 );
172 q.fetch();
173 nTotalRecord = q.fields()[0].asInteger();
174 if (nTotalRecord == 0) {
175 assign(L"EMPTY", (*this)[L"EMPTY"]);
176 HtmlView::onPrint(session);
177 return;
178 }
179
180 __DCL_VERIFY(nTotalRecord > 0);
181
182 nTotalPart = nTotalRecord / nUsingRecord;
183 if (nTotalRecord % nUsingRecord)
184 nTotalPart++;
185
186 if (nCurrentPart <= 0 || nCurrentPart > nTotalPart)
187 nCurrentPart = nTotalPart;
188
189 StringBuilder strThisPageEx = strThisPage;
190 if (nCurrentPart > 1)
191 strThisPageEx += L"&part=" + String::valueOf(nCurrentPart);
192 if (!strListPageEnc.isEmpty())
193 strThisPageEx += L"&list=" + strListPageEnc;
194 strThisPageEnc = URLEncoder::encode(strThisPageEx);
195
196 assign(L"_LIST", strListPageEnc);
197 assign(L"_THIS", strThisPageEnc);
198
199 int nOffset = (nCurrentPart - 1) * nUsingRecord;
200 int nNo = nTotalRecord - ((nCurrentPart - 1) * nUsingRecord);
201
202 TextTemplate& DS = (*this)[L"DS"];
203
204 String strSQL = L""
205 "SELECT D.USER_ID, D.DS_ID, D.DS_NAME, D.DS_TYPE, D.TABLE_ID"
206 ", D.COMMENT, D.UPDATE_TIME, U.USER_NAME"
207 "\n FROM DCL_DATA_SOURCE AS D"
208 "\n INNER JOIN DCL_USER AS U ON (D.USER_ID = U.USER_ID)"
209 + strWhere.toString() + L""
210 "\n ORDER BY D.USER_ID, D.DS_ID"
211 "\n LIMIT " + String::valueOf(nUsingRecord) + L""
212 "\n OFFSET " + String::valueOf(nOffset);
213
214 __DCL_TRACE1(L"\n%ls\n", strSQL.data());
215
216 q.execute(strSQL);
217 q.fetch();
218 if (q.eof())
219 assign(L"EMPTY", (*this)[L"EMPTY"]);
220 else {
221 if (__bNoAsc)
222 nNo = 1;
223
224 do {
225 DS.assign(q.fields(), L"&nbsp;");
226 DS.assign(L"DS_TYPE_NAME",
227 __dsTypeName(q.fields().byName(L"DS_TYPE").asInteger()));
228
229 if (__nShortComment > 0) {
230 String strLong;
231 String strShort;
232 if (getShortString(q.fields().byName(L"COMMENT"),
233 __nShortComment, strLong, strShort) == 0
234 ) {
235 strShort = L"&nbsp;";
236 }
237
238 DS.assign(L"SHORT_COMMENT", strShort);
239 DS.assign(L"COMMENT", strLong);
240 }
241
242 DS.assign(L"NO", String::valueOf(nNo));
243 if (__bNoAsc)
244 nNo++;
245 else
246 nNo--;
247 DS.assign(L"DETAIL", strDetailPage);
248 DS.assign(L"WRITE", strWritePage);
249 DS.assign(L"_THIS", strThisPageEnc);
250
251 append(L"EMPTY", DS);
252 q.fetch();
253 } while(!q.eof());
254
255 TextTemplate* pPART_LINK = atP(L"PART_LINK");
256 if (pPART_LINK && nTotalPart > 1) {
257 PartLink pl(pPART_LINK, strThisPage, String());
258 pl.assign(this, nTotalPart, nCurrentPart, __nParts);
259 }
260 }
261
262 HtmlView::onPrint(session);
263}
264
266
267DataSourceWriteForm::DataSourceWriteForm(HtmlPage* pPage)
268 : FormView(pPage)
269{
270}
271
272void DataSourceWriteForm::init(SQLFields& fields)
274{
275 FormView::init(fields);
276
277 __mapParams.lookup(L"DETAIL", __strDetailPage);
278 __mapParams.lookup(L"LIST", __strListPage);
279}
280
281void DataSourceWriteForm::onPrint(Session& session)
283{
284 ListedStringToStringArrayMap& mapQuery = session.__ctx.__queryMap;
285 SQLQuery& q = session.__query;
286
287 String strUserID = getDefault(mapQuery, L"user");
288 String strDsID = getDefault(mapQuery, L"ds");
289 String strListPage = getDefault(mapQuery, L"list");
290 if (!strListPage.isEmpty()) {
291 String strListPageEnc = URLEncoder::encode(strListPage);
292 assign(L"_LIST", strListPageEnc);
293 }
294 else
295 strListPage = __strListPage;
296
297 assign(L"LIST", strListPage);
298
299 // "user" 만 있으면 새 메시지소스
300 // "user"과 "ds"가 모두 있으면 수정
301 // 그외는 잘못된 QUERY_STRING
302
303#define CM_INVALID 0
304#define CM_INSERT 1
305#define CM_MODIFY 2
306
307 int nCM = CM_INVALID;
308 if (!strUserID.isEmpty()) {
309 append(L"ACTION", L"&user=" + strUserID);
310 if (!strDsID.isEmpty()) {
311 nCM = CM_MODIFY;
312 append(L"ACTION", L"&ds=" + strDsID);
313 }
314 else
315 nCM = CM_INSERT;
316 }
317 else {
318 // invalid QUERY_STRING
319 FormView::onPrint(session);
320 return;
321 }
322
323 TextTemplate& ROLE = (*this)[L"ROLE"];
324 q.execute(L""
325 "SELECT ROLE_ID, ROLE_NAME FROM DCL_ROLE"
326 "\n WHERE ROLE_ID > 0"
327 "\n ORDER BY ROLE_ID"
328 );
329 q.fetch();
330 while(!q.eof()) {
331 ROLE.assign(q.fields(), L"");
332 append(L"ROLE", ROLE);
333 q.fetch();
334 }
335
336 if (nCM == CM_MODIFY) {
337 q.execute(L""
338 "SELECT D.USER_ID, D.DS_ID, D.DS_NAME"
339 ", D.DS_TYPE, D.TABLE_ID, D.COMMENT"
340 ", D.REPLY_DEPTH, D.SEQUENCE, D.MESSAGE_ID, D.NOTICE_ID"
341 ", D.START_WPERM_ID, D.REPLY_WPERM_ID, D.ATTACH_RPERM_ID"
342 ", U.USER_NAME"
343 "\n FROM DCL_DATA_SOURCE AS D"
344 "\n INNER JOIN DCL_USER AS U ON (D.USER_ID = U.USER_ID)"
345 "\n WHERE D.USER_ID = " + strUserID + L""
346 "\n AND D.DS_ID = " + strDsID
347 );
348 q.fetch();
349 if (!q.eof()) {
350 assign(q.fields(), L"");
351 if (q.fields().byName(L"DS_TYPE").asInteger() == DS_BOARD) {
352 assign(L"REPLY_WIDTH",
353 String::valueOf(
355 q.fields().byName(L"REPLY_DEPTH").asInteger()
356 )
357 )
358 );
359 }
360 }
361 else {
362 // invalid QUERY_STRING
363 __DCL_TRACE0(L"Invalid QUERY_STRING !\n");
364 }
365 }
366 else {
367 // CM_INSERT
368 q.execute(L""
369 "SELECT USER_ID, USER_NAME"
370 "\n FROM DCL_USER"
371 "\n WHERE USER_ID = " + strUserID
372 );
373 q.fetch();
374 if (!q.eof()) {
375 assign(q.fields(), L"");
376
377 q.execute(L""
378 "SELECT MAX(TABLE_ID)"
379 "\n FROM DCL_DATA_SOURCE"
380 "\n WHERE TABLE_ID >= 0"
381 );
382 q.fetch();
383
384 int nTableID = 0;
385 if (!q.eof())
386 nTableID = q.fields()[0].asInteger() + 1;
387 assign(L"_TABLE_ID", String::valueOf(nTableID));
388
389 q.execute(L""
390 "SELECT MAX(DS_ID)"
391 "\n FROM DCL_DATA_SOURCE"
392 "\n WHERE USER_ID = " + strUserID
393 );
394 q.fetch();
395 int nDsID = 1;
396 if (!q.fields()[0].isNull())
397 nDsID += q.fields()[0].asInteger();
398 assign(L"_DS_ID", String::valueOf(nDsID));
399 }
400 else {
401 // invalid QUERY_STRING
402 __DCL_TRACE0(L"Invalid QUERY_STRING !\n");
403 }
404
405 }
406
407 FormView::onPrint(session);
408}
409
410static void __CreateTables(SQLQuery& q, int nDsType, int nTableID);
411
412void DataSourceWriteForm::onPost(Session& session)
414{
415// dump(session);
416// return;
417
418 ListedStringToStringArrayMap& mapQuery = session.__ctx.__queryMap;
419 ListedStringToStringArrayMap& mapForm = session.__ctx.__formMap;
420 SQLQuery& q = session.__query;
421
422 String strUserID = getDefault(mapQuery, L"user");
423 String strDsID = getDefault(mapQuery, L"ds");
424
425 // "user" 만 있으면 새 메시지소스
426 // "user"과 "ds"가 모두 있으면 수정
427 // 그외는 잘못된 QUERY_STRING
428
429#define CM_INVALID 0
430#define CM_INSERT 1
431#define CM_MODIFY 2
432
433 int nCM = CM_INVALID;
434 if (!strUserID.isEmpty()) {
435 if (!strDsID.isEmpty())
436 nCM = CM_MODIFY;
437 else {
438 nCM = CM_INSERT;
439 strDsID = getDefault(mapForm, L"DS_ID");
440 }
441 }
442 else {
443 // invalid QUERY_STRING
444 String strListPage = getDefault(mapQuery, L"list");
445 if (strListPage.isEmpty())
446 strListPage = __strListPage;
447 __pPage->refresh(session, L"?page=" + strListPage);
448 return;
449 }
450
451 int nUserID = Integer::parse(strUserID, 10, -1);
452 int nDsID = Integer::parse(strDsID, 10, 1);
453 int nDsType = Integer::parse(getDefault(mapForm, L"DS_TYPE"), 10, 0);
454 int nTableID = Integer::parse(getDefault(mapForm, L"TABLE_ID"), 10, 0);
455 int nReplyDepth = Integer::parse(getDefault(mapForm, L"REPLY_DEPTH"), 10, 2);
456 int nSequence = Integer::parse(getDefault(mapForm, L"SEQUENCE"), 10, -1);
457 int nStartWPermID = Integer::parse(getDefault(mapForm, L"START_WPERM_ID"), 10, 0);
458 int nReplyWPermID = Integer::parse(getDefault(mapForm, L"REPLY_WPERM_ID"), 10, 0);
459 int nAttachRPermID = Integer::parse(getDefault(mapForm, L"ATTACH_RPERM_ID"), 10, 0);
460 String strDsName = getDefault(mapForm, L"DS_NAME");
461 String strComment = getDefault(mapForm, L"COMMENT");
462
463 if (nUserID < 0 || strDsName.isEmpty()) {
464 __pPage->printError(
465 session,
466 L"필수 입력값 오류",
467 L"메시지소스를 생성하는데 필요한 필수 입력값이 잘못되었습니다."
468 );
469 return;
470 }
471
472 q.execute(L""
473 "SELECT DISTINCT TABLE_ID"
474 "\n FROM DCL_DATA_SOURCE"
475 "\n WHERE DS_TYPE = " + String::valueOf(nDsType) + L""
476 "\n AND TABLE_ID = " + String::valueOf(nTableID)
477 );
478 q.fetch();
479 if (q.eof()) {
480 __CreateTables(q, nDsType, nTableID);
481 }
482
483 int nOldDsType = DS_NONE;
484 String strOldTableID;
485
486 if (nCM == CM_INSERT) {
487 q.prepare(L""
488 "INSERT INTO DCL_DATA_SOURCE(L"
489 "USER_ID, DS_ID, DS_NAME, DS_TYPE, TABLE_ID"
490 ", COMMENT, UPDATE_TIME"
491 ", REPLY_DEPTH, SEQUENCE, MESSAGE_ID, NOTICE_ID"
492 ", START_WPERM_ID, REPLY_WPERM_ID, ATTACH_RPERM_ID"
493 ")"
494 "\n VALUES(L"
495 ":USER_ID, :DS_ID, :DS_NAME, :DS_TYPE, :TABLE_ID"
496 ", :COMMENT, CURRENT_TIMESTAMP"
497 ", :REPLY_DEPTH, :SEQUENCE, :MESSAGE_ID, :NOTICE_ID"
498 ", :START_WPERM_ID, :REPLY_WPERM_ID, :ATTACH_RPERM_ID"
499 ")"
500 );
501 }
502 else {
503 // CM_MODIFY;
504 q.execute(L"SET AUTOCOMMIT = 0");
505 q.execute(L"COMMIT");
506
507 q.execute(L""
508 "SELECT DS_TYPE, TABLE_ID, REPLY_DEPTH, SEQUENCE, MESSAGE_ID, NOTICE_ID"
509 "\n FROM DCL_DATA_SOURCE"
510 "\n WHERE USER_ID = " + strUserID + L""
511 "\n AND DS_ID = " + strDsID + L""
512 "\n FOR UPDATE"
513 );
514 q.fetch();
515 __DCL_VERIFY(!q.eof());
516 if ((q.fields()[1].asInteger() != nTableID)
517 || (q.fields()[2].asInteger() != nReplyDepth)
518 || (q.fields()[3].asInteger() != nSequence)
519 || (q.fields()[4].asInteger() != MESSAGE_START_ID)
520 || (q.fields()[5].asInteger() != NOTICE_START_ID)
521 ) {
522 nOldDsType = q.fields()[0].asInteger();
523 strOldTableID = q.fields()[1].asString();
524
525 switch(nOldDsType) {
526 case DS_BOARD: {
527 q.execute(L""
528 "DELETE FROM DCL_MESSAGE_A_" + strOldTableID + L""
529 "\n WHERE USER_ID = " + strUserID + L" AND DS_ID = " + strDsID
530 );
531 q.execute(L""
532 "DELETE FROM DCL_MESSAGE_R_" + strOldTableID + L""
533 "\n WHERE USER_ID = " + strUserID + L" AND DS_ID = " + strDsID
534 );
535 q.execute(L""
536 "DELETE FROM DCL_MESSAGE_" + strOldTableID + L""
537 "\n WHERE USER_ID = " + strUserID + L" AND DS_ID = " + strDsID
538 );
539 break;
540 }
541 }
542 }
543
544 q.prepare(L""
545 "UPDATE DCL_DATA_SOURCE SET"
546 " DS_NAME = :DS_NAME"
547 ", TABLE_ID = :TABLE_ID"
548 ", COMMENT = :COMMENT"
549 ", UPDATE_TIME = CURRENT_TIMESTAMP"
550 ", REPLY_DEPTH = :REPLY_DEPTH"
551 ", SEQUENCE = :SEQUENCE"
552 ", MESSAGE_ID = :MESSAGE_ID"
553 ", NOTICE_ID = :NOTICE_ID"
554 ", START_WPERM_ID = :START_WPERM_ID"
555 ", REPLY_WPERM_ID = :REPLY_WPERM_ID"
556 ", ATTACH_RPERM_ID = :ATTACH_RPERM_ID"
557 "\n WHERE USER_ID = :USER_ID"
558 "\n AND DS_ID = :DS_ID"
559 );
560 }
561
562 SQLParams& params = q.params();
563 params.byName(L"USER_ID").setValue(nUserID);
564 params.byName(L"DS_ID").setValue(nDsID);
565 params.byName(L"DS_NAME").setValue(strDsName);
566 if (strComment.isEmpty())
567 params.byName(L"COMMENT").setNull();
568 else
569 params.byName(L"COMMENT").setValue(strComment);
570
571 if (nCM == CM_INSERT)
572 params.byName(L"DS_TYPE").setValue(nDsType);
573
574 params.byName(L"TABLE_ID").setValue(nTableID);
575
576 params.byName(L"REPLY_DEPTH").setValue(nReplyDepth);
577 params.byName(L"SEQUENCE").setValue(nSequence);
578 params.byName(L"MESSAGE_ID").setValue(MESSAGE_START_ID);
579 params.byName(L"NOTICE_ID").setValue(NOTICE_START_ID);
580 params.byName(L"START_WPERM_ID").setValue(nStartWPermID);
581 params.byName(L"REPLY_WPERM_ID").setValue(nReplyWPermID);
582 params.byName(L"ATTACH_RPERM_ID").setValue(nAttachRPermID);
583 q.execute();
584
585 if (nCM == CM_MODIFY) {
586 q.execute(L"COMMIT");
587 q.execute(L"SET AUTOCOMMIT = 1");
588
589 if (nOldDsType != DS_NONE) {
590 // 사용하지 않는 테이블을 삭제한다.
591 q.execute(L""
592 "SELECT DISTINCT TABLE_ID"
593 "\n FROM DCL_DATA_SOURCE"
594 "\n WHERE DS_TYPE = " + String::valueOf(nOldDsType) + L""
595 "\n AND TABLE_ID = " + strOldTableID
596 );
597 q.fetch();
598 if (q.eof()) {
599 switch (nOldDsType) {
600 case DS_BOARD: {
601 q.execute(L"DROP TABLE DCL_MESSAGE_A_" + strOldTableID);
602 q.execute(L"DROP TABLE DCL_MESSAGE_R_" + strOldTableID);
603 q.execute(L"DROP TABLE DCL_MESSAGE_" + strOldTableID);
604 break;
605 }
606 }
607 }
608 }
609 }
610
611 StringBuilder strNext = getDefault(mapQuery, L"next");
612 if (strNext.isEmpty()) {
613 strNext = __strDetailPage;
614 strNext += L"&user=" + String::valueOf(nUserID)
615 + L"&ds=" + String::valueOf(nDsID);
616 }
617
618 String strListPage = getDefault(mapQuery, L"list");
619 if (!strListPage.isEmpty())
620 strNext += L"&list=" + URLEncoder::encode(strListPage);
621
622 __pPage->refresh(session, L"?page=" + strNext.toString());
623}
624
626
627DataSourceDetailView::DataSourceDetailView(HtmlPage* pPage)
628 : HtmlView(pPage)
629{
630}
631
632void DataSourceDetailView::init(SQLFields& fields)
634{
635 HtmlView::init(fields);
636
637 __mapParams.lookup(L"LIST", __strListPage);
638 __mapParams.lookup(L"WRITE", __strWritePage);
639}
640
641void DataSourceDetailView::onPrint(Session& session)
643{
644 ListedStringToStringArrayMap& mapQuery = session.__ctx.__queryMap;
645 SQLQuery& q = session.__query;
646
647 String strListPage = getDefault(mapQuery, L"list");
648 String strListPageEnc;
649 String strWritePage = __strWritePage;
650 if (strListPage.isEmpty())
651 strListPage = __strListPage;
652
653 strListPageEnc = URLEncoder::encode(strListPage);
654
655 assign(L"LIST", strListPage);
656 assign(L"_LIST", strListPageEnc);
657 assign(L"WRITE", strWritePage);
658
659 String strUserID = getDefault(mapQuery, L"user");
660 String strMsIDs = String::join(mapQuery[L"ds"], L',');
661
662 TextTemplate& DS = (*this)[L"DS"];
663 TextTemplate& EMPTY = (*this)[L"EMPTY"];
664
665 if (strUserID.isEmpty() || strMsIDs.isEmpty()) {
666 assign(L"EMPTY", EMPTY);
667 HtmlView::onPrint(session);
668 return;
669 }
670
671 q.execute(L""
672 "SELECT D.USER_ID, D.DS_ID, D.DS_NAME, D.DS_TYPE, D.TABLE_ID"
673 ", D.COMMENT, D.UPDATE_TIME"
674 ", D.REPLY_DEPTH, D.SEQUENCE, D.MESSAGE_ID, D.NOTICE_ID"
675 ", D.START_WPERM_ID, D.REPLY_WPERM_ID, D.ATTACH_RPERM_ID"
676 ", U.USER_NAME, S.ROLE_NAME AS START_WPERM"
677 ", R.ROLE_NAME AS REPLY_WPERM, A.ROLE_NAME AS ATTACH_RPERM"
678 "\n FROM DCL_DATA_SOURCE AS D"
679 "\n INNER JOIN DCL_USER AS U ON (D.USER_ID = U.USER_ID)"
680 "\n INNER JOIN DCL_ROLE AS S ON (D.START_WPERM_ID = S.ROLE_ID)"
681 "\n INNER JOIN DCL_ROLE AS R ON (D.REPLY_WPERM_ID = R.ROLE_ID)"
682 "\n INNER JOIN DCL_ROLE AS A ON (D.ATTACH_RPERM_ID = A.ROLE_ID)"
683 "\n WHERE D.USER_ID = " + strUserID + L""
684 "\n AND D.DS_ID IN (" + strMsIDs + L")"
685 "\n ORDER BY D.DS_ID"
686 );
687
688 q.fetch();
689 if (q.eof())
690 assign(L"EMPTY", EMPTY);
691 else {
692 do {
693 DS.assign(q.fields(), L"&nbsp;");
694 int nDsType = q.fields().byName(L"DS_TYPE").asInteger();
695 DS.assign(L"DS_TYPE_NAME", __dsTypeName(nDsType));
696 if (nDsType == DS_BOARD) {
697 DS.assign(L"REPLY_WIDTH",
698 String::valueOf(
700 q.fields().byName(L"REPLY_DEPTH").asInteger()
701 )
702 )
703 );
704
705 int nSequence = q.fields().byName(L"SEQUENCE").asInteger();
706 if (nSequence < 0)
707 DS.assign(L"SEQUENCE_NAME", L"내림차순");
708 else
709 DS.assign(L"SEQUENCE_NAME", L"오름차순");
710 }
711 else {
712 static const wchar_t* apsz[] = {
713 L"REPLY_DEPTH",
714 L"REPLY_WIDTH",
715 L"SEQUENCE",
716 L"SEQUENCE_NAME",
717// L"MESSAGE_ID",
718 L"NOTICE_ID",
719 L"START_WPERM",
720 L"REPLY_WPERM",
721 L"ATTACH_RPERM"
722 };
723
724 String strNA = L"-";
725 for(size_t i = 0; i < (sizeof(apsz) / sizeof(const char*)); i++)
726 DS.assign(apsz[i], strNA);
727 }
728
729 SQLField& field = q.fields().byName(L"COMMENT");
730 if (!field.isNull()) {
731 String strComment = field.asString();
732 if (!strComment.isEmpty()) {
733 strComment = Html::format(
734 strComment,
735 4, // TAB 문자를 4개의 ' '로 변환
736 String(), // 빈 문자열
737 L"<br>"
738 );
739 }
740 else {
741 strComment = L"&nbsp;";
742 }
743 DS.assign(L"COMMENT", strComment);
744 }
745
746 DS.assign(L"LIST", strListPage);
747 DS.assign(L"_LIST", strListPageEnc);
748 DS.assign(L"WRITE", strWritePage);
749 append(L"DS", DS);
750
751 q.fetch();
752 } while(!q.eof());
753 }
754
755 HtmlView::onPrint(session);
756}
757
758static void __CreateTables(SQLQuery& q, int nDsType, int nTableID)
759{
760 String strTableID = String::valueOf(nTableID);
761 try {
762 switch(nDsType) {
763 case DS_BOARD: {
764 q.execute(L""
765 "CREATE TABLE DCL_MESSAGE_" + strTableID + L""
766 "\n(L"
767 "\n USER_ID INTEGER NOT NULL,"
768 "\n DS_ID SMALLINT NOT NULL,"
769 "\n MESSAGE_ID INTEGER NOT NULL,"
770 "\n PREV_ID INTEGER NOT NULL DEFAULT 0,"
771 "\n NEXT_ID INTEGER NOT NULL DEFAULT 0,"
772 "\n PARENT_ID INTEGER NOT NULL DEFAULT 0,"
773 "\n CHILD_ID INTEGER NOT NULL DEFAULT 0,"
774 "\n START_ID INTEGER NOT NULL,"
775 "\n REPLY_ID BIGINT NOT NULL DEFAULT 1,"
776 "\n NCHILD INTEGER NOT NULL DEFAULT 0,"
777 "\n TYPE TINYINT NOT NULL DEFAULT 0,"
778 "\n WRITER_ID INTEGER NOT NULL,"
779 "\n SUBJECT VARCHAR(255) NULL,"
780 "\n BODY_ORG TEXT NULL,"
781 "\n BODY_PLAIN TEXT NULL,"
782 "\n BODY_HTML TEXT NULL,"
783 "\n UPDATE_TIME DATETIME NOT NULL,"
784 "\n NREAD INTEGER NOT NULL DEFAULT 0,"
785 "\n NAGREE INTEGER NOT NULL DEFAULT 0,"
786 "\n NDISAGREE INTEGER NOT NULL DEFAULT 0,"
787 "\n VOTE_END DATETIME,"
788 "\n CONSTRAINT PRIMARY KEY (USER_ID, DS_ID, MESSAGE_ID),"
789 "\n CONSTRAINT FOREIGN KEY (WRITER_ID) REFERENCES DCL_USER (USER_ID),"
790 "\n CONSTRAINT UNIQUE INDEX (USER_ID, DS_ID, START_ID, REPLY_ID),"
791 "\n INDEX (USER_ID, DS_ID, PARENT_ID)"
792 "\n)"
793 );
794 q.execute(L""
795 "CREATE TABLE DCL_MESSAGE_R_" + strTableID + L""
796 "\n(L"
797 "\n USER_ID INTEGER NOT NULL,"
798 "\n DS_ID SMALLINT NOT NULL,"
799 "\n MESSAGE_ID INTEGER NOT NULL,"
800 "\n READER_ID INTEGER NOT NULL,"
801 "\n NVOTE TINYINT NOT NULL DEFAULT 0,"
802 "\n UPDATE_TIME DATETIME NOT NULL,"
803 "\n CONSTRAINT PRIMARY KEY (USER_ID, DS_ID, MESSAGE_ID, READER_ID),"
804 "\n CONSTRAINT FOREIGN KEY (USER_ID, DS_ID, MESSAGE_ID)"
805 "\n REFERENCES DCL_MESSAGE_" + strTableID + L""
806 " (USER_ID, DS_ID, MESSAGE_ID)"
807 "\n)"
808 );
809 q.execute(L""
810 "CREATE TABLE DCL_MESSAGE_A_" + strTableID + L""
811 "\n(L"
812 "\n USER_ID INTEGER NOT NULL,"
813 "\n DS_ID SMALLINT NOT NULL,"
814 "\n MESSAGE_ID INTEGER NOT NULL,"
815 "\n NO SMALLINT NOT NULL DEFAULT 1,"
816 "\n NREAD INTEGER NOT NULL DEFAULT 0,"
817 "\n FILENAME VARCHAR(255) NOT NULL,"
818 "\n TYPE VARCHAR(255) NOT NULL,"
819 "\n ICON VARCHAR(20),"
820 "\n SIZE INTEGER NOT NULL DEFAULT 0,"
821 "\n CONSTRAINT PRIMARY KEY (USER_ID, DS_ID, MESSAGE_ID, NO),"
822 "\n CONSTRAINT FOREIGN KEY (USER_ID, DS_ID, MESSAGE_ID)"
823 "\n REFERENCES DCL_MESSAGE_" + strTableID + L""
824 " (USER_ID, DS_ID, MESSAGE_ID)"
825 "\n)"
826 );
827 break;
828 }
829 default: {
830 __DCL_ASSERT(false);
831 }
832 }
833
834 }
835 catch (Exception* e)
836 {
837 __DCL_TRACE1(L"%ls\n", e->toStringAll().data());
838 e->destroy();
839 }
840}
841
842__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
#define CM_MODIFY
#define CM_INSERT
#define CM_INVALID
#define NOTICE_START_ID
Definition DataSource.h:11
#define MESSAGE_START_ID
Definition DataSource.h:10
#define IMPLEMENT_CLASSINFO_EX(class_name, base_class_name)
Definition HtmlView.h:37
@ DS_BOARD
Definition HtmlView.h:28
@ DS_MENU
Definition HtmlView.h:29
@ DS_NONE
Definition HtmlView.h:27
#define __DCL_TRACE0(psz)
Definition Object.h:398
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_VERIFY(expr)
Definition Object.h:396
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define __T(str)
Definition Object.h:60
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
static String format(const String &_str, int _tab2Space, const String &_beginOfLine, const String &_endOfLine)
Definition Html.cpp:122
virtual void onPrint(Session &session) __DCL_THROWS1(Exception *)
Definition HtmlView.cpp:349
static String getDefault(ListedStringToStringArrayMap &map, const String &strKey)
Definition HtmlView.cpp:256
virtual void init(SQLFields &fields) __DCL_THROWS1(Exception *)
Definition HtmlView.cpp:298
static size_t getShortString(SQLField &field, size_t _len, String &strLong, String &strShort)
Definition HtmlView.cpp:266
HtmlPage * __pPage
Definition HtmlView.h:108
static int parse(const wchar_t *_number, unsigned _base=10) __DCL_THROWS1(NumericConvertException *)
Definition Numeric.inl:36
static int getDefaultWidth(int nDepth)
Definition SQL.h:48
_CONST SQLField & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
Definition SQLQuery.cpp:77
SQLParam & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
Definition SQLQuery.cpp:157
void prepare(const String &_sql) __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:282
_CONST SQLParams & params() _CONST
Definition SQL.inl:106
_CONST SQLFields & fields() _CONST
Definition SQL.inl:101
void execute() __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:316
bool eof() const
Definition SQL.inl:91
void fetch() __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:336
@ GUEST_USER_ID
Definition Session.h:23
HttpServletContextEx & __ctx
Definition Session.h:41
SQLQuery & __query
Definition Session.h:42
static ByteString encode(const ByteString &_str)
Definition URI.cpp:82