r45765 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r45764‎ | r45765 | r45766 >
Date:10:18, 15 January 2009
Author:catrope
Status:ok
Tags:
Comment:
* svn:eol-style native for r45755
* Replace spaces with tabs in ApiFormatJson_json.php, fix some crazy indentation
Modified paths:
  • /trunk/phase3/includes/SearchIBM_DB2.php (modified) (history)
  • /trunk/phase3/includes/api/ApiFormatJson_json.php (modified) (history)
  • /trunk/phase3/includes/db/DatabaseIbm_db2.php (modified) (history)
  • /trunk/phase3/maintenance/ibm_db2/README (modified) (history)
  • /trunk/phase3/maintenance/ibm_db2/tables.sql (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/ibm_db2/tables.sql
@@ -1,604 +1,604 @@
2 -
3 -
4 -
5 -
6 -
7 -CREATE SEQUENCE user_user_id_seq AS INTEGER START WITH 0 INCREMENT BY 1;
8 -CREATE TABLE mwuser ( -- replace reserved word 'user'
9 - user_id INTEGER NOT NULL PRIMARY KEY, -- DEFAULT nextval('user_user_id_seq'),
10 - user_name VARCHAR(255) NOT NULL UNIQUE,
11 - user_real_name VARCHAR(255),
12 - user_password clob(1K),
13 - user_newpassword clob(1K),
14 - user_newpass_time TIMESTAMP,
15 - user_token VARCHAR(255),
16 - user_email VARCHAR(255),
17 - user_email_token VARCHAR(255),
18 - user_email_token_expires TIMESTAMP,
19 - user_email_authenticated TIMESTAMP,
20 - user_options CLOB(64K),
21 - user_touched TIMESTAMP,
22 - user_registration TIMESTAMP,
23 - user_editcount INTEGER
24 -);
25 -CREATE INDEX user_email_token_idx ON mwuser (user_email_token);
26 -
27 -INSERT INTO mwuser
28 - VALUES (NEXTVAL FOR user_user_id_seq,'Anonymous','', NULL,NULL,CURRENT_TIMESTAMP,NULL, NULL,NULL,NULL,NULL, NULL,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,0);
29 -
30 -CREATE TABLE user_groups (
31 - ug_user INTEGER REFERENCES mwuser(user_id) ON DELETE CASCADE,
32 - ug_group VARCHAR(255) NOT NULL
33 -);
34 -CREATE UNIQUE INDEX user_groups_unique ON user_groups (ug_user, ug_group);
35 -
36 -CREATE TABLE user_newtalk (
37 - user_id INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
38 - user_ip VARCHAR(255),
39 - user_last_timestamp TIMESTAMP
40 -);
41 -CREATE INDEX user_newtalk_id_idx ON user_newtalk (user_id);
42 -CREATE INDEX user_newtalk_ip_idx ON user_newtalk (user_ip);
43 -
44 -
45 -CREATE SEQUENCE page_page_id_seq;
46 -CREATE TABLE page (
47 - page_id INTEGER NOT NULL PRIMARY KEY, -- DEFAULT NEXT VALUE FOR user_user_id_seq,
48 - page_namespace SMALLINT NOT NULL,
49 - page_title VARCHAR(255) NOT NULL,
50 - page_restrictions clob(1K),
51 - page_counter BIGINT NOT NULL DEFAULT 0,
52 - page_is_redirect SMALLINT NOT NULL DEFAULT 0,
53 - page_is_new SMALLINT NOT NULL DEFAULT 0,
54 - page_random NUMERIC(15,14) NOT NULL,
55 - page_touched TIMESTAMP,
56 - page_latest INTEGER NOT NULL, -- FK?
57 - page_len INTEGER NOT NULL
58 -);
59 -CREATE UNIQUE INDEX page_unique_name ON page (page_namespace, page_title);
60 -CREATE INDEX page_random_idx ON page (page_random);
61 -CREATE INDEX page_len_idx ON page (page_len);
62 -
63 -
64 -
65 -CREATE SEQUENCE rev_rev_id_val;
66 -CREATE TABLE revision (
67 - rev_id INTEGER NOT NULL UNIQUE, --DEFAULT nextval('rev_rev_id_val'),
68 - rev_page INTEGER REFERENCES page (page_id) ON DELETE CASCADE,
69 - rev_text_id INTEGER, -- FK
70 - rev_comment clob(1K), -- changed from VARCHAR(255)
71 - rev_user INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE RESTRICT,
72 - rev_user_text VARCHAR(255) NOT NULL,
73 - rev_timestamp TIMESTAMP NOT NULL,
74 - rev_minor_edit SMALLINT NOT NULL DEFAULT 0,
75 - rev_deleted SMALLINT NOT NULL DEFAULT 0,
76 - rev_len INTEGER,
77 - rev_parent_id INTEGER
78 -);
79 -CREATE UNIQUE INDEX revision_unique ON revision (rev_page, rev_id);
80 -CREATE INDEX rev_text_id_idx ON revision (rev_text_id);
81 -CREATE INDEX rev_timestamp_idx ON revision (rev_timestamp);
82 -CREATE INDEX rev_user_idx ON revision (rev_user);
83 -CREATE INDEX rev_user_text_idx ON revision (rev_user_text);
84 -
85 -
86 -CREATE SEQUENCE text_old_id_val;
87 -CREATE TABLE pagecontent ( -- replaces reserved word 'text'
88 - old_id INTEGER NOT NULL,
89 - --PRIMARY KEY DEFAULT nextval('text_old_id_val'),
90 - old_text CLOB(16M),
91 - old_flags clob(1K)
92 -);
93 -
94 -CREATE SEQUENCE pr_id_val;
95 -CREATE TABLE page_restrictions (
96 - pr_id INTEGER NOT NULL UNIQUE,
97 - --DEFAULT nextval('pr_id_val'),
98 - pr_page INTEGER NOT NULL
99 - --(used to be nullable)
100 - REFERENCES page (page_id) ON DELETE CASCADE,
101 - pr_type VARCHAR(255) NOT NULL,
102 - pr_level VARCHAR(255) NOT NULL,
103 - pr_cascade SMALLINT NOT NULL,
104 - pr_user INTEGER,
105 - pr_expiry TIMESTAMP,
106 - PRIMARY KEY (pr_page, pr_type)
107 -);
108 -
109 -CREATE TABLE page_props (
110 - pp_page INTEGER NOT NULL REFERENCES page (page_id) ON DELETE CASCADE,
111 - pp_propname VARCHAR(255) NOT NULL,
112 - pp_value CLOB(64K) NOT NULL,
113 - PRIMARY KEY (pp_page,pp_propname)
114 -);
115 -CREATE INDEX page_props_propname ON page_props (pp_propname);
116 -
117 -
118 -
119 -CREATE TABLE archive (
120 - ar_namespace SMALLINT NOT NULL,
121 - ar_title VARCHAR(255) NOT NULL,
122 - ar_text CLOB(16M),
123 - ar_page_id INTEGER,
124 - ar_parent_id INTEGER,
125 - ar_comment clob(1K),
126 - ar_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
127 - ar_user_text VARCHAR(255) NOT NULL,
128 - ar_timestamp TIMESTAMP NOT NULL,
129 - ar_minor_edit SMALLINT NOT NULL DEFAULT 0,
130 - ar_flags clob(1K),
131 - ar_rev_id INTEGER,
132 - ar_text_id INTEGER,
133 - ar_deleted SMALLINT NOT NULL DEFAULT 0,
134 - ar_len INTEGER
135 -);
136 -CREATE INDEX archive_name_title_timestamp ON archive (ar_namespace,ar_title,ar_timestamp);
137 -CREATE INDEX archive_user_text ON archive (ar_user_text);
138 -
139 -
140 -
141 -CREATE TABLE redirect (
142 - rd_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
143 - rd_namespace SMALLINT NOT NULL,
144 - rd_title VARCHAR(255) NOT NULL
145 -);
146 -CREATE INDEX redirect_ns_title ON redirect (rd_namespace,rd_title,rd_from);
147 -
148 -
149 -CREATE TABLE pagelinks (
150 - pl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
151 - pl_namespace SMALLINT NOT NULL,
152 - pl_title VARCHAR(255) NOT NULL
153 -);
154 -CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title);
155 -
156 -CREATE TABLE templatelinks (
157 - tl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
158 - tl_namespace SMALLINT NOT NULL,
159 - tl_title VARCHAR(255) NOT NULL
160 -);
161 -CREATE UNIQUE INDEX templatelinks_unique ON templatelinks (tl_namespace,tl_title,tl_from);
162 -
163 -CREATE TABLE imagelinks (
164 - il_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
165 - il_to VARCHAR(255) NOT NULL
166 -);
167 -CREATE UNIQUE INDEX il_from ON imagelinks (il_to,il_from);
168 -
169 -CREATE TABLE categorylinks (
170 - cl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
171 - cl_to VARCHAR(255) NOT NULL,
172 - cl_sortkey VARCHAR(255),
173 - cl_timestamp TIMESTAMP NOT NULL
174 -);
175 -CREATE UNIQUE INDEX cl_from ON categorylinks (cl_from, cl_to);
176 -CREATE INDEX cl_sortkey ON categorylinks (cl_to, cl_sortkey, cl_from);
177 -
178 -
179 -
180 -CREATE TABLE externallinks (
181 - el_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
182 - el_to VARCHAR(255) NOT NULL,
183 - el_index VARCHAR(255) NOT NULL
184 -);
185 -CREATE INDEX externallinks_from_to ON externallinks (el_from,el_to);
186 -CREATE INDEX externallinks_index ON externallinks (el_index);
187 -
188 -CREATE TABLE langlinks (
189 - ll_from INTEGER NOT NULL REFERENCES page (page_id) ON DELETE CASCADE,
190 - ll_lang VARCHAR(255),
191 - ll_title VARCHAR(255)
192 -);
193 -CREATE UNIQUE INDEX langlinks_unique ON langlinks (ll_from,ll_lang);
194 -CREATE INDEX langlinks_lang_title ON langlinks (ll_lang,ll_title);
195 -
196 -
197 -CREATE TABLE site_stats (
198 - ss_row_id INTEGER NOT NULL UNIQUE,
199 - ss_total_views INTEGER DEFAULT 0,
200 - ss_total_edits INTEGER DEFAULT 0,
201 - ss_good_articles INTEGER DEFAULT 0,
202 - ss_total_pages INTEGER DEFAULT -1,
203 - ss_users INTEGER DEFAULT -1,
204 - ss_admins INTEGER DEFAULT -1,
205 - ss_images INTEGER DEFAULT 0
206 -);
207 -
208 -CREATE TABLE hitcounter (
209 - hc_id BIGINT NOT NULL
210 -);
211 -
212 -CREATE SEQUENCE ipblocks_ipb_id_val;
213 -CREATE TABLE ipblocks (
214 - ipb_id INTEGER NOT NULL PRIMARY KEY,
215 - --DEFAULT nextval('ipblocks_ipb_id_val'),
216 - ipb_address VARCHAR(255),
217 - ipb_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
218 - ipb_by INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
219 - ipb_by_text VARCHAR(255) NOT NULL DEFAULT '',
220 - ipb_reason VARCHAR(255) NOT NULL,
221 - ipb_timestamp TIMESTAMP NOT NULL,
222 - ipb_auto SMALLINT NOT NULL DEFAULT 0,
223 - ipb_anon_only SMALLINT NOT NULL DEFAULT 0,
224 - ipb_create_account SMALLINT NOT NULL DEFAULT 1,
225 - ipb_enable_autoblock SMALLINT NOT NULL DEFAULT 1,
226 - ipb_expiry TIMESTAMP NOT NULL,
227 - ipb_range_start VARCHAR(255),
228 - ipb_range_end VARCHAR(255),
229 - ipb_deleted SMALLINT NOT NULL DEFAULT 0,
230 - ipb_block_email SMALLINT NOT NULL DEFAULT 0
231 -
232 -);
233 -CREATE INDEX ipb_address ON ipblocks (ipb_address);
234 -CREATE INDEX ipb_user ON ipblocks (ipb_user);
235 -CREATE INDEX ipb_range ON ipblocks (ipb_range_start,ipb_range_end);
236 -
237 -
238 -
239 -CREATE TABLE image (
240 - img_name VARCHAR(255) NOT NULL PRIMARY KEY,
241 - img_size INTEGER NOT NULL,
242 - img_width INTEGER NOT NULL,
243 - img_height INTEGER NOT NULL,
244 - img_metadata CLOB(16M) NOT NULL DEFAULT '',
245 - img_bits SMALLINT,
246 - img_media_type VARCHAR(255),
247 - img_major_mime VARCHAR(255) DEFAULT 'unknown',
248 - img_minor_mime VARCHAR(255) DEFAULT 'unknown',
249 - img_description clob(1K) NOT NULL DEFAULT '',
250 - img_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
251 - img_user_text VARCHAR(255) NOT NULL DEFAULT '',
252 - img_timestamp TIMESTAMP,
253 - img_sha1 VARCHAR(255) NOT NULL DEFAULT ''
254 -);
255 -CREATE INDEX img_size_idx ON image (img_size);
256 -CREATE INDEX img_timestamp_idx ON image (img_timestamp);
257 -CREATE INDEX img_sha1 ON image (img_sha1);
258 -
259 -CREATE TABLE oldimage (
260 - oi_name VARCHAR(255) NOT NULL,
261 - oi_archive_name VARCHAR(255) NOT NULL,
262 - oi_size INTEGER NOT NULL,
263 - oi_width INTEGER NOT NULL,
264 - oi_height INTEGER NOT NULL,
265 - oi_bits SMALLINT NOT NULL,
266 - oi_description clob(1K),
267 - oi_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
268 - oi_user_text VARCHAR(255) NOT NULL,
269 - oi_timestamp TIMESTAMP NOT NULL,
270 - oi_metadata CLOB(16M) NOT NULL DEFAULT '',
271 - oi_media_type VARCHAR(255) ,
272 - oi_major_mime VARCHAR(255) NOT NULL DEFAULT 'unknown',
273 - oi_minor_mime VARCHAR(255) NOT NULL DEFAULT 'unknown',
274 - oi_deleted SMALLINT NOT NULL DEFAULT 0,
275 - oi_sha1 VARCHAR(255) NOT NULL DEFAULT '',
276 - FOREIGN KEY (oi_name) REFERENCES image(img_name) ON DELETE CASCADE
277 -);
278 -CREATE INDEX oi_name_timestamp ON oldimage (oi_name,oi_timestamp);
279 -CREATE INDEX oi_name_archive_name ON oldimage (oi_name,oi_archive_name);
280 -CREATE INDEX oi_sha1 ON oldimage (oi_sha1);
281 -
282 -
283 -CREATE SEQUENCE filearchive_fa_id_seq;
284 -CREATE TABLE filearchive (
285 - fa_id INTEGER NOT NULL PRIMARY KEY,
286 - --PRIMARY KEY DEFAULT nextval('filearchive_fa_id_seq'),
287 - fa_name VARCHAR(255) NOT NULL,
288 - fa_archive_name VARCHAR(255),
289 - fa_storage_group VARCHAR(255),
290 - fa_storage_key VARCHAR(255),
291 - fa_deleted_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
292 - fa_deleted_timestamp TIMESTAMP NOT NULL,
293 - fa_deleted_reason VARCHAR(255),
294 - fa_size INTEGER NOT NULL,
295 - fa_width INTEGER NOT NULL,
296 - fa_height INTEGER NOT NULL,
297 - fa_metadata CLOB(16M) NOT NULL DEFAULT '',
298 - fa_bits SMALLINT,
299 - fa_media_type VARCHAR(255),
300 - fa_major_mime VARCHAR(255) DEFAULT 'unknown',
301 - fa_minor_mime VARCHAR(255) DEFAULT 'unknown',
302 - fa_description clob(1K) NOT NULL,
303 - fa_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
304 - fa_user_text VARCHAR(255) NOT NULL,
305 - fa_timestamp TIMESTAMP,
306 - fa_deleted SMALLINT NOT NULL DEFAULT 0
307 -);
308 -CREATE INDEX fa_name_time ON filearchive (fa_name, fa_timestamp);
309 -CREATE INDEX fa_dupe ON filearchive (fa_storage_group, fa_storage_key);
310 -CREATE INDEX fa_notime ON filearchive (fa_deleted_timestamp);
311 -CREATE INDEX fa_nouser ON filearchive (fa_deleted_user);
312 -
313 -CREATE SEQUENCE rc_rc_id_seq;
314 -CREATE TABLE recentchanges (
315 - rc_id INTEGER NOT NULL PRIMARY KEY,
316 - --PRIMARY KEY DEFAULT nextval('rc_rc_id_seq'),
317 - rc_timestamp TIMESTAMP NOT NULL,
318 - rc_cur_time TIMESTAMP NOT NULL,
319 - rc_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
320 - rc_user_text VARCHAR(255) NOT NULL,
321 - rc_namespace SMALLINT NOT NULL,
322 - rc_title VARCHAR(255) NOT NULL,
323 - rc_comment VARCHAR(255),
324 - rc_minor SMALLINT NOT NULL DEFAULT 0,
325 - rc_bot SMALLINT NOT NULL DEFAULT 0,
326 - rc_new SMALLINT NOT NULL DEFAULT 0,
327 - rc_cur_id INTEGER REFERENCES page(page_id) ON DELETE SET NULL,
328 - rc_this_oldid INTEGER NOT NULL,
329 - rc_last_oldid INTEGER NOT NULL,
330 - rc_type SMALLINT NOT NULL DEFAULT 0,
331 - rc_moved_to_ns SMALLINT,
332 - rc_moved_to_title VARCHAR(255),
333 - rc_patrolled SMALLINT NOT NULL DEFAULT 0,
334 - rc_ip VARCHAR(255), -- was CIDR type
335 - rc_old_len INTEGER,
336 - rc_new_len INTEGER,
337 - rc_deleted SMALLINT NOT NULL DEFAULT 0,
338 - rc_logid INTEGER NOT NULL DEFAULT 0,
339 - rc_log_type VARCHAR(255),
340 - rc_log_action VARCHAR(255),
341 - rc_params CLOB(64K)
342 -);
343 -CREATE INDEX rc_timestamp ON recentchanges (rc_timestamp);
344 -CREATE INDEX rc_namespace_title ON recentchanges (rc_namespace, rc_title);
345 -CREATE INDEX rc_cur_id ON recentchanges (rc_cur_id);
346 -CREATE INDEX new_name_timestamp ON recentchanges (rc_new, rc_namespace, rc_timestamp);
347 -CREATE INDEX rc_ip ON recentchanges (rc_ip);
348 -
349 -
350 -
351 -CREATE TABLE watchlist (
352 - wl_user INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
353 - wl_namespace SMALLINT NOT NULL DEFAULT 0,
354 - wl_title VARCHAR(255) NOT NULL,
355 - wl_notificationtimestamp TIMESTAMP
356 -);
357 -CREATE UNIQUE INDEX wl_user_namespace_title ON watchlist (wl_namespace, wl_title, wl_user);
358 -
359 -
360 -CREATE TABLE math (
361 - math_inputhash VARGRAPHIC(255) NOT NULL UNIQUE,
362 - math_outputhash VARGRAPHIC(255) NOT NULL,
363 - math_html_conservativeness SMALLINT NOT NULL,
364 - math_html VARCHAR(255),
365 - math_mathml VARCHAR(255)
366 -);
367 -
368 -
369 -CREATE TABLE interwiki (
370 - iw_prefix VARCHAR(255) NOT NULL UNIQUE,
371 - iw_url CLOB(64K) NOT NULL,
372 - iw_local SMALLINT NOT NULL,
373 - iw_trans SMALLINT NOT NULL DEFAULT 0
374 -);
375 -
376 -
377 -CREATE TABLE querycache (
378 - qc_type VARCHAR(255) NOT NULL,
379 - qc_value INTEGER NOT NULL,
380 - qc_namespace SMALLINT NOT NULL,
381 - qc_title VARCHAR(255) NOT NULL
382 -);
383 -CREATE INDEX querycache_type_value ON querycache (qc_type, qc_value);
384 -
385 -
386 -
387 -CREATE TABLE querycache_info (
388 - qci_type VARCHAR(255) UNIQUE NOT NULL,
389 - qci_timestamp TIMESTAMP
390 -);
391 -
392 -
393 -CREATE TABLE querycachetwo (
394 - qcc_type VARCHAR(255) NOT NULL,
395 - qcc_value INTEGER NOT NULL DEFAULT 0,
396 - qcc_namespace INTEGER NOT NULL DEFAULT 0,
397 - qcc_title VARCHAR(255) NOT NULL DEFAULT '',
398 - qcc_namespacetwo INTEGER NOT NULL DEFAULT 0,
399 - qcc_titletwo VARCHAR(255) NOT NULL DEFAULT ''
400 -);
401 -CREATE INDEX querycachetwo_type_value ON querycachetwo (qcc_type, qcc_value);
402 -CREATE INDEX querycachetwo_title ON querycachetwo (qcc_type,qcc_namespace,qcc_title);
403 -CREATE INDEX querycachetwo_titletwo ON querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo);
404 -
405 -CREATE TABLE objectcache (
406 - keyname VARCHAR(255) NOT NULL UNIQUE, -- was nullable
407 - value CLOB(16M) NOT NULL DEFAULT '',
408 - exptime TIMESTAMP NOT NULL
409 -);
410 -CREATE INDEX objectcacache_exptime ON objectcache (exptime);
411 -
412 -
413 -
414 -CREATE TABLE transcache (
415 - tc_url VARCHAR(255) NOT NULL UNIQUE,
416 - tc_contents VARCHAR(255) NOT NULL,
417 - tc_time TIMESTAMP NOT NULL
418 -);
419 -
420 -CREATE SEQUENCE log_log_id_seq;
421 -CREATE TABLE logging (
422 - log_id INTEGER NOT NULL PRIMARY KEY,
423 - --PRIMARY KEY DEFAULT nextval('log_log_id_seq'),
424 - log_type VARCHAR(255) NOT NULL,
425 - log_action VARCHAR(255) NOT NULL,
426 - log_timestamp TIMESTAMP NOT NULL,
427 - log_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
428 - log_namespace SMALLINT NOT NULL,
429 - log_title VARCHAR(255) NOT NULL,
430 - log_comment VARCHAR(255),
431 - log_params CLOB(64K),
432 - log_deleted SMALLINT NOT NULL DEFAULT 0
433 -);
434 -CREATE INDEX logging_type_name ON logging (log_type, log_timestamp);
435 -CREATE INDEX logging_user_time ON logging (log_timestamp, log_user);
436 -CREATE INDEX logging_page_time ON logging (log_namespace, log_title, log_timestamp);
437 -
438 -CREATE SEQUENCE trackbacks_tb_id_seq;
439 -CREATE TABLE trackbacks (
440 - tb_id INTEGER NOT NULL PRIMARY KEY,
441 - --PRIMARY KEY DEFAULT nextval('trackbacks_tb_id_seq'),
442 - tb_page INTEGER REFERENCES page(page_id) ON DELETE CASCADE,
443 - tb_title VARCHAR(255) NOT NULL,
444 - tb_url CLOB(64K) NOT NULL,
445 - tb_ex VARCHAR(255),
446 - tb_name VARCHAR(255)
447 -);
448 -CREATE INDEX trackback_page ON trackbacks (tb_page);
449 -
450 -
451 -CREATE SEQUENCE job_job_id_seq;
452 -CREATE TABLE job (
453 - job_id INTEGER NOT NULL PRIMARY KEY,
454 - --PRIMARY KEY DEFAULT nextval('job_job_id_seq'),
455 - job_cmd VARCHAR(255) NOT NULL,
456 - job_namespace SMALLINT NOT NULL,
457 - job_title VARCHAR(255) NOT NULL,
458 - job_params CLOB(64K) NOT NULL
459 -);
460 -CREATE INDEX job_cmd_namespace_title ON job (job_cmd, job_namespace, job_title);
461 -
462 -
463 -
464 -
465 -
466 -
467 -
468 -
469 -
470 -
471 -
472 -CREATE TABLE searchindex (
473 - si_page int NOT NULL,
474 - si_title varchar(255) NOT NULL default '',
475 - si_text clob NOT NULL
476 -);
477 -
478 -CREATE TABLE profiling (
479 - pf_count INTEGER NOT NULL DEFAULT 0,
480 - pf_time NUMERIC(18,10) NOT NULL DEFAULT 0,
481 - pf_memory NUMERIC(18,10) NOT NULL DEFAULT 0,
482 - pf_name VARCHAR(255) NOT NULL,
483 - pf_server VARCHAR(255)
484 -);
485 -CREATE UNIQUE INDEX pf_name_server ON profiling (pf_name, pf_server);
486 -
487 -CREATE TABLE protected_titles (
488 - pt_namespace SMALLINT NOT NULL,
489 - pt_title VARCHAR(255) NOT NULL,
490 - pt_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
491 - pt_reason clob(1K),
492 - pt_timestamp TIMESTAMP NOT NULL,
493 - pt_expiry TIMESTAMP ,
494 - pt_create_perm VARCHAR(255) NOT NULL DEFAULT ''
495 -);
496 -CREATE UNIQUE INDEX protected_titles_unique ON protected_titles(pt_namespace, pt_title);
497 -
498 -
499 -
500 -CREATE TABLE updatelog (
501 - ul_key VARCHAR(255) NOT NULL PRIMARY KEY
502 -);
503 -
504 -CREATE SEQUENCE category_id_seq;
505 -CREATE TABLE category (
506 - cat_id INTEGER NOT NULL PRIMARY KEY,
507 - --PRIMARY KEY DEFAULT nextval('category_id_seq'),
508 - cat_title VARCHAR(255) NOT NULL,
509 - cat_pages INTEGER NOT NULL DEFAULT 0,
510 - cat_subcats INTEGER NOT NULL DEFAULT 0,
511 - cat_files INTEGER NOT NULL DEFAULT 0,
512 - cat_hidden SMALLINT NOT NULL DEFAULT 0
513 -);
514 -CREATE UNIQUE INDEX category_title ON category(cat_title);
515 -CREATE INDEX category_pages ON category(cat_pages);
516 -
517 -CREATE TABLE mediawiki_version (
518 - type VARCHAR(255) NOT NULL,
519 - mw_version VARCHAR(255) NOT NULL,
520 - notes VARCHAR(255) ,
521 -
522 - pg_version VARCHAR(255) ,
523 - pg_dbname VARCHAR(255) ,
524 - pg_user VARCHAR(255) ,
525 - pg_port VARCHAR(255) ,
526 - mw_schema VARCHAR(255) ,
527 - ts2_schema VARCHAR(255) ,
528 - ctype VARCHAR(255) ,
529 -
530 - sql_version VARCHAR(255) ,
531 - sql_date VARCHAR(255) ,
532 - cdate TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP
533 -);
534 -
535 -INSERT INTO mediawiki_version (type,mw_version,sql_version,sql_date)
536 - VALUES ('Creation','??','$LastChangedRevision: 34049 $','$LastChangedDate: 2008-04-30 10:20:36 -0400 (Wed, 30 Apr 2008) $');
537 -
 2+-- DB2
 3+
 4+-- SQL to create the initial tables for the MediaWiki database.
 5+-- This is read and executed by the install script; you should
 6+-- not have to run it by itself unless doing a manual install.
 7+-- This is the IBM DB2 version.
 8+-- For information about each table, please see the notes in maintenance/tables.sql
 9+-- Please make sure all dollar-quoting uses $mw$ at the start of the line
 10+-- TODO: Change CHAR/SMALLINT to BOOL (still used in a non-bool fashion in PHP code)
 11+
 12+
 13+
 14+
 15+CREATE SEQUENCE user_user_id_seq AS INTEGER START WITH 0 INCREMENT BY 1;
 16+CREATE TABLE mwuser ( -- replace reserved word 'user'
 17+ user_id INTEGER NOT NULL PRIMARY KEY, -- DEFAULT nextval('user_user_id_seq'),
 18+ user_name VARCHAR(255) NOT NULL UNIQUE,
 19+ user_real_name VARCHAR(255),
 20+ user_password clob(1K),
 21+ user_newpassword clob(1K),
 22+ user_newpass_time TIMESTAMP,
 23+ user_token VARCHAR(255),
 24+ user_email VARCHAR(255),
 25+ user_email_token VARCHAR(255),
 26+ user_email_token_expires TIMESTAMP,
 27+ user_email_authenticated TIMESTAMP,
 28+ user_options CLOB(64K),
 29+ user_touched TIMESTAMP,
 30+ user_registration TIMESTAMP,
 31+ user_editcount INTEGER
 32+);
 33+CREATE INDEX user_email_token_idx ON mwuser (user_email_token);
 34+
 35+-- Create a dummy user to satisfy fk contraints especially with revisions
 36+INSERT INTO mwuser
 37+ VALUES (NEXTVAL FOR user_user_id_seq,'Anonymous','', NULL,NULL,CURRENT_TIMESTAMP,NULL, NULL,NULL,NULL,NULL, NULL,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,0);
 38+
 39+CREATE TABLE user_groups (
 40+ ug_user INTEGER REFERENCES mwuser(user_id) ON DELETE CASCADE,
 41+ ug_group VARCHAR(255) NOT NULL
 42+);
 43+CREATE UNIQUE INDEX user_groups_unique ON user_groups (ug_user, ug_group);
 44+
 45+CREATE TABLE user_newtalk (
 46+ user_id INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
 47+ user_ip VARCHAR(255),
 48+ user_last_timestamp TIMESTAMP
 49+);
 50+CREATE INDEX user_newtalk_id_idx ON user_newtalk (user_id);
 51+CREATE INDEX user_newtalk_ip_idx ON user_newtalk (user_ip);
 52+
 53+
 54+CREATE SEQUENCE page_page_id_seq;
 55+CREATE TABLE page (
 56+ page_id INTEGER NOT NULL PRIMARY KEY, -- DEFAULT NEXT VALUE FOR user_user_id_seq,
 57+ page_namespace SMALLINT NOT NULL,
 58+ page_title VARCHAR(255) NOT NULL,
 59+ page_restrictions clob(1K),
 60+ page_counter BIGINT NOT NULL DEFAULT 0,
 61+ page_is_redirect SMALLINT NOT NULL DEFAULT 0,
 62+ page_is_new SMALLINT NOT NULL DEFAULT 0,
 63+ page_random NUMERIC(15,14) NOT NULL,
 64+ page_touched TIMESTAMP,
 65+ page_latest INTEGER NOT NULL, -- FK?
 66+ page_len INTEGER NOT NULL
 67+);
 68+CREATE UNIQUE INDEX page_unique_name ON page (page_namespace, page_title);
 69+--CREATE INDEX page_main_title ON page (page_title) WHERE page_namespace = 0;
 70+--CREATE INDEX page_talk_title ON page (page_title) WHERE page_namespace = 1;
 71+--CREATE INDEX page_user_title ON page (page_title) WHERE page_namespace = 2;
 72+--CREATE INDEX page_utalk_title ON page (page_title) WHERE page_namespace = 3;
 73+--CREATE INDEX page_project_title ON page (page_title) WHERE page_namespace = 4;
 74+CREATE INDEX page_random_idx ON page (page_random);
 75+CREATE INDEX page_len_idx ON page (page_len);
 76+
 77+--CREATE FUNCTION page_deleted() RETURNS TRIGGER LANGUAGE plpgsql AS
 78+--$mw$
 79+--BEGIN
 80+--DELETE FROM recentchanges WHERE rc_namespace = OLD.page_namespace AND rc_title = OLD.page_title;
 81+--RETURN NULL;
 82+--END;
 83+--$mw$;
 84+
 85+--CREATE TRIGGER page_deleted AFTER DELETE ON page
 86+-- FOR EACH ROW EXECUTE PROCEDURE page_deleted();
 87+
 88+CREATE SEQUENCE rev_rev_id_val;
 89+CREATE TABLE revision (
 90+ rev_id INTEGER NOT NULL UNIQUE, --DEFAULT nextval('rev_rev_id_val'),
 91+ rev_page INTEGER REFERENCES page (page_id) ON DELETE CASCADE,
 92+ rev_text_id INTEGER, -- FK
 93+ rev_comment clob(1K), -- changed from VARCHAR(255)
 94+ rev_user INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE RESTRICT,
 95+ rev_user_text VARCHAR(255) NOT NULL,
 96+ rev_timestamp TIMESTAMP NOT NULL,
 97+ rev_minor_edit SMALLINT NOT NULL DEFAULT 0,
 98+ rev_deleted SMALLINT NOT NULL DEFAULT 0,
 99+ rev_len INTEGER,
 100+ rev_parent_id INTEGER
 101+);
 102+CREATE UNIQUE INDEX revision_unique ON revision (rev_page, rev_id);
 103+CREATE INDEX rev_text_id_idx ON revision (rev_text_id);
 104+CREATE INDEX rev_timestamp_idx ON revision (rev_timestamp);
 105+CREATE INDEX rev_user_idx ON revision (rev_user);
 106+CREATE INDEX rev_user_text_idx ON revision (rev_user_text);
 107+
 108+
 109+CREATE SEQUENCE text_old_id_val;
 110+CREATE TABLE pagecontent ( -- replaces reserved word 'text'
 111+ old_id INTEGER NOT NULL,
 112+ --PRIMARY KEY DEFAULT nextval('text_old_id_val'),
 113+ old_text CLOB(16M),
 114+ old_flags clob(1K)
 115+);
 116+
 117+CREATE SEQUENCE pr_id_val;
 118+CREATE TABLE page_restrictions (
 119+ pr_id INTEGER NOT NULL UNIQUE,
 120+ --DEFAULT nextval('pr_id_val'),
 121+ pr_page INTEGER NOT NULL
 122+ --(used to be nullable)
 123+ REFERENCES page (page_id) ON DELETE CASCADE,
 124+ pr_type VARCHAR(255) NOT NULL,
 125+ pr_level VARCHAR(255) NOT NULL,
 126+ pr_cascade SMALLINT NOT NULL,
 127+ pr_user INTEGER,
 128+ pr_expiry TIMESTAMP,
 129+ PRIMARY KEY (pr_page, pr_type)
 130+);
 131+--ALTER TABLE page_restrictions ADD CONSTRAINT page_restrictions_pk PRIMARY KEY (pr_page,pr_type);
 132+
 133+CREATE TABLE page_props (
 134+ pp_page INTEGER NOT NULL REFERENCES page (page_id) ON DELETE CASCADE,
 135+ pp_propname VARCHAR(255) NOT NULL,
 136+ pp_value CLOB(64K) NOT NULL,
 137+ PRIMARY KEY (pp_page,pp_propname)
 138+);
 139+--ALTER TABLE page_props ADD CONSTRAINT page_props_pk PRIMARY KEY (pp_page,pp_propname);
 140+CREATE INDEX page_props_propname ON page_props (pp_propname);
 141+
 142+
 143+
 144+CREATE TABLE archive (
 145+ ar_namespace SMALLINT NOT NULL,
 146+ ar_title VARCHAR(255) NOT NULL,
 147+ ar_text CLOB(16M),
 148+ ar_page_id INTEGER,
 149+ ar_parent_id INTEGER,
 150+ ar_comment clob(1K),
 151+ ar_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 152+ ar_user_text VARCHAR(255) NOT NULL,
 153+ ar_timestamp TIMESTAMP NOT NULL,
 154+ ar_minor_edit SMALLINT NOT NULL DEFAULT 0,
 155+ ar_flags clob(1K),
 156+ ar_rev_id INTEGER,
 157+ ar_text_id INTEGER,
 158+ ar_deleted SMALLINT NOT NULL DEFAULT 0,
 159+ ar_len INTEGER
 160+);
 161+CREATE INDEX archive_name_title_timestamp ON archive (ar_namespace,ar_title,ar_timestamp);
 162+CREATE INDEX archive_user_text ON archive (ar_user_text);
 163+
 164+
 165+
 166+CREATE TABLE redirect (
 167+ rd_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
 168+ rd_namespace SMALLINT NOT NULL,
 169+ rd_title VARCHAR(255) NOT NULL
 170+);
 171+CREATE INDEX redirect_ns_title ON redirect (rd_namespace,rd_title,rd_from);
 172+
 173+
 174+CREATE TABLE pagelinks (
 175+ pl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
 176+ pl_namespace SMALLINT NOT NULL,
 177+ pl_title VARCHAR(255) NOT NULL
 178+);
 179+CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title);
 180+
 181+CREATE TABLE templatelinks (
 182+ tl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
 183+ tl_namespace SMALLINT NOT NULL,
 184+ tl_title VARCHAR(255) NOT NULL
 185+);
 186+CREATE UNIQUE INDEX templatelinks_unique ON templatelinks (tl_namespace,tl_title,tl_from);
 187+
 188+CREATE TABLE imagelinks (
 189+ il_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
 190+ il_to VARCHAR(255) NOT NULL
 191+);
 192+CREATE UNIQUE INDEX il_from ON imagelinks (il_to,il_from);
 193+
 194+CREATE TABLE categorylinks (
 195+ cl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
 196+ cl_to VARCHAR(255) NOT NULL,
 197+ cl_sortkey VARCHAR(255),
 198+ cl_timestamp TIMESTAMP NOT NULL
 199+);
 200+CREATE UNIQUE INDEX cl_from ON categorylinks (cl_from, cl_to);
 201+CREATE INDEX cl_sortkey ON categorylinks (cl_to, cl_sortkey, cl_from);
 202+
 203+
 204+
 205+CREATE TABLE externallinks (
 206+ el_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
 207+ el_to VARCHAR(255) NOT NULL,
 208+ el_index VARCHAR(255) NOT NULL
 209+);
 210+CREATE INDEX externallinks_from_to ON externallinks (el_from,el_to);
 211+CREATE INDEX externallinks_index ON externallinks (el_index);
 212+
 213+CREATE TABLE langlinks (
 214+ ll_from INTEGER NOT NULL REFERENCES page (page_id) ON DELETE CASCADE,
 215+ ll_lang VARCHAR(255),
 216+ ll_title VARCHAR(255)
 217+);
 218+CREATE UNIQUE INDEX langlinks_unique ON langlinks (ll_from,ll_lang);
 219+CREATE INDEX langlinks_lang_title ON langlinks (ll_lang,ll_title);
 220+
 221+
 222+CREATE TABLE site_stats (
 223+ ss_row_id INTEGER NOT NULL UNIQUE,
 224+ ss_total_views INTEGER DEFAULT 0,
 225+ ss_total_edits INTEGER DEFAULT 0,
 226+ ss_good_articles INTEGER DEFAULT 0,
 227+ ss_total_pages INTEGER DEFAULT -1,
 228+ ss_users INTEGER DEFAULT -1,
 229+ ss_admins INTEGER DEFAULT -1,
 230+ ss_images INTEGER DEFAULT 0
 231+);
 232+
 233+CREATE TABLE hitcounter (
 234+ hc_id BIGINT NOT NULL
 235+);
 236+
 237+CREATE SEQUENCE ipblocks_ipb_id_val;
 238+CREATE TABLE ipblocks (
 239+ ipb_id INTEGER NOT NULL PRIMARY KEY,
 240+ --DEFAULT nextval('ipblocks_ipb_id_val'),
 241+ ipb_address VARCHAR(255),
 242+ ipb_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 243+ ipb_by INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
 244+ ipb_by_text VARCHAR(255) NOT NULL DEFAULT '',
 245+ ipb_reason VARCHAR(255) NOT NULL,
 246+ ipb_timestamp TIMESTAMP NOT NULL,
 247+ ipb_auto SMALLINT NOT NULL DEFAULT 0,
 248+ ipb_anon_only SMALLINT NOT NULL DEFAULT 0,
 249+ ipb_create_account SMALLINT NOT NULL DEFAULT 1,
 250+ ipb_enable_autoblock SMALLINT NOT NULL DEFAULT 1,
 251+ ipb_expiry TIMESTAMP NOT NULL,
 252+ ipb_range_start VARCHAR(255),
 253+ ipb_range_end VARCHAR(255),
 254+ ipb_deleted SMALLINT NOT NULL DEFAULT 0,
 255+ ipb_block_email SMALLINT NOT NULL DEFAULT 0
 256+
 257+);
 258+CREATE INDEX ipb_address ON ipblocks (ipb_address);
 259+CREATE INDEX ipb_user ON ipblocks (ipb_user);
 260+CREATE INDEX ipb_range ON ipblocks (ipb_range_start,ipb_range_end);
 261+
 262+
 263+
 264+CREATE TABLE image (
 265+ img_name VARCHAR(255) NOT NULL PRIMARY KEY,
 266+ img_size INTEGER NOT NULL,
 267+ img_width INTEGER NOT NULL,
 268+ img_height INTEGER NOT NULL,
 269+ img_metadata CLOB(16M) NOT NULL DEFAULT '',
 270+ img_bits SMALLINT,
 271+ img_media_type VARCHAR(255),
 272+ img_major_mime VARCHAR(255) DEFAULT 'unknown',
 273+ img_minor_mime VARCHAR(255) DEFAULT 'unknown',
 274+ img_description clob(1K) NOT NULL DEFAULT '',
 275+ img_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 276+ img_user_text VARCHAR(255) NOT NULL DEFAULT '',
 277+ img_timestamp TIMESTAMP,
 278+ img_sha1 VARCHAR(255) NOT NULL DEFAULT ''
 279+);
 280+CREATE INDEX img_size_idx ON image (img_size);
 281+CREATE INDEX img_timestamp_idx ON image (img_timestamp);
 282+CREATE INDEX img_sha1 ON image (img_sha1);
 283+
 284+CREATE TABLE oldimage (
 285+ oi_name VARCHAR(255) NOT NULL,
 286+ oi_archive_name VARCHAR(255) NOT NULL,
 287+ oi_size INTEGER NOT NULL,
 288+ oi_width INTEGER NOT NULL,
 289+ oi_height INTEGER NOT NULL,
 290+ oi_bits SMALLINT NOT NULL,
 291+ oi_description clob(1K),
 292+ oi_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 293+ oi_user_text VARCHAR(255) NOT NULL,
 294+ oi_timestamp TIMESTAMP NOT NULL,
 295+ oi_metadata CLOB(16M) NOT NULL DEFAULT '',
 296+ oi_media_type VARCHAR(255) ,
 297+ oi_major_mime VARCHAR(255) NOT NULL DEFAULT 'unknown',
 298+ oi_minor_mime VARCHAR(255) NOT NULL DEFAULT 'unknown',
 299+ oi_deleted SMALLINT NOT NULL DEFAULT 0,
 300+ oi_sha1 VARCHAR(255) NOT NULL DEFAULT '',
 301+ FOREIGN KEY (oi_name) REFERENCES image(img_name) ON DELETE CASCADE
 302+);
 303+--ALTER TABLE oldimage ADD CONSTRAINT oldimage_oi_name_fkey_cascade FOREIGN KEY (oi_name) REFERENCES image(img_name) ON DELETE CASCADE;
 304+CREATE INDEX oi_name_timestamp ON oldimage (oi_name,oi_timestamp);
 305+CREATE INDEX oi_name_archive_name ON oldimage (oi_name,oi_archive_name);
 306+CREATE INDEX oi_sha1 ON oldimage (oi_sha1);
 307+
 308+
 309+CREATE SEQUENCE filearchive_fa_id_seq;
 310+CREATE TABLE filearchive (
 311+ fa_id INTEGER NOT NULL PRIMARY KEY,
 312+ --PRIMARY KEY DEFAULT nextval('filearchive_fa_id_seq'),
 313+ fa_name VARCHAR(255) NOT NULL,
 314+ fa_archive_name VARCHAR(255),
 315+ fa_storage_group VARCHAR(255),
 316+ fa_storage_key VARCHAR(255),
 317+ fa_deleted_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 318+ fa_deleted_timestamp TIMESTAMP NOT NULL,
 319+ fa_deleted_reason VARCHAR(255),
 320+ fa_size INTEGER NOT NULL,
 321+ fa_width INTEGER NOT NULL,
 322+ fa_height INTEGER NOT NULL,
 323+ fa_metadata CLOB(16M) NOT NULL DEFAULT '',
 324+ fa_bits SMALLINT,
 325+ fa_media_type VARCHAR(255),
 326+ fa_major_mime VARCHAR(255) DEFAULT 'unknown',
 327+ fa_minor_mime VARCHAR(255) DEFAULT 'unknown',
 328+ fa_description clob(1K) NOT NULL,
 329+ fa_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 330+ fa_user_text VARCHAR(255) NOT NULL,
 331+ fa_timestamp TIMESTAMP,
 332+ fa_deleted SMALLINT NOT NULL DEFAULT 0
 333+);
 334+CREATE INDEX fa_name_time ON filearchive (fa_name, fa_timestamp);
 335+CREATE INDEX fa_dupe ON filearchive (fa_storage_group, fa_storage_key);
 336+CREATE INDEX fa_notime ON filearchive (fa_deleted_timestamp);
 337+CREATE INDEX fa_nouser ON filearchive (fa_deleted_user);
 338+
 339+CREATE SEQUENCE rc_rc_id_seq;
 340+CREATE TABLE recentchanges (
 341+ rc_id INTEGER NOT NULL PRIMARY KEY,
 342+ --PRIMARY KEY DEFAULT nextval('rc_rc_id_seq'),
 343+ rc_timestamp TIMESTAMP NOT NULL,
 344+ rc_cur_time TIMESTAMP NOT NULL,
 345+ rc_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 346+ rc_user_text VARCHAR(255) NOT NULL,
 347+ rc_namespace SMALLINT NOT NULL,
 348+ rc_title VARCHAR(255) NOT NULL,
 349+ rc_comment VARCHAR(255),
 350+ rc_minor SMALLINT NOT NULL DEFAULT 0,
 351+ rc_bot SMALLINT NOT NULL DEFAULT 0,
 352+ rc_new SMALLINT NOT NULL DEFAULT 0,
 353+ rc_cur_id INTEGER REFERENCES page(page_id) ON DELETE SET NULL,
 354+ rc_this_oldid INTEGER NOT NULL,
 355+ rc_last_oldid INTEGER NOT NULL,
 356+ rc_type SMALLINT NOT NULL DEFAULT 0,
 357+ rc_moved_to_ns SMALLINT,
 358+ rc_moved_to_title VARCHAR(255),
 359+ rc_patrolled SMALLINT NOT NULL DEFAULT 0,
 360+ rc_ip VARCHAR(255), -- was CIDR type
 361+ rc_old_len INTEGER,
 362+ rc_new_len INTEGER,
 363+ rc_deleted SMALLINT NOT NULL DEFAULT 0,
 364+ rc_logid INTEGER NOT NULL DEFAULT 0,
 365+ rc_log_type VARCHAR(255),
 366+ rc_log_action VARCHAR(255),
 367+ rc_params CLOB(64K)
 368+);
 369+CREATE INDEX rc_timestamp ON recentchanges (rc_timestamp);
 370+CREATE INDEX rc_namespace_title ON recentchanges (rc_namespace, rc_title);
 371+CREATE INDEX rc_cur_id ON recentchanges (rc_cur_id);
 372+CREATE INDEX new_name_timestamp ON recentchanges (rc_new, rc_namespace, rc_timestamp);
 373+CREATE INDEX rc_ip ON recentchanges (rc_ip);
 374+
 375+
 376+
 377+CREATE TABLE watchlist (
 378+ wl_user INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
 379+ wl_namespace SMALLINT NOT NULL DEFAULT 0,
 380+ wl_title VARCHAR(255) NOT NULL,
 381+ wl_notificationtimestamp TIMESTAMP
 382+);
 383+CREATE UNIQUE INDEX wl_user_namespace_title ON watchlist (wl_namespace, wl_title, wl_user);
 384+
 385+
 386+CREATE TABLE math (
 387+ math_inputhash VARGRAPHIC(255) NOT NULL UNIQUE,
 388+ math_outputhash VARGRAPHIC(255) NOT NULL,
 389+ math_html_conservativeness SMALLINT NOT NULL,
 390+ math_html VARCHAR(255),
 391+ math_mathml VARCHAR(255)
 392+);
 393+
 394+
 395+CREATE TABLE interwiki (
 396+ iw_prefix VARCHAR(255) NOT NULL UNIQUE,
 397+ iw_url CLOB(64K) NOT NULL,
 398+ iw_local SMALLINT NOT NULL,
 399+ iw_trans SMALLINT NOT NULL DEFAULT 0
 400+);
 401+
 402+
 403+CREATE TABLE querycache (
 404+ qc_type VARCHAR(255) NOT NULL,
 405+ qc_value INTEGER NOT NULL,
 406+ qc_namespace SMALLINT NOT NULL,
 407+ qc_title VARCHAR(255) NOT NULL
 408+);
 409+CREATE INDEX querycache_type_value ON querycache (qc_type, qc_value);
 410+
 411+
 412+
 413+CREATE TABLE querycache_info (
 414+ qci_type VARCHAR(255) UNIQUE NOT NULL,
 415+ qci_timestamp TIMESTAMP
 416+);
 417+
 418+
 419+CREATE TABLE querycachetwo (
 420+ qcc_type VARCHAR(255) NOT NULL,
 421+ qcc_value INTEGER NOT NULL DEFAULT 0,
 422+ qcc_namespace INTEGER NOT NULL DEFAULT 0,
 423+ qcc_title VARCHAR(255) NOT NULL DEFAULT '',
 424+ qcc_namespacetwo INTEGER NOT NULL DEFAULT 0,
 425+ qcc_titletwo VARCHAR(255) NOT NULL DEFAULT ''
 426+);
 427+CREATE INDEX querycachetwo_type_value ON querycachetwo (qcc_type, qcc_value);
 428+CREATE INDEX querycachetwo_title ON querycachetwo (qcc_type,qcc_namespace,qcc_title);
 429+CREATE INDEX querycachetwo_titletwo ON querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo);
 430+
 431+CREATE TABLE objectcache (
 432+ keyname VARCHAR(255) NOT NULL UNIQUE, -- was nullable
 433+ value CLOB(16M) NOT NULL DEFAULT '',
 434+ exptime TIMESTAMP NOT NULL
 435+);
 436+CREATE INDEX objectcacache_exptime ON objectcache (exptime);
 437+
 438+
 439+
 440+CREATE TABLE transcache (
 441+ tc_url VARCHAR(255) NOT NULL UNIQUE,
 442+ tc_contents VARCHAR(255) NOT NULL,
 443+ tc_time TIMESTAMP NOT NULL
 444+);
 445+
 446+CREATE SEQUENCE log_log_id_seq;
 447+CREATE TABLE logging (
 448+ log_id INTEGER NOT NULL PRIMARY KEY,
 449+ --PRIMARY KEY DEFAULT nextval('log_log_id_seq'),
 450+ log_type VARCHAR(255) NOT NULL,
 451+ log_action VARCHAR(255) NOT NULL,
 452+ log_timestamp TIMESTAMP NOT NULL,
 453+ log_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 454+ log_namespace SMALLINT NOT NULL,
 455+ log_title VARCHAR(255) NOT NULL,
 456+ log_comment VARCHAR(255),
 457+ log_params CLOB(64K),
 458+ log_deleted SMALLINT NOT NULL DEFAULT 0
 459+);
 460+CREATE INDEX logging_type_name ON logging (log_type, log_timestamp);
 461+CREATE INDEX logging_user_time ON logging (log_timestamp, log_user);
 462+CREATE INDEX logging_page_time ON logging (log_namespace, log_title, log_timestamp);
 463+
 464+CREATE SEQUENCE trackbacks_tb_id_seq;
 465+CREATE TABLE trackbacks (
 466+ tb_id INTEGER NOT NULL PRIMARY KEY,
 467+ --PRIMARY KEY DEFAULT nextval('trackbacks_tb_id_seq'),
 468+ tb_page INTEGER REFERENCES page(page_id) ON DELETE CASCADE,
 469+ tb_title VARCHAR(255) NOT NULL,
 470+ tb_url CLOB(64K) NOT NULL,
 471+ tb_ex VARCHAR(255),
 472+ tb_name VARCHAR(255)
 473+);
 474+CREATE INDEX trackback_page ON trackbacks (tb_page);
 475+
 476+
 477+CREATE SEQUENCE job_job_id_seq;
 478+CREATE TABLE job (
 479+ job_id INTEGER NOT NULL PRIMARY KEY,
 480+ --PRIMARY KEY DEFAULT nextval('job_job_id_seq'),
 481+ job_cmd VARCHAR(255) NOT NULL,
 482+ job_namespace SMALLINT NOT NULL,
 483+ job_title VARCHAR(255) NOT NULL,
 484+ job_params CLOB(64K) NOT NULL
 485+);
 486+CREATE INDEX job_cmd_namespace_title ON job (job_cmd, job_namespace, job_title);
 487+
 488+
 489+
 490+-- Postgres' Tsearch2 dropped
 491+--ALTER TABLE page ADD titlevector tsvector;
 492+--CREATE FUNCTION ts2_page_title() RETURNS TRIGGER LANGUAGE plpgsql AS
 493+--$mw$
 494+--BEGIN
 495+--IF TG_OP = 'INSERT' THEN
 496+-- NEW.titlevector = to_tsvector('default',REPLACE(NEW.page_title,'/',' '));
 497+--ELSIF NEW.page_title != OLD.page_title THEN
 498+-- NEW.titlevector := to_tsvector('default',REPLACE(NEW.page_title,'/',' '));
 499+--END IF;
 500+--RETURN NEW;
 501+--END;
 502+--$mw$;
 503+
 504+--CREATE TRIGGER ts2_page_title BEFORE INSERT OR UPDATE ON page
 505+-- FOR EACH ROW EXECUTE PROCEDURE ts2_page_title();
 506+
 507+
 508+--ALTER TABLE pagecontent ADD textvector tsvector;
 509+--CREATE FUNCTION ts2_page_text() RETURNS TRIGGER LANGUAGE plpgsql AS
 510+--$mw$
 511+--BEGIN
 512+--IF TG_OP = 'INSERT' THEN
 513+-- NEW.textvector = to_tsvector('default',NEW.old_text);
 514+--ELSIF NEW.old_text != OLD.old_text THEN
 515+-- NEW.textvector := to_tsvector('default',NEW.old_text);
 516+--END IF;
 517+--RETURN NEW;
 518+--END;
 519+--$mw$;
 520+
 521+--CREATE TRIGGER ts2_page_text BEFORE INSERT OR UPDATE ON pagecontent
 522+-- FOR EACH ROW EXECUTE PROCEDURE ts2_page_text();
 523+
 524+-- These are added by the setup script due to version compatibility issues
 525+-- If using 8.1, we switch from "gin" to "gist"
 526+
 527+--CREATE INDEX ts2_page_title ON page USING gin(titlevector);
 528+--CREATE INDEX ts2_page_text ON pagecontent USING gin(textvector);
 529+
 530+--TODO
 531+--CREATE FUNCTION add_interwiki (TEXT,INT,SMALLINT) RETURNS INT LANGUAGE SQL AS
 532+--$mw$
 533+-- INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES ($1,$2,$3);
 534+-- SELECT 1;
 535+--$mw$;
 536+
 537+-- hack implementation
 538+-- should be replaced with OmniFind, Contains(), etc
 539+CREATE TABLE searchindex (
 540+ si_page int NOT NULL,
 541+ si_title varchar(255) NOT NULL default '',
 542+ si_text clob NOT NULL
 543+);
 544+
 545+-- This table is not used unless profiling is turned on
 546+CREATE TABLE profiling (
 547+ pf_count INTEGER NOT NULL DEFAULT 0,
 548+ pf_time NUMERIC(18,10) NOT NULL DEFAULT 0,
 549+ pf_memory NUMERIC(18,10) NOT NULL DEFAULT 0,
 550+ pf_name VARCHAR(255) NOT NULL,
 551+ pf_server VARCHAR(255)
 552+);
 553+CREATE UNIQUE INDEX pf_name_server ON profiling (pf_name, pf_server);
 554+
 555+CREATE TABLE protected_titles (
 556+ pt_namespace SMALLINT NOT NULL,
 557+ pt_title VARCHAR(255) NOT NULL,
 558+ pt_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
 559+ pt_reason clob(1K),
 560+ pt_timestamp TIMESTAMP NOT NULL,
 561+ pt_expiry TIMESTAMP ,
 562+ pt_create_perm VARCHAR(255) NOT NULL DEFAULT ''
 563+);
 564+CREATE UNIQUE INDEX protected_titles_unique ON protected_titles(pt_namespace, pt_title);
 565+
 566+
 567+
 568+CREATE TABLE updatelog (
 569+ ul_key VARCHAR(255) NOT NULL PRIMARY KEY
 570+);
 571+
 572+CREATE SEQUENCE category_id_seq;
 573+CREATE TABLE category (
 574+ cat_id INTEGER NOT NULL PRIMARY KEY,
 575+ --PRIMARY KEY DEFAULT nextval('category_id_seq'),
 576+ cat_title VARCHAR(255) NOT NULL,
 577+ cat_pages INTEGER NOT NULL DEFAULT 0,
 578+ cat_subcats INTEGER NOT NULL DEFAULT 0,
 579+ cat_files INTEGER NOT NULL DEFAULT 0,
 580+ cat_hidden SMALLINT NOT NULL DEFAULT 0
 581+);
 582+CREATE UNIQUE INDEX category_title ON category(cat_title);
 583+CREATE INDEX category_pages ON category(cat_pages);
 584+
 585+CREATE TABLE mediawiki_version (
 586+ type VARCHAR(255) NOT NULL,
 587+ mw_version VARCHAR(255) NOT NULL,
 588+ notes VARCHAR(255) ,
 589+
 590+ pg_version VARCHAR(255) ,
 591+ pg_dbname VARCHAR(255) ,
 592+ pg_user VARCHAR(255) ,
 593+ pg_port VARCHAR(255) ,
 594+ mw_schema VARCHAR(255) ,
 595+ ts2_schema VARCHAR(255) ,
 596+ ctype VARCHAR(255) ,
 597+
 598+ sql_version VARCHAR(255) ,
 599+ sql_date VARCHAR(255) ,
 600+ cdate TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP
 601+);
 602+
 603+INSERT INTO mediawiki_version (type,mw_version,sql_version,sql_date)
 604+ VALUES ('Creation','??','$LastChangedRevision: 34049 $','$LastChangedDate: 2008-04-30 10:20:36 -0400 (Wed, 30 Apr 2008) $');
 605+
