Desenvolver e Download de Software Open Source

Browse Subversion Repository

Contents of /bathyscaphe/trunk/application/source/browser/BSDBThreadsListDBUpdateTask2.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1422 - (show annotations) (download)
Tue May 1 13:07:47 2012 UTC (12 years ago) by masakih
File size: 12140 byte(s)
change task classes for thread list.

1 //
2 // BSDBThreadsListDBUpdateTask2.m
3 // BathyScaphe
4 //
5 // Created by Hori,Masaki on 06/08/06.
6 // Copyright 2006-2011 BathyScaphe Project. All rights reserved.
7 // encoding="UTF-8"
8 //
9
10 #import "BSDBThreadsListDBUpdateTask2.h"
11
12 #import <CocoaOniguruma/OnigRegexp.h>
13
14 #import "DatabaseManager.h"
15 #import "CMRHostHandler.h"
16 #import "CMXTextParser.h"
17 #import "CMRDocumentFileManager.h"
18
19 //NSString *const BSDBThreadsListDBUpdateTask2DidFinishNotification = @"BSDBThreadsListDBUpdateTask2DidFinishNotification";
20
21
22 static inline id nilIfObjectIsNSNull(id obj)
23 {
24 return (obj == [NSNull null]) ? nil : obj;
25 }
26
27 @implementation BSDBThreadsListDBUpdateTask2
28
29 static NSString *sSelectThreadTableQuery = nil;
30 static NSString *sInsertQuery = nil;
31 static NSString *sUpdateQuery = nil;
32 static NSString *sInsertNumberQuery = nil;
33 static OnigRegexp *gRegexp = nil;
34
35 - (id)initWithBBSName:(NSString *)name data:(NSData *)data livedoor:(BOOL)isLivedoorFlag rebuilding:(BOOL)isRebuildingFlag
36 {
37 if (self = [super init]) {
38 bbsName = [name retain];
39
40 subjectData = [data retain];
41 isRebuilding = isRebuildingFlag;
42 isLivedoor = isLivedoorFlag;
43 }
44
45 return self;
46 }
47
48 + (id)taskWithBBSName:(NSString *)name data:(NSData *)data livedoor:(BOOL)isLivedoorFlag rebuilding:(BOOL)isRebuildingFlag
49 {
50 return [[[self alloc] initWithBBSName:name data:data livedoor:isLivedoorFlag rebuilding:isRebuildingFlag] autorelease];
51 }
52
53 - (BOOL)isRebuilding
54 {
55 return isRebuilding;
56 }
57
58 - (BOOL)isLivedoor
59 {
60 return isLivedoor;
61 }
62
63 - (NSError *)lastErrorWhileRebuilding
64 {
65 return lastError;
66 }
67
68 - (void)dealloc
69 {
70 [subjectData release];
71 [boardID release];
72 [bbsName release];
73 [lastError release];
74
75 [super dealloc];
76 }
77
78 - (void)setBBSName:(NSString *)name
79 {
80 NSArray *boradIDs = [[DatabaseManager defaultManager] boardIDsForName:name];
81 if (!boradIDs || [boradIDs count] == 0) {
82 return;
83 }
84 boardID = [[boradIDs objectAtIndex:0] retain];
85 bbsName = [name retain];
86 }
87
88 static inline SQLiteReservedQuery *reservedSelectThreadTable(SQLiteDB* db)
89 {
90 return [SQLiteReservedQuery sqliteReservedQueryWithQuery:sSelectThreadTableQuery usingSQLiteDB:db];
91 }
92
93 static inline SQLiteReservedQuery *reservedInsert(SQLiteDB* db)
94 {
95 return [SQLiteReservedQuery sqliteReservedQueryWithQuery:sInsertQuery usingSQLiteDB:db];
96 }
97
98 static inline SQLiteReservedQuery *reservedUpdate(SQLiteDB* db)
99 {
100 return [SQLiteReservedQuery sqliteReservedQueryWithQuery:sUpdateQuery usingSQLiteDB:db];
101 }
102
103 static inline SQLiteReservedQuery *reservedInsertNumber(SQLiteDB* db)
104 {
105 return [SQLiteReservedQuery sqliteReservedQueryWithQuery:sInsertNumberQuery usingSQLiteDB:db];
106 }
107
108 + (BOOL)makeQuerys
109 {
110 // ������������������
111 if (!sSelectThreadTableQuery) {
112 sSelectThreadTableQuery = [NSString stringWithFormat: @"SELECT %@, %@, %@ FROM %@ WHERE %@ = ? AND %@ = ?",
113 ThreadStatusColumn, NumberOfAllColumn, NumberOfReadColumn,
114 ThreadInfoTableName,
115 BoardIDColumn, ThreadIDColumn];
116 [sSelectThreadTableQuery retain];
117 }
118
119 // ���������������������
120 if (!sInsertQuery) {
121 sInsertQuery = [NSString stringWithFormat: @"INSERT INTO %@ ( %@, %@, %@, %@, %@ ) VALUES ( ?, ?, ?, ?, %ld )",
122 ThreadInfoTableName,
123 BoardIDColumn, ThreadIDColumn, ThreadNameColumn, NumberOfAllColumn, ThreadStatusColumn,
124 (long)ThreadNewCreatedStatus];
125 [sInsertQuery retain];
126 }
127
128 // ������������������������������
129 if (!sUpdateQuery) {
130 sUpdateQuery = [NSString stringWithFormat: @"UPDATE %@ SET %@ = ?, %@ = ? WHERE %@ = ? AND %@ = ?",
131 ThreadInfoTableName,
132 NumberOfAllColumn, ThreadStatusColumn,
133 BoardIDColumn, ThreadIDColumn];
134 [sUpdateQuery retain];
135 }
136
137 // ���������������������������
138 if (!sInsertNumberQuery) {
139 sInsertNumberQuery = [NSString stringWithFormat: @"INSERT INTO %@ ( %@, %@, %@ ) VALUES ( ?, ?, ? )",
140 TempThreadNumberTableName,
141 BoardIDColumn, ThreadIDColumn, TempThreadThreadNumberColumn];
142 [sInsertNumberQuery retain];
143 }
144
145 return YES;
146 }
147
148 + (BOOL)makeRegex
149 {
150 if (!gRegexp) {
151 gRegexp = [OnigRegexp compile:[NSString stringWithFormat:@"(\\d+)[^,<>]*(?:<>|,)(.*)\\s*(?:\\(|<>|%C)(\\d+)",0xFF08]];
152 [gRegexp retain];
153 }
154 return YES;
155 }
156
157 - (BOOL)updateDB:(SQLiteDB *)db ID:(NSString *)datString title:(NSString *)title count:(NSInteger)countInt index:(NSInteger)index
158 {
159 NSArray *bindValues;
160 id<SQLiteCursor> cursor;
161
162 // ������������������������������������������������������
163 // [cursor rowCount] ���0���������������������������������
164 bindValues = [NSArray arrayWithObjects:
165 boardID, datString, nil];
166
167 cursor = [reservedSelectThreadTable(db) cursorForBindValues:bindValues];
168 if (!cursor) {
169 return NO;
170 }
171
172 if ([cursor rowCount] == 0) {
173 // ���������������������������������������������������������
174 SQLiteReservedQuery *rFirstQuery = reservedInsert(db);
175 const char *format = F_NSNumberOfInt F_NSString F_NSString F_Int;
176 [rFirstQuery cursorWithFormat:format, boardID, datString, title, countInt, nil];
177 if ([db lastErrorID] != SQLITE_OK) {
178 NSLog(@"Fail INSERT. ErrorID -> %ld. Reason: %@", (long)[db lastErrorID], [db lastError]);
179 }
180
181 } else {
182 // ���������������������������������������������������������������������������������������������������������������������
183 id<SQLiteRow> row = [cursor rowAtIndex:0];
184
185 NSUInteger currentNumber;
186 NSUInteger currentStatus, newStatus;
187 NSUInteger readNumber;
188
189 currentNumber = [nilIfObjectIsNSNull([row valueForColumn:NumberOfAllColumn]) integerValue];
190 currentStatus = [nilIfObjectIsNSNull([row valueForColumn:ThreadStatusColumn]) integerValue];
191 readNumber = [nilIfObjectIsNSNull([row valueForColumn:NumberOfReadColumn]) integerValue];
192
193 if (readNumber == 0) {
194 newStatus = ThreadNoCacheStatus;
195 } else if (countInt <= readNumber) {
196 newStatus = ThreadLogCachedStatus;
197 } else {
198 newStatus = ThreadUpdatedStatus;;
199 }
200
201 if (currentNumber != countInt || currentStatus != newStatus) {
202 SQLiteReservedQuery *rUpdateQuery = reservedUpdate(db);
203 const char *format2 = F_Int F_Int F_NSNumberOfInt F_NSString;
204 [rUpdateQuery cursorWithFormat:format2, countInt, newStatus, boardID, datString, nil];
205 if ([db lastErrorID] != SQLITE_OK) {
206 NSLog(@"Fail UPDATE. ErrorID -> %ld. Reason: %@", (long)[db lastErrorID], [db lastError]);
207 }
208 }
209 }
210
211 // ���������������������������������������������������������������������
212 SQLiteReservedQuery *rTempInsertQuery = reservedInsertNumber(db);
213 const char *format3 = F_NSNumberOfInt F_NSString F_Int;
214 [rTempInsertQuery cursorWithFormat:format3, boardID, datString, index, nil];
215 if ([db lastErrorID] != SQLITE_OK) {
216 NSLog(@"Fail INSERT. ErrorID -> %ld. Reason: %@", (long)[db lastErrorID], [db lastError]);
217 }
218
219 return YES;
220 }
221
222 - (void)deleteUnusedInfomations:(SQLiteDB *)db
223 {
224 BOOL isDelete = SGTemplateBool(@"System - Delete Unused Thread Informations");
225 if (!isDelete) {
226 return;
227 }
228
229 if (db && [db beginTransaction]) {
230 // ���������������������������
231 UTILDebugWrite(@"START DELETING");
232 NSString *query = [NSString stringWithFormat:
233 @"DELETE FROM %@ "
234 @"WHERE "
235 @"%@ = %@ AND "
236 @"%@ IS NULL AND "
237 @"%@ NOT IN "
238 @"(SELECT %@ FROM %@ WHERE %@ = %@)"
239 ,
240 ThreadInfoTableName,
241 BoardIDColumn, boardID,
242 NumberOfReadColumn,
243 ThreadIDColumn,
244 ThreadIDColumn, TempThreadNumberTableName, BoardIDColumn, boardID];
245 [db performQuery:query];
246 if ([db lastErrorID] != 0) {
247 NSLog(@"Fail DELETE. ErrorID -> %ld. Reason: %@", (long)[db lastErrorID], [db lastError] );
248 }
249 UTILDebugWrite1(@" %d row(s) deleted.", sqlite3_changes([db rowDatabase]));
250 [db commitTransaction];
251 UTILDebugWrite(@"END DELETEING");
252 }
253 }
254
255 - (BOOL)rebuildFromLogFiles:(NSError **)errorPtr
256 {
257 NSString *folderPath = [[CMRDocumentFileManager defaultManager] directoryWithBoardName:bbsName];
258
259 return [[DatabaseManager defaultManager] rebuildFromLogFolder:folderPath boardID:boardID error:errorPtr];
260 }
261
262 - (void)run
263 {
264 NSString *str;
265 NSArray *lines;
266 NSUInteger count, i;
267 NSString *line;
268 NSString *datString;
269 id title;
270 NSString *numString;
271
272 UTILDebugWrite(@"Start BSDBThreadsListDBUpdateTask2.");
273
274 CFStringEncoding enc;
275 DatabaseManager *dbm = [DatabaseManager defaultManager];
276 NSArray *array = [dbm boardIDsForName:bbsName];
277 NSString *urlStr;
278 NSURL *url;
279 CMRHostHandler *handler;
280
281 if (!array || [array count] == 0) {
282 NSLog(@"Can NOT found bbs named %@.",bbsName);
283 return;
284 }
285 boardID = [[array objectAtIndex:0] retain];
286
287 urlStr = [dbm urlStringForBoardID:[boardID integerValue]];
288 url = [NSURL URLWithString:urlStr];
289 if (!url) {
290 NSLog(@"Can NOT create url from bbs named %@.",bbsName);
291 return;
292 }
293 handler = [CMRHostHandler hostHandlerForURL:url];
294 if (!handler) {
295 NSLog(@"Can NOT create host handler from url %@.",url);
296 return;
297 }
298 enc = [handler subjectEncoding];
299 str = [CMXTextParser stringWithData:subjectData CFEncoding:enc];//[NSString stringWithDataUsingTEC:subjectData encoding:enc];
300 // ���������
301 lines = [str componentsSeparatedByNewline];
302
303 if (![[self class] makeRegex]) {
304 UTILDebugWrite(@"Can not create regular expression(BSDBThreadsListDBUpdateTask2.)");
305 return;
306 }
307 OnigResult *match;
308
309 SQLiteDB *db = [dbm databaseForCurrentThread];
310
311 if (db && [db beginTransaction]) {
312 if (![BSDBThreadsListDBUpdateTask2 makeQuerys]) {
313 UTILDebugWrite(@"Can not create query string(BSDBThreadsListDBUpdateTask2.)");
314 goto abort;
315 }
316
317 if (isInterrupted) {
318 goto abort;
319 }
320 // ���������������������������������������������
321 UTILDebugWrite(@"START CLEAR TEMP DATA");
322 id query = [NSString stringWithFormat:@"DELETE FROM %@ WHERE %@ = %@",
323 TempThreadNumberTableName,
324 BoardIDColumn, boardID];
325 [db performQuery:query];
326 UTILDebugWrite1(@" %d row(s) deleted.", sqlite3_changes([db rowDatabase]));
327 UTILDebugWrite(@"END CLEAR TEMP DATA");
328
329 UTILDebugWrite(@"START REGISTER THREADS");
330 count = [lines count];
331 NSMutableSet *dats = isLivedoor ? [[NSMutableSet alloc] initWithCapacity:count] : nil;
332 for (i = 0; i < count; i++) {
333 if (isInterrupted) {
334 [dats release];
335 goto abort;
336 }
337 line = [lines objectAtIndex:i];
338 match = [gRegexp search:line];
339
340 datString = [match stringAt:1];
341 title = [match stringAt:2];
342 numString = [match stringAt:3];
343
344 if (!numString) {
345 continue;
346 }
347 if (isLivedoor) {
348 if ([dats member:datString]) {
349 continue;
350 } else {
351 [dats addObject:datString];
352 }
353 }
354 title = [[title mutableCopy] autorelease];
355 [CMXTextParser replaceEntityReferenceWithString:title];
356
357 // DB ���������
358 if(![self updateDB:db ID:datString title:title count:[numString integerValue] index:(i+1)]) {
359 UTILDebugWrite(@"Abort in updateDB.");
360 [dats release];
361 goto abort;
362 }
363 }
364 [dats release];
365 [db commitTransaction];
366 UTILDebugWrite(@"END REGISTER THREADS");
367 }
368
369 if (isRebuilding) {
370 NSError *error = nil;
371 [self rebuildFromLogFiles:&error];
372 if (error) {
373 lastError = [error retain];
374 }
375 } else {
376 [self deleteUnusedInfomations:db];
377 }
378
379 // [self postNotificationWithName:BSDBThreadsListDBUpdateTask2DidFinishNotification];
380
381 return;
382
383 abort:
384 NSLog(@"Fail Database operation. Reason: \n%@\nin %@(%@)",
385 [db lastError], NSStringFromClass([self class]), NSStringFromSelector(_cmd));
386 [db rollbackTransaction];
387
388 // if (!isInterrupted) {
389 // [self postNotificationWithName:BSDBThreadsListDBUpdateTask2DidFinishNotification];
390 // }
391 }
392
393 - (void)cancel:(id)sender
394 {
395 // [self postNotificationWithName:BSDBThreadsListDBUpdateTask2DidFinishNotification];
396 isInterrupted = YES;
397 }
398 @end
399
400 /*
401 @implementation BSDBThreadsListDBUpdateTask2(TaskNotification)
402 - (void)postNotificationWithName:(NSString *)name
403 {
404 [[NSNotificationCenter defaultCenter] postNotificationName:name object:self];
405 UTILDebugWrite(@"End BSDBThreadsListDBUpdateTask2.");
406 }
407 @end
408 */

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26