Property changes on: trunk/phase3/maintenance/ibm_db2/tables.sql
___________________________________________________________________
Name: svn:eol-style
538606 + native
Index: trunk/phase3/maintenance/ibm_db2/README
@@ -1,41 +1,41 @@
2 -== Syntax differences between other databases and IBM DB2 ==
3 -{| border cellspacing=0 cellpadding=4
4 -!MySQL!!IBM DB2
5 -|-
6 -
7 -|SELECT 1 FROM $table LIMIT 1
8 -|SELECT COUNT(*) FROM SYSIBM.SYSTABLES ST
9 -WHERE ST.NAME = '$table' AND ST.CREATOR = '$schema'
10 -|-
11 -|MySQL code tries to read one row and interprets lack of error as proof of existence.
12 -|DB2 code counts the number of TABLES of that name in the database. There ought to be 1 for it to exist.
13 -|-
14 -|BEGIN
15 -|(implicit)
16 -|-
17 -|TEXT
18 -|VARCHAR(255) or CLOB
19 -|-
20 -|TIMESTAMPTZ
21 -|TIMESTAMP
22 -|-
23 -|BYTEA
24 -|VARGRAPHIC(255)
25 -|-
26 -|DEFAULT nextval('some_kind_of_sequence'),
27 -|GENERATED ALWAYS AS IDENTITY (START WITH 0, INCREMENT BY 1),
28 -|-
29 -|CIDR
30 -|VARCHAR(255)
31 -|-
32 -|LIMIT 10
33 -|FETCH FIRST 10 ROWS ONLY
34 -|-
35 -|ROLLBACK TO
36 -|ROLLBACK TO SAVEPOINT
37 -|-
38 -|RELEASE
39 -|RELEASE SAVEPOINT
40 -|}
41 -== See also ==
 2+== Syntax differences between other databases and IBM DB2 ==
 3+{| border cellspacing=0 cellpadding=4
 4+!MySQL!!IBM DB2
 5+|-
 6+
 7+|SELECT 1 FROM $table LIMIT 1
 8+|SELECT COUNT(*) FROM SYSIBM.SYSTABLES ST
 9+WHERE ST.NAME = '$table' AND ST.CREATOR = '$schema'
 10+|-
 11+|MySQL code tries to read one row and interprets lack of error as proof of existence.
 12+|DB2 code counts the number of TABLES of that name in the database. There ought to be 1 for it to exist.
 13+|-
 14+|BEGIN
 15+|(implicit)
 16+|-
 17+|TEXT
 18+|VARCHAR(255) or CLOB
 19+|-
 20+|TIMESTAMPTZ
 21+|TIMESTAMP
 22+|-
 23+|BYTEA
 24+|VARGRAPHIC(255)
 25+|-
 26+|DEFAULT nextval('some_kind_of_sequence'),
 27+|GENERATED ALWAYS AS IDENTITY (START WITH 0, INCREMENT BY 1),
 28+|-
 29+|CIDR
 30+|VARCHAR(255)
 31+|-
 32+|LIMIT 10
 33+|FETCH FIRST 10 ROWS ONLY
 34+|-
 35+|ROLLBACK TO
 36+|ROLLBACK TO SAVEPOINT
 37+|-
 38+|RELEASE
 39+|RELEASE SAVEPOINT
 40+|}
 41+== See also ==
4242 *[http://ca.php.net/manual/en/function.db2-connect.php PHP Manual for DB2 functions]
\ No newline at end of file
Property changes on: trunk/phase3/maintenance/ibm_db2/README
___________________________________________________________________
Name: svn:eol-style
4343 + native
Index: trunk/phase3/includes/db/DatabaseIbm_db2.php
@@ -684,16 +684,16 @@
685685 throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' . htmlspecialchars( $this->lastError() ) );
686686 }
687687 return $row;
688 - }
689 -
690 - /**
691 - * Override if introduced to base Database class
692 - */
693 - public function initial_setup() {
694 - // do nothing
695688 }
696689
697690 /**
 691+ * Override if introduced to base Database class
 692+ */
 693+ public function initial_setup() {
 694+ // do nothing
 695+ }
 696+
 697+ /**
698698 * Create tables, stored procedures, and so on
699699 */
700700 public function setup_database() {
@@ -721,12 +721,12 @@
722722 print "<br><pre>$mwe</pre><br>";
723723 }
724724 }
725 -
726 - /**
 725+
 726+ /**
727727 * Escapes strings
728 - * Doesn't escape numbers
729 - * @param string s string to escape
730 - * @return escaped string
 728+ * Doesn't escape numbers
 729+ * @param string s string to escape
 730+ * @return escaped string
731731 */
732732 public function addQuotes( $s ) {
733733 //wfDebug("DB2::addQuotes($s)\n");
@@ -814,48 +814,48 @@
815815 $s = str_replace($from, $to, $s); // DB2 expects '', not \' escaping
816816 return $s;
817817 }
818 -
819 - /**
820 - * Switch into the database schema
 818+
 819+ /**
 820+ * Switch into the database schema
821821 */
822822 protected function applySchema() {
823 - if ( !($this->mSchemaSet) ) {
 823+ if ( !($this->mSchemaSet) ) {
824824 $this->mSchemaSet = true;
825825 $this->begin();
826 - $this->doQuery("SET SCHEMA = $this->mSchema");
 826+ $this->doQuery("SET SCHEMA = $this->mSchema");
827827 $this->commit();
828828 }
829 - }
830 -
831 - /**
832 - * Start a transaction (mandatory)
833 - */
834 - public function begin() {
 829+ }
 830+
 831+ /**
 832+ * Start a transaction (mandatory)
 833+ */
 834+ public function begin() {
835835 // turn off auto-commit
836836 db2_autocommit($this->mConn, DB2_AUTOCOMMIT_OFF);
837 - $this->mTrxLevel = 1;
838 - }
839 -
840 - /**
 837+ $this->mTrxLevel = 1;
 838+ }
 839+
 840+ /**
841841 * End a transaction
842 - * Must have a preceding begin()
843 - */
844 - public function commit() {
 842+ * Must have a preceding begin()
 843+ */
 844+ public function commit() {
845845 db2_commit($this->mConn);
846846 // turn auto-commit back on
847847 db2_autocommit($this->mConn, DB2_AUTOCOMMIT_ON);
848 - $this->mTrxLevel = 0;
849 - }
850 -
851 - /**
852 - * Cancel a transaction
853 - */
854 - public function rollback() {
 848+ $this->mTrxLevel = 0;
 849+ }
 850+
 851+ /**
 852+ * Cancel a transaction
 853+ */
 854+ public function rollback() {
855855 db2_rollback($this->mConn);
856856 // turn auto-commit back on
857857 // not sure if this is appropriate
858858 db2_autocommit($this->mConn, DB2_AUTOCOMMIT_ON);
859 - $this->mTrxLevel = 0;
 859+ $this->mTrxLevel = 0;
860860 }
861861
862862 /**
Property changes on: trunk/phase3/includes/db/DatabaseIbm_db2.php
___________________________________________________________________
Name: svn:eol-style
863863 + native
Index: trunk/phase3/includes/api/ApiFormatJson_json.php
@@ -45,14 +45,14 @@
4646 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
4747 * DAMAGE.
4848 *
49 -* @ingroup API
50 -* @author Michal Migurski <mike-json@teczno.com>
51 -* @author Matt Knapp <mdknapp[at]gmail[dot]com>
52 -* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
53 -* @copyright 2005 Michal Migurski
54 -* @version CVS: $Id$
55 -* @license http://www.opensource.org/licenses/bsd-license.php
56 -* @see http://pear.php.net/pepr/pepr-proposal-show.php?id=198
 49+* @ingroup API
 50+* @author Michal Migurski <mike-json@teczno.com>
 51+* @author Matt Knapp <mdknapp[at]gmail[dot]com>
 52+* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
 53+* @copyright 2005 Michal Migurski
 54+* @version CVS: $Id$
 55+* @license http://www.opensource.org/licenses/bsd-license.php
 56+* @see http://pear.php.net/pepr/pepr-proposal-show.php?id=198
5757 */
5858
5959 /**
@@ -115,715 +115,715 @@
116116 */
117117 class Services_JSON
118118 {
119 - /**
120 - * constructs a new JSON instance
121 - *
122 - * @param int $use object behavior flags; combine with boolean-OR
123 - *
124 - * possible values:
125 - * - SERVICES_JSON_LOOSE_TYPE: loose typing.
126 - * "{...}" syntax creates associative arrays
127 - * instead of objects in decode().
128 - * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
129 - * Values which can't be encoded (e.g. resources)
130 - * appear as NULL instead of throwing errors.
131 - * By default, a deeply-nested resource will
132 - * bubble up with an error, so all return values
133 - * from encode() should be checked with isError()
134 - */
135 - function Services_JSON($use = 0)
136 - {
137 - $this->use = $use;
138 - }
 119+ /**
 120+ * constructs a new JSON instance
 121+ *
 122+ * @param int $use object behavior flags; combine with boolean-OR
 123+ *
 124+ * possible values:
 125+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
 126+ * "{...}" syntax creates associative arrays
 127+ * instead of objects in decode().
 128+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
 129+ * Values which can't be encoded (e.g. resources)
 130+ * appear as NULL instead of throwing errors.
 131+ * By default, a deeply-nested resource will
 132+ * bubble up with an error, so all return values
 133+ * from encode() should be checked with isError()
 134+ */
 135+ function Services_JSON($use = 0)
 136+ {
 137+ $this->use = $use;
 138+ }
139139
140 - /**
141 - * convert a string from one UTF-16 char to one UTF-8 char
142 - *
143 - * Normally should be handled by mb_convert_encoding, but
144 - * provides a slower PHP-only method for installations
145 - * that lack the multibye string extension.
146 - *
147 - * @param string $utf16 UTF-16 character
148 - * @return string UTF-8 character
149 - * @access private
150 - */
151 - function utf162utf8($utf16)
152 - {
153 - // oh please oh please oh please oh please oh please
154 - if(function_exists('mb_convert_encoding')) {
155 - return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
156 - }
 140+ /**
 141+ * convert a string from one UTF-16 char to one UTF-8 char
 142+ *
 143+ * Normally should be handled by mb_convert_encoding, but
 144+ * provides a slower PHP-only method for installations
 145+ * that lack the multibye string extension.
 146+ *
 147+ * @param string $utf16 UTF-16 character
 148+ * @return string UTF-8 character
 149+ * @access private
 150+ */
 151+ function utf162utf8($utf16)
 152+ {
 153+ // oh please oh please oh please oh please oh please
 154+ if(function_exists('mb_convert_encoding')) {
 155+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
 156+ }
157157
158 - $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
 158+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
159159
160 - switch(true) {
161 - case ((0x7F & $bytes) == $bytes):
162 - // this case should never be reached, because we are in ASCII range
163 - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
164 - return chr(0x7F & $bytes);
 160+ switch(true) {
 161+ case ((0x7F & $bytes) == $bytes):
 162+ // this case should never be reached, because we are in ASCII range
 163+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 164+ return chr(0x7F & $bytes);
165165
166 - case (0x07FF & $bytes) == $bytes:
167 - // return a 2-byte UTF-8 character
168 - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
169 - return chr(0xC0 | (($bytes >> 6) & 0x1F))
170 - . chr(0x80 | ($bytes & 0x3F));
 166+ case (0x07FF & $bytes) == $bytes:
 167+ // return a 2-byte UTF-8 character
 168+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 169+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
 170+ . chr(0x80 | ($bytes & 0x3F));
171171
172 - case (0xFC00 & $bytes) == 0xD800 && strlen($utf16) >= 4 && (0xFC & ord($utf16{2})) == 0xDC:
173 - // return a 4-byte UTF-8 character
174 - $char = ((($bytes & 0x03FF) << 10)
175 - | ((ord($utf16{2}) & 0x03) << 8)
176 - | ord($utf16{3}));
177 - $char += 0x10000;
178 - return chr(0xF0 | (($char >> 18) & 0x07))
179 - . chr(0x80 | (($char >> 12) & 0x3F))
180 - . chr(0x80 | (($char >> 6) & 0x3F))
181 - . chr(0x80 | ($char & 0x3F));
 172+ case (0xFC00 & $bytes) == 0xD800 && strlen($utf16) >= 4 && (0xFC & ord($utf16{2})) == 0xDC:
 173+ // return a 4-byte UTF-8 character
 174+ $char = ((($bytes & 0x03FF) << 10)
 175+ | ((ord($utf16{2}) & 0x03) << 8)
 176+ | ord($utf16{3}));
 177+ $char += 0x10000;
 178+ return chr(0xF0 | (($char >> 18) & 0x07))
 179+ . chr(0x80 | (($char >> 12) & 0x3F))
 180+ . chr(0x80 | (($char >> 6) & 0x3F))
 181+ . chr(0x80 | ($char & 0x3F));
182182
183 - case (0xFFFF & $bytes) == $bytes:
184 - // return a 3-byte UTF-8 character
185 - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
186 - return chr(0xE0 | (($bytes >> 12) & 0x0F))
187 - . chr(0x80 | (($bytes >> 6) & 0x3F))
188 - . chr(0x80 | ($bytes & 0x3F));
189 - }
 183+ case (0xFFFF & $bytes) == $bytes:
 184+ // return a 3-byte UTF-8 character
 185+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 186+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
 187+ . chr(0x80 | (($bytes >> 6) & 0x3F))
 188+ . chr(0x80 | ($bytes & 0x3F));
 189+ }
190190
191 - // ignoring UTF-32 for now, sorry
192 - return '';
193 - }
 191+ // ignoring UTF-32 for now, sorry
 192+ return '';
 193+ }
194194
195 - /**
196 - * convert a string from one UTF-8 char to one UTF-16 char
197 - *
198 - * Normally should be handled by mb_convert_encoding, but
199 - * provides a slower PHP-only method for installations
200 - * that lack the multibye string extension.
201 - *
202 - * @param string $utf8 UTF-8 character
203 - * @return string UTF-16 character
204 - * @access private
205 - */
206 - function utf82utf16($utf8)
207 - {
208 - // oh please oh please oh please oh please oh please
209 - if(function_exists('mb_convert_encoding')) {
210 - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
211 - }
 195+ /**
 196+ * convert a string from one UTF-8 char to one UTF-16 char
 197+ *
 198+ * Normally should be handled by mb_convert_encoding, but
 199+ * provides a slower PHP-only method for installations
 200+ * that lack the multibye string extension.
 201+ *
 202+ * @param string $utf8 UTF-8 character
 203+ * @return string UTF-16 character
 204+ * @access private
 205+ */
 206+ function utf82utf16($utf8)
 207+ {
 208+ // oh please oh please oh please oh please oh please
 209+ if(function_exists('mb_convert_encoding')) {
 210+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
 211+ }
212212
213 - switch(strlen($utf8)) {
214 - case 1:
215 - // this case should never be reached, because we are in ASCII range
216 - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
217 - return $utf8;
 213+ switch(strlen($utf8)) {
 214+ case 1:
 215+ // this case should never be reached, because we are in ASCII range
 216+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 217+ return $utf8;
218218
219 - case 2:
220 - // return a UTF-16 character from a 2-byte UTF-8 char
221 - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
222 - return chr(0x07 & (ord($utf8{0}) >> 2))
223 - . chr((0xC0 & (ord($utf8{0}) << 6))
224 - | (0x3F & ord($utf8{1})));
 219+ case 2:
 220+ // return a UTF-16 character from a 2-byte UTF-8 char
 221+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 222+ return chr(0x07 & (ord($utf8{0}) >> 2))
 223+ . chr((0xC0 & (ord($utf8{0}) << 6))
 224+ | (0x3F & ord($utf8{1})));
225225
226 - case 3:
227 - // return a UTF-16 character from a 3-byte UTF-8 char
228 - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
229 - return chr((0xF0 & (ord($utf8{0}) << 4))
230 - | (0x0F & (ord($utf8{1}) >> 2)))
231 - . chr((0xC0 & (ord($utf8{1}) << 6))
232 - | (0x7F & ord($utf8{2})));
 226+ case 3:
 227+ // return a UTF-16 character from a 3-byte UTF-8 char
 228+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 229+ return chr((0xF0 & (ord($utf8{0}) << 4))
 230+ | (0x0F & (ord($utf8{1}) >> 2)))
 231+ . chr((0xC0 & (ord($utf8{1}) << 6))
 232+ | (0x7F & ord($utf8{2})));
233233
234 - case 4:
235 - // return a UTF-16 surrogate pair from a 4-byte UTF-8 char
236 - if(ord($utf8{0}) > 0xF4) return ''; # invalid
237 - $char = ((0x1C0000 & (ord($utf8{0}) << 18))
238 - | (0x03F000 & (ord($utf8{1}) << 12))
239 - | (0x000FC0 & (ord($utf8{2}) << 6))
240 - | (0x00003F & ord($utf8{3})));
241 - if($char > 0x10FFFF) return ''; # invalid
242 - $char -= 0x10000;
243 - return chr(0xD8 | (($char >> 18) & 0x03))
244 - . chr(($char >> 10) & 0xFF)
245 - . chr(0xDC | (($char >> 8) & 0x03))
246 - . chr($char & 0xFF);
247 - }
 234+ case 4:
 235+ // return a UTF-16 surrogate pair from a 4-byte UTF-8 char
 236+ if(ord($utf8{0}) > 0xF4) return ''; # invalid
 237+ $char = ((0x1C0000 & (ord($utf8{0}) << 18))
 238+ | (0x03F000 & (ord($utf8{1}) << 12))
 239+ | (0x000FC0 & (ord($utf8{2}) << 6))
 240+ | (0x00003F & ord($utf8{3})));
 241+ if($char > 0x10FFFF) return ''; # invalid
 242+ $char -= 0x10000;
 243+ return chr(0xD8 | (($char >> 18) & 0x03))
 244+ . chr(($char >> 10) & 0xFF)
 245+ . chr(0xDC | (($char >> 8) & 0x03))
 246+ . chr($char & 0xFF);
 247+ }
248248
249 - // ignoring UTF-32 for now, sorry
250 - return '';
251 - }
 249+ // ignoring UTF-32 for now, sorry
 250+ return '';
 251+ }
252252
253 - /**
254 - * encodes an arbitrary variable into JSON format
255 - *
256 - * @param mixed $var any number, boolean, string, array, or object to be encoded.
257 - * see argument 1 to Services_JSON() above for array-parsing behavior.
258 - * if var is a strng, note that encode() always expects it
259 - * to be in ASCII or UTF-8 format!
260 - * @param bool $pretty pretty-print output with indents and newlines
261 - *
262 - * @return mixed JSON string representation of input var or an error if a problem occurs
263 - * @access public
264 - */
265 - function encode($var, $pretty=false)
266 - {
267 - $this->indent = 0;
268 - $this->pretty = $pretty;
269 - $this->nameValSeparator = $pretty ? ': ' : ':';
270 - return $this->encode2($var);
271 - }
 253+ /**
 254+ * encodes an arbitrary variable into JSON format
 255+ *
 256+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
 257+ * see argument 1 to Services_JSON() above for array-parsing behavior.
 258+ * if var is a strng, note that encode() always expects it
 259+ * to be in ASCII or UTF-8 format!
 260+ * @param bool $pretty pretty-print output with indents and newlines
 261+ *
 262+ * @return mixed JSON string representation of input var or an error if a problem occurs
 263+ * @access public
 264+ */
 265+ function encode($var, $pretty=false)
 266+ {
 267+ $this->indent = 0;
 268+ $this->pretty = $pretty;
 269+ $this->nameValSeparator = $pretty ? ': ' : ':';
 270+ return $this->encode2($var);
 271+ }
272272
273 - /**
274 - * encodes an arbitrary variable into JSON format
275 - *
276 - * @param mixed $var any number, boolean, string, array, or object to be encoded.
277 - * see argument 1 to Services_JSON() above for array-parsing behavior.
278 - * if var is a strng, note that encode() always expects it
279 - * to be in ASCII or UTF-8 format!
280 - *
281 - * @return mixed JSON string representation of input var or an error if a problem occurs
282 - * @access private
283 - */
284 - function encode2($var)
285 - {
286 - if ($this->pretty) {
287 - $close = "\n" . str_repeat("\t", $this->indent);
288 - $open = $close . "\t";
289 - $mid = ',' . $open;
290 - }
291 - else {
292 - $open = $close = '';
293 - $mid = ',';
294 - }
 273+ /**
 274+ * encodes an arbitrary variable into JSON format
 275+ *
 276+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
 277+ * see argument 1 to Services_JSON() above for array-parsing behavior.
 278+ * if var is a strng, note that encode() always expects it
 279+ * to be in ASCII or UTF-8 format!
 280+ *
 281+ * @return mixed JSON string representation of input var or an error if a problem occurs
 282+ * @access private
 283+ */
 284+ function encode2($var)
 285+ {
 286+ if ($this->pretty) {
 287+ $close = "\n" . str_repeat("\t", $this->indent);
 288+ $open = $close . "\t";
 289+ $mid = ',' . $open;
 290+ }
 291+ else {
 292+ $open = $close = '';
 293+ $mid = ',';
 294+ }
295295
296 - switch (gettype($var)) {
297 - case 'boolean':
298 - return $var ? 'true' : 'false';
 296+ switch (gettype($var)) {
 297+ case 'boolean':
 298+ return $var ? 'true' : 'false';
299299
300 - case 'NULL':
301 - return 'null';
 300+ case 'NULL':
 301+ return 'null';
302302
303 - case 'integer':
304 - return (int) $var;
 303+ case 'integer':
 304+ return (int) $var;
305305
306 - case 'double':
307 - case 'float':
308 - return (float) $var;
 306+ case 'double':
 307+ case 'float':
 308+ return (float) $var;
309309
310 - case 'string':
311 - // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
312 - $ascii = '';
313 - $strlen_var = strlen($var);
 310+ case 'string':
 311+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
 312+ $ascii = '';
 313+ $strlen_var = strlen($var);
314314
315 - /*
316 - * Iterate over every character in the string,
317 - * escaping with a slash or encoding to UTF-8 where necessary
318 - */
319 - for ($c = 0; $c < $strlen_var; ++$c) {
 315+ /*
 316+ * Iterate over every character in the string,
 317+ * escaping with a slash or encoding to UTF-8 where necessary
 318+ */
 319+ for ($c = 0; $c < $strlen_var; ++$c) {
320320
321 - $ord_var_c = ord($var{$c});
 321+ $ord_var_c = ord($var{$c});
322322
323 - switch (true) {
324 - case $ord_var_c == 0x08:
325 - $ascii .= '\b';
326 - break;
327 - case $ord_var_c == 0x09:
328 - $ascii .= '\t';
329 - break;
330 - case $ord_var_c == 0x0A:
331 - $ascii .= '\n';
332 - break;
333 - case $ord_var_c == 0x0C:
334 - $ascii .= '\f';
335 - break;
336 - case $ord_var_c == 0x0D:
337 - $ascii .= '\r';
338 - break;
 323+ switch (true) {
 324+ case $ord_var_c == 0x08:
 325+ $ascii .= '\b';
 326+ break;
 327+ case $ord_var_c == 0x09:
 328+ $ascii .= '\t';
 329+ break;
 330+ case $ord_var_c == 0x0A:
 331+ $ascii .= '\n';
 332+ break;
 333+ case $ord_var_c == 0x0C:
 334+ $ascii .= '\f';
 335+ break;
 336+ case $ord_var_c == 0x0D:
 337+ $ascii .= '\r';
 338+ break;
339339
340 - case $ord_var_c == 0x22:
341 - case $ord_var_c == 0x2F:
342 - case $ord_var_c == 0x5C:
343 - // double quote, slash, slosh
344 - $ascii .= '\\'.$var{$c};
345 - break;
 340+ case $ord_var_c == 0x22:
 341+ case $ord_var_c == 0x2F:
 342+ case $ord_var_c == 0x5C:
 343+ // double quote, slash, slosh
 344+ $ascii .= '\\'.$var{$c};
 345+ break;
346346
347 - case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
348 - // characters U-00000000 - U-0000007F (same as ASCII)
349 - $ascii .= $var{$c};
350 - break;
 347+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
 348+ // characters U-00000000 - U-0000007F (same as ASCII)
 349+ $ascii .= $var{$c};
 350+ break;
351351
352 - case (($ord_var_c & 0xE0) == 0xC0):
353 - // characters U-00000080 - U-000007FF, mask 110XXXXX
354 - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
355 - $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
356 - $c += 1;
357 - $utf16 = $this->utf82utf16($char);
358 - $ascii .= sprintf('\u%04s', bin2hex($utf16));
359 - break;
 352+ case (($ord_var_c & 0xE0) == 0xC0):
 353+ // characters U-00000080 - U-000007FF, mask 110XXXXX
 354+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 355+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
 356+ $c += 1;
 357+ $utf16 = $this->utf82utf16($char);
 358+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
 359+ break;
360360
361 - case (($ord_var_c & 0xF0) == 0xE0):
362 - // characters U-00000800 - U-0000FFFF, mask 1110XXXX
363 - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
364 - $char = pack('C*', $ord_var_c,
365 - ord($var{$c + 1}),
366 - ord($var{$c + 2}));
367 - $c += 2;
368 - $utf16 = $this->utf82utf16($char);
369 - $ascii .= sprintf('\u%04s', bin2hex($utf16));
370 - break;
 361+ case (($ord_var_c & 0xF0) == 0xE0):
 362+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
 363+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 364+ $char = pack('C*', $ord_var_c,
 365+ ord($var{$c + 1}),
 366+ ord($var{$c + 2}));
 367+ $c += 2;
 368+ $utf16 = $this->utf82utf16($char);
 369+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
 370+ break;
371371
372 - case (($ord_var_c & 0xF8) == 0xF0):
373 - // characters U-00010000 - U-001FFFFF, mask 11110XXX
374 - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
375 - // These will always return a surrogate pair
376 - $char = pack('C*', $ord_var_c,
377 - ord($var{$c + 1}),
378 - ord($var{$c + 2}),
379 - ord($var{$c + 3}));
380 - $c += 3;
381 - $utf16 = $this->utf82utf16($char);
382 - if($utf16 == '') {
383 - $ascii .= '\ufffd';
384 - } else {
385 - $utf16 = str_split($utf16, 2);
386 - $ascii .= sprintf('\u%04s\u%04s', bin2hex($utf16[0]), bin2hex($utf16[1]));
387 - }
388 - break;
389 - }
390 - }
 372+ case (($ord_var_c & 0xF8) == 0xF0):
 373+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
 374+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 375+ // These will always return a surrogate pair
 376+ $char = pack('C*', $ord_var_c,
 377+ ord($var{$c + 1}),
 378+ ord($var{$c + 2}),
 379+ ord($var{$c + 3}));
 380+ $c += 3;
 381+ $utf16 = $this->utf82utf16($char);
 382+ if($utf16 == '') {
 383+ $ascii .= '\ufffd';
 384+ } else {
 385+ $utf16 = str_split($utf16, 2);
 386+ $ascii .= sprintf('\u%04s\u%04s', bin2hex($utf16[0]), bin2hex($utf16[1]));
 387+ }
 388+ break;
 389+ }
 390+ }
391391
392 - return '"'.$ascii.'"';
 392+ return '"'.$ascii.'"';
393393
394 - case 'array':
395 - /*
396 - * As per JSON spec if any array key is not an integer
397 - * we must treat the the whole array as an object. We
398 - * also try to catch a sparsely populated associative
399 - * array with numeric keys here because some JS engines
400 - * will create an array with empty indexes up to
401 - * max_index which can cause memory issues and because
402 - * the keys, which may be relevant, will be remapped
403 - * otherwise.
404 - *
405 - * As per the ECMA and JSON specification an object may
406 - * have any string as a property. Unfortunately due to
407 - * a hole in the ECMA specification if the key is a
408 - * ECMA reserved word or starts with a digit the
409 - * parameter is only accessible using ECMAScript's
410 - * bracket notation.
411 - */
 394+ case 'array':
 395+ /*
 396+ * As per JSON spec if any array key is not an integer
 397+ * we must treat the the whole array as an object. We
 398+ * also try to catch a sparsely populated associative
 399+ * array with numeric keys here because some JS engines
 400+ * will create an array with empty indexes up to
 401+ * max_index which can cause memory issues and because
 402+ * the keys, which may be relevant, will be remapped
 403+ * otherwise.
 404+ *
 405+ * As per the ECMA and JSON specification an object may
 406+ * have any string as a property. Unfortunately due to
 407+ * a hole in the ECMA specification if the key is a
 408+ * ECMA reserved word or starts with a digit the
 409+ * parameter is only accessible using ECMAScript's
 410+ * bracket notation.
 411+ */
412412
413 - // treat as a JSON object
414 - if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
415 - $this->indent++;
416 - $properties = array_map(array($this, 'name_value'),
417 - array_keys($var),
418 - array_values($var));
419 - $this->indent--;
 413+ // treat as a JSON object
 414+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
 415+ $this->indent++;
 416+ $properties = array_map(array($this, 'name_value'),
 417+ array_keys($var),
 418+ array_values($var));
 419+ $this->indent--;
420420
421 - foreach($properties as $property) {
422 - if(Services_JSON::isError($property)) {
423 - return $property;
424 - }
425 - }
 421+ foreach($properties as $property) {
 422+ if(Services_JSON::isError($property)) {
 423+ return $property;
 424+ }
 425+ }
426426
427 - return '{' . $open . join($mid, $properties) . $close . '}';
428 - }
 427+ return '{' . $open . join($mid, $properties) . $close . '}';
 428+ }
429429
430 - // treat it like a regular array
431 - $this->indent++;
432 - $elements = array_map(array($this, 'encode2'), $var);
433 - $this->indent--;
 430+ // treat it like a regular array
 431+ $this->indent++;
 432+ $elements = array_map(array($this, 'encode2'), $var);
 433+ $this->indent--;
434434
435 - foreach($elements as $element) {
436 - if(Services_JSON::isError($element)) {
437 - return $element;
438 - }
439 - }
 435+ foreach($elements as $element) {
 436+ if(Services_JSON::isError($element)) {
 437+ return $element;
 438+ }
 439+ }
440440
441 - return '[' . $open . join($mid, $elements) . $close . ']';
 441+ return '[' . $open . join($mid, $elements) . $close . ']';
442442
443 - case 'object':
444 - $vars = get_object_vars($var);
 443+ case 'object':
 444+ $vars = get_object_vars($var);
445445
446 - $this->indent++;
447 - $properties = array_map(array($this, 'name_value'),
448 - array_keys($vars),
449 - array_values($vars));
450 - $this->indent--;
 446+ $this->indent++;
 447+ $properties = array_map(array($this, 'name_value'),
 448+ array_keys($vars),
 449+ array_values($vars));
 450+ $this->indent--;
451451
452 - foreach($properties as $property) {
453 - if(Services_JSON::isError($property)) {
454 - return $property;
455 - }
456 - }
 452+ foreach($properties as $property) {
 453+ if(Services_JSON::isError($property)) {
 454+ return $property;
 455+ }
 456+ }
457457
458 - return '{' . $open . join($mid, $properties) . $close . '}';
 458+ return '{' . $open . join($mid, $properties) . $close . '}';
459459
460 - default:
461 - return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
462 - ? 'null'
463 - : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
464 - }
465 - }
 460+ default:
 461+ return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
 462+ ? 'null'
 463+ : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
 464+ }
 465+ }
466466
467 - /**
468 - * array-walking function for use in generating JSON-formatted name-value pairs
469 - *
470 - * @param string $name name of key to use
471 - * @param mixed $value reference to an array element to be encoded
472 - *
473 - * @return string JSON-formatted name-value pair, like '"name":value'
474 - * @access private
475 - */
476 - function name_value($name, $value)
477 - {
478 - $encoded_value = $this->encode2($value);
 467+ /**
 468+ * array-walking function for use in generating JSON-formatted name-value pairs
 469+ *
 470+ * @param string $name name of key to use
 471+ * @param mixed $value reference to an array element to be encoded
 472+ *
 473+ * @return string JSON-formatted name-value pair, like '"name":value'
 474+ * @access private
 475+ */
 476+ function name_value($name, $value)
 477+ {
 478+ $encoded_value = $this->encode2($value);
479479
480 - if(Services_JSON::isError($encoded_value)) {
481 - return $encoded_value;
482 - }
 480+ if(Services_JSON::isError($encoded_value)) {
 481+ return $encoded_value;
 482+ }
483483
484 - return $this->encode2(strval($name)) . $this->nameValSeparator . $encoded_value;
485 - }
 484+ return $this->encode2(strval($name)) . $this->nameValSeparator . $encoded_value;
 485+ }
486486
487 - /**
488 - * reduce a string by removing leading and trailing comments and whitespace
489 - *
490 - * @param $str string string value to strip of comments and whitespace
491 - *
492 - * @return string string value stripped of comments and whitespace
493 - * @access private
494 - */
495 - function reduce_string($str)
496 - {
497 - $str = preg_replace(array(
 487+ /**
 488+ * reduce a string by removing leading and trailing comments and whitespace
 489+ *
 490+ * @param $str string string value to strip of comments and whitespace
 491+ *
 492+ * @return string string value stripped of comments and whitespace
 493+ * @access private
 494+ */
 495+ function reduce_string($str)
 496+ {
 497+ $str = preg_replace(array(
498498
499 - // eliminate single line comments in '// ...' form
500 - '#^\s*//(.+)$#m',
 499+ // eliminate single line comments in '// ...' form
 500+ '#^\s*//(.+)$#m',
501501
502 - // eliminate multi-line comments in '/* ... */' form, at start of string
503 - '#^\s*/\*(.+)\*/#Us',
 502+ // eliminate multi-line comments in '/* ... */' form, at start of string
 503+ '#^\s*/\*(.+)\*/#Us',
504504
505 - // eliminate multi-line comments in '/* ... */' form, at end of string
506 - '#/\*(.+)\*/\s*$#Us'
 505+ // eliminate multi-line comments in '/* ... */' form, at end of string
 506+ '#/\*(.+)\*/\s*$#Us'
507507
508 - ), '', $str);
 508+ ), '', $str);
509509
510 - // eliminate extraneous space
511 - return trim($str);
512 - }
 510+ // eliminate extraneous space
 511+ return trim($str);
 512+ }
513513
514 - /**
515 - * decodes a JSON string into appropriate variable
516 - *
517 - * @param string $str JSON-formatted string
518 - *
519 - * @return mixed number, boolean, string, array, or object
520 - * corresponding to given JSON input string.
521 - * See argument 1 to Services_JSON() above for object-output behavior.
522 - * Note that decode() always returns strings
523 - * in ASCII or UTF-8 format!
524 - * @access public
525 - */
526 - function decode($str)
527 - {
528 - $str = $this->reduce_string($str);
 514+ /**
 515+ * decodes a JSON string into appropriate variable
 516+ *
 517+ * @param string $str JSON-formatted string
 518+ *
 519+ * @return mixed number, boolean, string, array, or object
 520+ * corresponding to given JSON input string.
 521+ * See argument 1 to Services_JSON() above for object-output behavior.
 522+ * Note that decode() always returns strings
 523+ * in ASCII or UTF-8 format!
 524+ * @access public
 525+ */
 526+ function decode($str)
 527+ {
 528+ $str = $this->reduce_string($str);
529529
530 - switch (strtolower($str)) {
531 - case 'true':
532 - return true;
 530+ switch (strtolower($str)) {
 531+ case 'true':
 532+ return true;
533533
534 - case 'false':
535 - return false;
 534+ case 'false':
 535+ return false;
536536
537 - case 'null':
538 - return null;
 537+ case 'null':
 538+ return null;
539539
540 - default:
541 - $m = array();
 540+ default:
 541+ $m = array();
542542
543 - if (is_numeric($str)) {
544 - // Lookie-loo, it's a number
 543+ if (is_numeric($str)) {
 544+ // Lookie-loo, it's a number
545545
546 - // This would work on its own, but I'm trying to be
547 - // good about returning integers where appropriate:
548 - // return (float)$str;
 546+ // This would work on its own, but I'm trying to be
 547+ // good about returning integers where appropriate:
 548+ // return (float)$str;
549549
550 - // Return float or int, as appropriate
551 - return ((float)$str == (integer)$str)
552 - ? (integer)$str
553 - : (float)$str;
 550+ // Return float or int, as appropriate
 551+ return ((float)$str == (integer)$str)
 552+ ? (integer)$str
 553+ : (float)$str;
554554
555 - } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
556 - // STRINGS RETURNED IN UTF-8 FORMAT
557 - $delim = substr($str, 0, 1);
558 - $chrs = substr($str, 1, -1);
559 - $utf8 = '';
560 - $strlen_chrs = strlen($chrs);
 555+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
 556+ // STRINGS RETURNED IN UTF-8 FORMAT
 557+ $delim = substr($str, 0, 1);
 558+ $chrs = substr($str, 1, -1);
 559+ $utf8 = '';
 560+ $strlen_chrs = strlen($chrs);
561561
562 - for ($c = 0; $c < $strlen_chrs; ++$c) {
 562+ for ($c = 0; $c < $strlen_chrs; ++$c) {
563563
564 - $substr_chrs_c_2 = substr($chrs, $c, 2);
565 - $ord_chrs_c = ord($chrs{$c});
 564+ $substr_chrs_c_2 = substr($chrs, $c, 2);
 565+ $ord_chrs_c = ord($chrs{$c});
566566
567 - switch (true) {
568 - case $substr_chrs_c_2 == '\b':
569 - $utf8 .= chr(0x08);
570 - ++$c;
571 - break;
572 - case $substr_chrs_c_2 == '\t':
573 - $utf8 .= chr(0x09);
574 - ++$c;
575 - break;
576 - case $substr_chrs_c_2 == '\n':
577 - $utf8 .= chr(0x0A);
578 - ++$c;
579 - break;
580 - case $substr_chrs_c_2 == '\f':
581 - $utf8 .= chr(0x0C);
582 - ++$c;
583 - break;
584 - case $substr_chrs_c_2 == '\r':
585 - $utf8 .= chr(0x0D);
586 - ++$c;
587 - break;
 567+ switch (true) {
 568+ case $substr_chrs_c_2 == '\b':
 569+ $utf8 .= chr(0x08);
 570+ ++$c;
 571+ break;
 572+ case $substr_chrs_c_2 == '\t':
 573+ $utf8 .= chr(0x09);
 574+ ++$c;
 575+ break;
 576+ case $substr_chrs_c_2 == '\n':
 577+ $utf8 .= chr(0x0A);
 578+ ++$c;
 579+ break;
 580+ case $substr_chrs_c_2 == '\f':
 581+ $utf8 .= chr(0x0C);
 582+ ++$c;
 583+ break;
 584+ case $substr_chrs_c_2 == '\r':
 585+ $utf8 .= chr(0x0D);
 586+ ++$c;
 587+ break;
588588
589 - case $substr_chrs_c_2 == '\\"':
590 - case $substr_chrs_c_2 == '\\\'':
591 - case $substr_chrs_c_2 == '\\\\':
592 - case $substr_chrs_c_2 == '\\/':
593 - if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
594 - ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
595 - $utf8 .= $chrs{++$c};
596 - }
597 - break;
 589+ case $substr_chrs_c_2 == '\\"':
 590+ case $substr_chrs_c_2 == '\\\'':
 591+ case $substr_chrs_c_2 == '\\\\':
 592+ case $substr_chrs_c_2 == '\\/':
 593+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
 594+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
 595+ $utf8 .= $chrs{++$c};
 596+ }
 597+ break;
598598
599 - case preg_match('/\\\uD[89AB][0-9A-F]{2}\\\uD[C-F][0-9A-F]{2}/i', substr($chrs, $c, 12)):
600 - // escaped unicode surrogate pair
601 - $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
602 - . chr(hexdec(substr($chrs, ($c + 4), 2)))
603 - . chr(hexdec(substr($chrs, ($c + 8), 2)))
604 - . chr(hexdec(substr($chrs, ($c + 10), 2)));
605 - $utf8 .= $this->utf162utf8($utf16);
606 - $c += 11;
607 - break;
 599+ case preg_match('/\\\uD[89AB][0-9A-F]{2}\\\uD[C-F][0-9A-F]{2}/i', substr($chrs, $c, 12)):
 600+ // escaped unicode surrogate pair
 601+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
 602+ . chr(hexdec(substr($chrs, ($c + 4), 2)))
 603+ . chr(hexdec(substr($chrs, ($c + 8), 2)))
 604+ . chr(hexdec(substr($chrs, ($c + 10), 2)));
 605+ $utf8 .= $this->utf162utf8($utf16);
 606+ $c += 11;
 607+ break;
608608
609 - case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
610 - // single, escaped unicode character
611 - $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
612 - . chr(hexdec(substr($chrs, ($c + 4), 2)));
613 - $utf8 .= $this->utf162utf8($utf16);
614 - $c += 5;
615 - break;
 609+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
 610+ // single, escaped unicode character
 611+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
 612+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
 613+ $utf8 .= $this->utf162utf8($utf16);
 614+ $c += 5;
 615+ break;
616616
617 - case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
618 - $utf8 .= $chrs{$c};
619 - break;
 617+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
 618+ $utf8 .= $chrs{$c};
 619+ break;
620620
621 - case ($ord_chrs_c & 0xE0) == 0xC0:
622 - // characters U-00000080 - U-000007FF, mask 110XXXXX
623 - //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
624 - $utf8 .= substr($chrs, $c, 2);
625 - ++$c;
626 - break;
 621+ case ($ord_chrs_c & 0xE0) == 0xC0:
 622+ // characters U-00000080 - U-000007FF, mask 110XXXXX
 623+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 624+ $utf8 .= substr($chrs, $c, 2);
 625+ ++$c;
 626+ break;
627627
628 - case ($ord_chrs_c & 0xF0) == 0xE0:
629 - // characters U-00000800 - U-0000FFFF, mask 1110XXXX
630 - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
631 - $utf8 .= substr($chrs, $c, 3);
632 - $c += 2;
633 - break;
 628+ case ($ord_chrs_c & 0xF0) == 0xE0:
 629+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
 630+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 631+ $utf8 .= substr($chrs, $c, 3);
 632+ $c += 2;
 633+ break;
634634
635 - case ($ord_chrs_c & 0xF8) == 0xF0:
636 - // characters U-00010000 - U-001FFFFF, mask 11110XXX
637 - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
638 - $utf8 .= substr($chrs, $c, 4);
639 - $c += 3;
640 - break;
 635+ case ($ord_chrs_c & 0xF8) == 0xF0:
 636+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
 637+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 638+ $utf8 .= substr($chrs, $c, 4);
 639+ $c += 3;
 640+ break;
641641
642 - case ($ord_chrs_c & 0xFC) == 0xF8:
643 - // characters U-00200000 - U-03FFFFFF, mask 111110XX
644 - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
645 - $utf8 .= substr($chrs, $c, 5);
646 - $c += 4;
647 - break;
 642+ case ($ord_chrs_c & 0xFC) == 0xF8:
 643+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
 644+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 645+ $utf8 .= substr($chrs, $c, 5);
 646+ $c += 4;
 647+ break;
648648
649 - case ($ord_chrs_c & 0xFE) == 0xFC:
650 - // characters U-04000000 - U-7FFFFFFF, mask 1111110X
651 - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
652 - $utf8 .= substr($chrs, $c, 6);
653 - $c += 5;
654 - break;
 649+ case ($ord_chrs_c & 0xFE) == 0xFC:
 650+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
 651+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 652+ $utf8 .= substr($chrs, $c, 6);
 653+ $c += 5;
 654+ break;
655655
656 - }
 656+ }
657657
658 - }
 658+ }
659659
660 - return $utf8;
 660+ return $utf8;
661661
662 - } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
663 - // array, or object notation
 662+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
 663+ // array, or object notation
664664
665 - if ($str{0} == '[') {
666 - $stk = array(SERVICES_JSON_IN_ARR);
667 - $arr = array();
668 - } else {
669 - if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
670 - $stk = array(SERVICES_JSON_IN_OBJ);
671 - $obj = array();
672 - } else {
673 - $stk = array(SERVICES_JSON_IN_OBJ);
674 - $obj = new stdClass();
675 - }
676 - }
 665+ if ($str{0} == '[') {
 666+ $stk = array(SERVICES_JSON_IN_ARR);
 667+ $arr = array();
 668+ } else {
 669+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
 670+ $stk = array(SERVICES_JSON_IN_OBJ);
 671+ $obj = array();
 672+ } else {
 673+ $stk = array(SERVICES_JSON_IN_OBJ);
 674+ $obj = new stdClass();
 675+ }
 676+ }
677677
678 - array_push($stk, array('what' => SERVICES_JSON_SLICE,
679 - 'where' => 0,
680 - 'delim' => false));
 678+ array_push($stk, array( 'what' => SERVICES_JSON_SLICE,
 679+ 'where' => 0,
 680+ 'delim' => false));
681681
682 - $chrs = substr($str, 1, -1);
683 - $chrs = $this->reduce_string($chrs);
 682+ $chrs = substr($str, 1, -1);
 683+ $chrs = $this->reduce_string($chrs);
684684
685 - if ($chrs == '') {
686 - if (reset($stk) == SERVICES_JSON_IN_ARR) {
687 - return $arr;
 685+ if ($chrs == '') {
 686+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
 687+ return $arr;
688688
689 - } else {
690 - return $obj;
 689+ } else {
 690+ return $obj;
691691
692 - }
693 - }
 692+ }
 693+ }
694694
695 - //print("\nparsing {$chrs}\n");
 695+ //print("\nparsing {$chrs}\n");
696696
697 - $strlen_chrs = strlen($chrs);
 697+ $strlen_chrs = strlen($chrs);
698698
699 - for ($c = 0; $c <= $strlen_chrs; ++$c) {
 699+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
700700
701 - $top = end($stk);
702 - $substr_chrs_c_2 = substr($chrs, $c, 2);
 701+ $top = end($stk);
 702+ $substr_chrs_c_2 = substr($chrs, $c, 2);
703703
704 - if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
705 - // found a comma that is not inside a string, array, etc.,
706 - // OR we've reached the end of the character list
707 - $slice = substr($chrs, $top['where'], ($c - $top['where']));
708 - array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
709 - //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
 704+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
 705+ // found a comma that is not inside a string, array, etc.,
 706+ // OR we've reached the end of the character list
 707+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
 708+ array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
 709+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
710710
711 - if (reset($stk) == SERVICES_JSON_IN_ARR) {
712 - // we are in an array, so just push an element onto the stack
713 - array_push($arr, $this->decode($slice));
 711+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
 712+ // we are in an array, so just push an element onto the stack
 713+ array_push($arr, $this->decode($slice));
714714
715 - } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
716 - // we are in an object, so figure
717 - // out the property name and set an
718 - // element in an associative array,
719 - // for now
720 - $parts = array();
 715+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
 716+ // we are in an object, so figure
 717+ // out the property name and set an
 718+ // element in an associative array,
 719+ // for now
 720+ $parts = array();
721721
722 - if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
723 - // "name":value pair
724 - $key = $this->decode($parts[1]);
725 - $val = $this->decode($parts[2]);
 722+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
 723+ // "name":value pair
 724+ $key = $this->decode($parts[1]);
 725+ $val = $this->decode($parts[2]);
726726
727 - if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
728 - $obj[$key] = $val;
729 - } else {
730 - $obj->$key = $val;
731 - }
732 - } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
733 - // name:value pair, where name is unquoted
734 - $key = $parts[1];
735 - $val = $this->decode($parts[2]);
 727+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
 728+ $obj[$key] = $val;
 729+ } else {
 730+ $obj->$key = $val;
 731+ }
 732+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
 733+ // name:value pair, where name is unquoted
 734+ $key = $parts[1];
 735+ $val = $this->decode($parts[2]);
736736
737 - if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
738 - $obj[$key] = $val;
739 - } else {
740 - $obj->$key = $val;
741 - }
742 - }
 737+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
 738+ $obj[$key] = $val;
 739+ } else {
 740+ $obj->$key = $val;
 741+ }
 742+ }
743743
744 - }
 744+ }
745745
746 - } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
747 - // found a quote, and we are not inside a string
748 - array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
749 - //print("Found start of string at {$c}\n");
 746+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
 747+ // found a quote, and we are not inside a string
 748+ array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
 749+ //print("Found start of string at {$c}\n");
750750
751 - } elseif (($chrs{$c} == $top['delim']) &&
752 - ($top['what'] == SERVICES_JSON_IN_STR) &&
753 - (($chrs{$c - 1} != '\\') ||
754 - ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
755 - // found a quote, we're in a string, and it's not escaped
756 - array_pop($stk);
757 - //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
 751+ } elseif (($chrs{$c} == $top['delim']) &&
 752+ ($top['what'] == SERVICES_JSON_IN_STR) &&
 753+ (($chrs{$c - 1} != '\\') ||
 754+ ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
 755+ // found a quote, we're in a string, and it's not escaped
 756+ array_pop($stk);
 757+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
758758
759 - } elseif (($chrs{$c} == '[') &&
760 - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
761 - // found a left-bracket, and we are in an array, object, or slice
762 - array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
763 - //print("Found start of array at {$c}\n");
 759+ } elseif (($chrs{$c} == '[') &&
 760+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
 761+ // found a left-bracket, and we are in an array, object, or slice
 762+ array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
 763+ //print("Found start of array at {$c}\n");
764764
765 - } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
766 - // found a right-bracket, and we're in an array
767 - array_pop($stk);
768 - //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
 765+ } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
 766+ // found a right-bracket, and we're in an array
 767+ array_pop($stk);
 768+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
769769
770 - } elseif (($chrs{$c} == '{') &&
771 - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
772 - // found a left-brace, and we are in an array, object, or slice
773 - array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
774 - //print("Found start of object at {$c}\n");
 770+ } elseif (($chrs{$c} == '{') &&
 771+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
 772+ // found a left-brace, and we are in an array, object, or slice
 773+ array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
 774+ //print("Found start of object at {$c}\n");
775775
776 - } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
777 - // found a right-brace, and we're in an object
778 - array_pop($stk);
779 - //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
 776+ } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
 777+ // found a right-brace, and we're in an object
 778+ array_pop($stk);
 779+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
780780
781 - } elseif (($substr_chrs_c_2 == '/*') &&
782 - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
783 - // found a comment start, and we are in an array, object, or slice
784 - array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
785 - $c++;
786 - //print("Found start of comment at {$c}\n");
 781+ } elseif (($substr_chrs_c_2 == '/*') &&
 782+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
 783+ // found a comment start, and we are in an array, object, or slice
 784+ array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
 785+ $c++;
 786+ //print("Found start of comment at {$c}\n");
787787
788 - } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
789 - // found a comment end, and we're in one now
790 - array_pop($stk);
791 - $c++;
 788+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
 789+ // found a comment end, and we're in one now
 790+ array_pop($stk);
 791+ $c++;
792792
793 - for ($i = $top['where']; $i <= $c; ++$i)
794 - $chrs = substr_replace($chrs, ' ', $i, 1);
 793+ for ($i = $top['where']; $i <= $c; ++$i)
 794+ $chrs = substr_replace($chrs, ' ', $i, 1);
795795
796 - //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
 796+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
797797
798 - }
 798+ }
799799
800 - }
 800+ }
801801
802 - if (reset($stk) == SERVICES_JSON_IN_ARR) {
803 - return $arr;
 802+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
 803+ return $arr;
804804
805 - } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
806 - return $obj;
 805+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
 806+ return $obj;
807807
808 - }
 808+ }
809809
810 - }
811 - }
812 - }
 810+ }
 811+ }
 812+ }
813813
814 - /**
815 - * @todo Ultimately, this should just call PEAR::isError()
816 - */
817 - function isError($data, $code = null)
818 - {
819 - if (class_exists('pear')) {
820 - return PEAR::isError($data, $code);
821 - } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
822 - is_subclass_of($data, 'services_json_error'))) {
823 - return true;
824 - }
 814+ /**
 815+ * @todo Ultimately, this should just call PEAR::isError()
 816+ */
 817+ function isError($data, $code = null)
 818+ {
 819+ if (class_exists('pear')) {
 820+ return PEAR::isError($data, $code);
 821+ } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
 822+ is_subclass_of($data, 'services_json_error'))) {
 823+ return true;
 824+ }
825825
826 - return false;
827 - }
 826+ return false;
 827+ }
828828 }
829829
830830
@@ -831,31 +831,31 @@
832832 /// @cond
833833 if (class_exists('PEAR_Error')) {
834834
835 - /**
836 - * @ingroup API
837 - */
838 - class Services_JSON_Error extends PEAR_Error
839 - {
840 - function Services_JSON_Error($message = 'unknown error', $code = null,
841 - $mode = null, $options = null, $userinfo = null)
842 - {
843 - parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
844 - }
845 - }
 835+ /**
 836+ * @ingroup API
 837+ */
 838+ class Services_JSON_Error extends PEAR_Error
 839+ {
 840+ function Services_JSON_Error($message = 'unknown error', $code = null,
 841+ $mode = null, $options = null, $userinfo = null)
 842+ {
 843+ parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
 844+ }
 845+ }
846846
847847 } else {
848848 /// @endcond
849849
850 - /**
851 - * @todo Ultimately, this class shall be descended from PEAR_Error
852 - * @ingroup API
853 - */
854 - class Services_JSON_Error
855 - {
856 - function Services_JSON_Error($message = 'unknown error', $code = null,
857 - $mode = null, $options = null, $userinfo = null)
858 - {
 850+ /**
 851+ * @todo Ultimately, this class shall be descended from PEAR_Error
 852+ * @ingroup API
 853+ */
 854+ class Services_JSON_Error
 855+ {
 856+ function Services_JSON_Error($message = 'unknown error', $code = null,
 857+ $mode = null, $options = null, $userinfo = null)
 858+ {
859859
860 - }
861 - }
 860+ }
 861+ }
862862 }
Index: trunk/phase3/includes/SearchIBM_DB2.php
@@ -1,247 +1,247 @@
2 -<?php
3 -# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
4 -# http://www.mediawiki.org/
5 -#
6 -# This program is free software; you can redistribute it and/or modify
7 -# it under the terms of the GNU General Public License as published by
8 -# the Free Software Foundation; either version 2 of the License, or
9 -# (at your option) any later version.
10 -#
11 -# This program is distributed in the hope that it will be useful,
12 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
13 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 -# GNU General Public License for more details.
15 -#
16 -# You should have received a copy of the GNU General Public License along
17 -# with this program; if not, write to the Free Software Foundation, Inc.,
18 -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 -# http://www.gnu.org/copyleft/gpl.html
20 -
21 -/**
22 - * @file
23 - * @ingroup Search
24 - */
25 -
26 -/**
27 - * Search engine hook base class for IBM DB2
28 - * @ingroup Search
29 - */
30 -class SearchIBM_DB2 extends SearchEngine {
31 - function __construct($db) {
32 - $this->db = $db;
33 - }
34 -
35 - /**
36 - * Perform a full text search query and return a result set.
37 - *
38 - * @param string $term - Raw search term
39 - * @return IBM_DB2SearchResultSet
40 - * @access public
41 - */
42 - function searchText( $term ) {
43 - $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), true)));
44 - return new IBM_DB2SearchResultSet($resultSet, $this->searchTerms);
45 - }
46 -
47 - /**
48 - * Perform a title-only search query and return a result set.
49 - *
50 - * @param string $term - Raw search term
51 - * @return IBM_DB2SearchResultSet
52 - * @access public
53 - */
54 - function searchTitle($term) {
55 - $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), false)));
56 - return new MySQLSearchResultSet($resultSet, $this->searchTerms);
57 - }
58 -
59 -
60 - /**
61 - * Return a partial WHERE clause to exclude redirects, if so set
62 - * @return string
63 - * @private
64 - */
65 - function queryRedirect() {
66 - if ($this->showRedirects) {
67 - return '';
68 - } else {
69 - return 'AND page_is_redirect=0';
70 - }
71 - }
72 -
73 - /**
74 - * Return a partial WHERE clause to limit the search to the given namespaces
75 - * @return string
76 - * @private
77 - */
78 - function queryNamespaces() {
79 - if( is_null($this->namespaces) )
80 - return '';
81 - $namespaces = implode(',', $this->namespaces);
82 - if ($namespaces == '') {
83 - $namespaces = '0';
84 - }
85 - return 'AND page_namespace IN (' . $namespaces . ')';
86 - }
87 -
88 - /**
89 - * Return a LIMIT clause to limit results on the query.
90 - * @return string
91 - * @private
92 - */
93 - function queryLimit($sql) {
94 - return $this->db->limitResult($sql, $this->limit, $this->offset);
95 - }
96 -
97 - /**
98 - * Does not do anything for generic search engine
99 - * subclasses may define this though
100 - * @return string
101 - * @private
102 - */
103 - function queryRanking($filteredTerm, $fulltext) {
104 - // requires Net Search Extender or equivalent
105 - // return ' ORDER BY score(1)';
106 - return '';
107 - }
108 -
109 - /**
110 - * Construct the full SQL query to do the search.
111 - * The guts shoulds be constructed in queryMain()
112 - * @param string $filteredTerm
113 - * @param bool $fulltext
114 - * @private
115 - */
116 - function getQuery( $filteredTerm, $fulltext ) {
117 - return $this->queryLimit($this->queryMain($filteredTerm, $fulltext) . ' ' .
118 - $this->queryRedirect() . ' ' .
119 - $this->queryNamespaces() . ' ' .
120 - $this->queryRanking( $filteredTerm, $fulltext ) . ' ');
121 - }
122 -
123 -
124 - /**
125 - * Picks which field to index on, depending on what type of query.
126 - * @param bool $fulltext
127 - * @return string
128 - */
129 - function getIndexField($fulltext) {
130 - return $fulltext ? 'si_text' : 'si_title';
131 - }
132 -
133 - /**
134 - * Get the base part of the search query.
135 - *
136 - * @param string $filteredTerm
137 - * @param bool $fulltext
138 - * @return string
139 - * @private
140 - */
141 - function queryMain( $filteredTerm, $fulltext ) {
142 - $match = $this->parseQuery($filteredTerm, $fulltext);
143 - $page = $this->db->tableName('page');
144 - $searchindex = $this->db->tableName('searchindex');
145 - return 'SELECT page_id, page_namespace, page_title ' .
146 - "FROM $page,$searchindex " .
147 - 'WHERE page_id=si_page AND ' . $match;
148 - }
149 -
150 - /** @todo document */
151 - function parseQuery($filteredText, $fulltext) {
152 - global $wgContLang;
153 - $lc = SearchEngine::legalSearchChars();
154 - $this->searchTerms = array();
155 -
156 - # FIXME: This doesn't handle parenthetical expressions.
157 - $m = array();
158 - $q = array();
159 -
160 - if (preg_match_all('/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
161 - $filteredText, $m, PREG_SET_ORDER)) {
162 - foreach($m as $terms) {
163 - $q[] = $terms[1] . $wgContLang->stripForSearch($terms[2]);
164 -
165 - if (!empty($terms[3])) {
166 - $regexp = preg_quote( $terms[3], '/' );
167 - if ($terms[4])
168 - $regexp .= "[0-9A-Za-z_]+";
169 - } else {
170 - $regexp = preg_quote(str_replace('"', '', $terms[2]), '/');
171 - }
172 - $this->searchTerms[] = $regexp;
173 - }
174 - }
175 -
176 - $searchon = $this->db->strencode(join(',', $q));
177 - $field = $this->getIndexField($fulltext);
178 -
179 - // requires Net Search Extender or equivalent
180 - //return " CONTAINS($field, '$searchon') > 0 ";
181 -
182 - return " lcase($field) LIKE lcase('%$searchon%')";
183 - }
184 -
185 - /**
186 - * Create or update the search index record for the given page.
187 - * Title and text should be pre-processed.
188 - *
189 - * @param int $id
190 - * @param string $title
191 - * @param string $text
192 - */
193 - function update($id, $title, $text) {
194 - $dbw = wfGetDB(DB_MASTER);
195 - $dbw->replace('searchindex',
196 - array('si_page'),
197 - array(
198 - 'si_page' => $id,
199 - 'si_title' => $title,
200 - 'si_text' => $text
201 - ), 'SearchIBM_DB2::update' );
202 - // ?
203 - //$dbw->query("CALL ctx_ddl.sync_index('si_text_idx')");
204 - //$dbw->query("CALL ctx_ddl.sync_index('si_title_idx')");
205 - }
206 -
207 - /**
208 - * Update a search index record's title only.
209 - * Title should be pre-processed.
210 - *
211 - * @param int $id
212 - * @param string $title
213 - */
214 - function updateTitle($id, $title) {
215 - $dbw = wfGetDB(DB_MASTER);
216 -
217 - $dbw->update('searchindex',
218 - array('si_title' => $title),
219 - array('si_page' => $id),
220 - 'SearchIBM_DB2::updateTitle',
221 - array());
222 - }
223 -}
224 -
225 -/**
226 - * @ingroup Search
227 - */
228 -class IBM_DB2SearchResultSet extends SearchResultSet {
229 - function __construct($resultSet, $terms) {
230 - $this->mResultSet = $resultSet;
231 - $this->mTerms = $terms;
232 - }
233 -
234 - function termMatches() {
235 - return $this->mTerms;
236 - }
237 -
238 - function numRows() {
239 - return $this->mResultSet->numRows();
240 - }
241 -
242 - function next() {
243 - $row = $this->mResultSet->fetchObject();
244 - if ($row === false)
245 - return false;
246 - return new SearchResult($row);
247 - }
248 -}
 2+<?php
 3+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
 4+# http://www.mediawiki.org/
 5+#
 6+# This program is free software; you can redistribute it and/or modify
 7+# it under the terms of the GNU General Public License as published by
 8+# the Free Software Foundation; either version 2 of the License, or
 9+# (at your option) any later version.
 10+#
 11+# This program is distributed in the hope that it will be useful,
 12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 14+# GNU General Public License for more details.
 15+#
 16+# You should have received a copy of the GNU General Public License along
 17+# with this program; if not, write to the Free Software Foundation, Inc.,
 18+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 19+# http://www.gnu.org/copyleft/gpl.html
 20+
 21+/**
 22+ * @file
 23+ * @ingroup Search
 24+ */
 25+
 26+/**
 27+ * Search engine hook base class for IBM DB2
 28+ * @ingroup Search
 29+ */
 30+class SearchIBM_DB2 extends SearchEngine {
 31+ function __construct($db) {
 32+ $this->db = $db;
 33+ }
 34+
 35+ /**
 36+ * Perform a full text search query and return a result set.
 37+ *
 38+ * @param string $term - Raw search term
 39+ * @return IBM_DB2SearchResultSet
 40+ * @access public
 41+ */
 42+ function searchText( $term ) {
 43+ $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), true)));
 44+ return new IBM_DB2SearchResultSet($resultSet, $this->searchTerms);
 45+ }
 46+
 47+ /**
 48+ * Perform a title-only search query and return a result set.
 49+ *
 50+ * @param string $term - Raw search term
 51+ * @return IBM_DB2SearchResultSet
 52+ * @access public
 53+ */
 54+ function searchTitle($term) {
 55+ $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), false)));
 56+ return new MySQLSearchResultSet($resultSet, $this->searchTerms);
 57+ }
 58+
 59+
 60+ /**
 61+ * Return a partial WHERE clause to exclude redirects, if so set
 62+ * @return string
 63+ * @private
 64+ */
 65+ function queryRedirect() {
 66+ if ($this->showRedirects) {
 67+ return '';
 68+ } else {
 69+ return 'AND page_is_redirect=0';
 70+ }
 71+ }
 72+
 73+ /**
 74+ * Return a partial WHERE clause to limit the search to the given namespaces
 75+ * @return string
 76+ * @private
 77+ */
 78+ function queryNamespaces() {
 79+ if( is_null($this->namespaces) )
 80+ return '';
 81+ $namespaces = implode(',', $this->namespaces);
 82+ if ($namespaces == '') {
 83+ $namespaces = '0';
 84+ }
 85+ return 'AND page_namespace IN (' . $namespaces . ')';
 86+ }
 87+
 88+ /**
 89+ * Return a LIMIT clause to limit results on the query.
 90+ * @return string
 91+ * @private
 92+ */
 93+ function queryLimit($sql) {
 94+ return $this->db->limitResult($sql, $this->limit, $this->offset);
 95+ }
 96+
 97+ /**
 98+ * Does not do anything for generic search engine
 99+ * subclasses may define this though
 100+ * @return string
 101+ * @private
 102+ */
 103+ function queryRanking($filteredTerm, $fulltext) {
 104+ // requires Net Search Extender or equivalent
 105+ // return ' ORDER BY score(1)';
 106+ return '';
 107+ }
 108+
 109+ /**
 110+ * Construct the full SQL query to do the search.
 111+ * The guts shoulds be constructed in queryMain()
 112+ * @param string $filteredTerm
 113+ * @param bool $fulltext
 114+ * @private
 115+ */
 116+ function getQuery( $filteredTerm, $fulltext ) {
 117+ return $this->queryLimit($this->queryMain($filteredTerm, $fulltext) . ' ' .
 118+ $this->queryRedirect() . ' ' .
 119+ $this->queryNamespaces() . ' ' .
 120+ $this->queryRanking( $filteredTerm, $fulltext ) . ' ');
 121+ }
 122+
 123+
 124+ /**
 125+ * Picks which field to index on, depending on what type of query.
 126+ * @param bool $fulltext
 127+ * @return string
 128+ */
 129+ function getIndexField($fulltext) {
 130+ return $fulltext ? 'si_text' : 'si_title';
 131+ }
 132+
 133+ /**
 134+ * Get the base part of the search query.
 135+ *
 136+ * @param string $filteredTerm
 137+ * @param bool $fulltext
 138+ * @return string
 139+ * @private
 140+ */
 141+ function queryMain( $filteredTerm, $fulltext ) {
 142+ $match = $this->parseQuery($filteredTerm, $fulltext);
 143+ $page = $this->db->tableName('page');
 144+ $searchindex = $this->db->tableName('searchindex');
 145+ return 'SELECT page_id, page_namespace, page_title ' .
 146+ "FROM $page,$searchindex " .
 147+ 'WHERE page_id=si_page AND ' . $match;
 148+ }
 149+
 150+ /** @todo document */
 151+ function parseQuery($filteredText, $fulltext) {
 152+ global $wgContLang;
 153+ $lc = SearchEngine::legalSearchChars();
 154+ $this->searchTerms = array();
 155+
 156+ # FIXME: This doesn't handle parenthetical expressions.
 157+ $m = array();
 158+ $q = array();
 159+
 160+ if (preg_match_all('/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
 161+ $filteredText, $m, PREG_SET_ORDER)) {
 162+ foreach($m as $terms) {
 163+ $q[] = $terms[1] . $wgContLang->stripForSearch($terms[2]);
 164+
 165+ if (!empty($terms[3])) {
 166+ $regexp = preg_quote( $terms[3], '/' );
 167+ if ($terms[4])
 168+ $regexp .= "[0-9A-Za-z_]+";
 169+ } else {
 170+ $regexp = preg_quote(str_replace('"', '', $terms[2]), '/');
 171+ }
 172+ $this->searchTerms[] = $regexp;
 173+ }
 174+ }
 175+
 176+ $searchon = $this->db->strencode(join(',', $q));
 177+ $field = $this->getIndexField($fulltext);
 178+
 179+ // requires Net Search Extender or equivalent
 180+ //return " CONTAINS($field, '$searchon') > 0 ";
 181+
 182+ return " lcase($field) LIKE lcase('%$searchon%')";
 183+ }
 184+
 185+ /**
 186+ * Create or update the search index record for the given page.
 187+ * Title and text should be pre-processed.
 188+ *
 189+ * @param int $id
 190+ * @param string $title
 191+ * @param string $text
 192+ */
 193+ function update($id, $title, $text) {
 194+ $dbw = wfGetDB(DB_MASTER);
 195+ $dbw->replace('searchindex',
 196+ array('si_page'),
 197+ array(
 198+ 'si_page' => $id,
 199+ 'si_title' => $title,
 200+ 'si_text' => $text
 201+ ), 'SearchIBM_DB2::update' );
 202+ // ?
 203+ //$dbw->query("CALL ctx_ddl.sync_index('si_text_idx')");
 204+ //$dbw->query("CALL ctx_ddl.sync_index('si_title_idx')");
 205+ }
 206+
 207+ /**
 208+ * Update a search index record's title only.
 209+ * Title should be pre-processed.
 210+ *
 211+ * @param int $id
 212+ * @param string $title
 213+ */
 214+ function updateTitle($id, $title) {
 215+ $dbw = wfGetDB(DB_MASTER);
 216+
 217+ $dbw->update('searchindex',
 218+ array('si_title' => $title),
 219+ array('si_page' => $id),
 220+ 'SearchIBM_DB2::updateTitle',
 221+ array());
 222+ }
 223+}
 224+
 225+/**
 226+ * @ingroup Search
 227+ */
 228+class IBM_DB2SearchResultSet extends SearchResultSet {
 229+ function __construct($resultSet, $terms) {
 230+ $this->mResultSet = $resultSet;
 231+ $this->mTerms = $terms;
 232+ }
 233+
 234+ function termMatches() {
 235+ return $this->mTerms;
 236+ }
 237+
 238+ function numRows() {
 239+ return $this->mResultSet->numRows();
 240+ }
 241+
 242+ function next() {
 243+ $row = $this->mResultSet->fetchObject();
 244+ if ($row === false)
 245+ return false;
 246+ return new SearchResult($row);
 247+ }
 248+}
Property changes on: trunk/phase3/includes/SearchIBM_DB2.php
___________________________________________________________________
Name: svn:eol-style
249249 + native

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r45755(bug 17028) Added support for IBM DB2 database. config/index.php has new inte...leonsp22:20, 14 January 2009

Status & tagging log