r51500 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r51499‎ | r51500 | r51501 >
Date:11:45, 5 June 2009
Author:freakolowsky
Status:ok (Comments)
Tags:
Comment:
Oracle database abstraction updated.
Rewriten tables.sql, added user.sql (creating db user with privileges)
Fixed epoch in Special Ancientpages and Unusedimages
Timestamp default format altered in db abstraction and changed wfTimestamp function
SearchOracle changed to return empty resultset on empty term search (query error in oracle)
TODO: Maintenance scripts update
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/GlobalFunctions.php (modified) (history)
  • /trunk/phase3/includes/SearchOracle.php (modified) (history)
  • /trunk/phase3/includes/db/DatabaseOracle.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialAncientpages.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialUnusedimages.php (modified) (history)
  • /trunk/phase3/maintenance/ora/tables.sql (modified) (history)
  • /trunk/phase3/maintenance/ora/user.sql (added) (history)

Diff [purge]

Index: trunk/phase3/maintenance/ora/tables.sql
@@ -1,443 +1,630 @@
 2+DEFINE mw_prefix='';
23
 4+
35 CREATE SEQUENCE user_user_id_seq MINVALUE 0 START WITH 0;
4 -
5 -CREATE TABLE mwuser ( -- replace reserved word 'user'
6 - user_id INTEGER NOT NULL PRIMARY KEY,
7 - user_name VARCHAR(255) NOT NULL UNIQUE,
8 - user_real_name CLOB,
9 - user_password CLOB,
10 - user_newpassword CLOB,
11 - user_newpass_time TIMESTAMP WITH TIME ZONE,
12 - user_token CHAR(32),
13 - user_email CLOB,
14 - user_email_token CHAR(32),
15 - user_email_token_expires TIMESTAMP WITH TIME ZONE,
16 - user_email_authenticated TIMESTAMP WITH TIME ZONE,
 6+CREATE TABLE &mw_prefix.mwuser ( -- replace reserved word 'user'
 7+ user_id NUMBER NOT NULL,
 8+ user_name VARCHAR2(255) NOT NULL,
 9+ user_real_name VARCHAR2(512),
 10+ user_password VARCHAR2(255),
 11+ user_newpassword VARCHAR2(255),
 12+ user_newpass_time TIMESTAMP(6) WITH TIME ZONE,
 13+ user_token VARCHAR2(32),
 14+ user_email VARCHAR2(255),
 15+ user_email_token VARCHAR2(32),
 16+ user_email_token_expires TIMESTAMP(6) WITH TIME ZONE,
 17+ user_email_authenticated TIMESTAMP(6) WITH TIME ZONE,
1718 user_options CLOB,
18 - user_touched TIMESTAMP WITH TIME ZONE,
19 - user_registration TIMESTAMP WITH TIME ZONE,
20 - user_editcount INTEGER
 19+ user_touched TIMESTAMP(6) WITH TIME ZONE,
 20+ user_registration TIMESTAMP(6) WITH TIME ZONE,
 21+ user_editcount NUMBER
2122 );
22 -CREATE INDEX user_email_token_idx ON mwuser (user_email_token);
 23+ALTER TABLE &mw_prefix.mwuser ADD CONSTRAINT &mw_prefix.mwuser_pk PRIMARY KEY (user_id);
 24+CREATE UNIQUE INDEX &mw_prefix.mwuser_u01 ON &mw_prefix.mwuser (user_name);
 25+CREATE INDEX &mw_prefix.mwuser_i01 ON &mw_prefix.mwuser (user_email_token);
2326
2427 -- Create a dummy user to satisfy fk contraints especially with revisions
25 -INSERT INTO mwuser
 28+INSERT INTO &mw_prefix.mwuser
2629 VALUES (user_user_id_seq.nextval,'Anonymous','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, '', current_timestamp, current_timestamp, 0);
2730
28 -CREATE TABLE user_groups (
29 - ug_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
30 - ug_group CHAR(16) NOT NULL
 31+CREATE TABLE &mw_prefix.user_groups (
 32+ ug_user NUMBER NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE,
 33+ ug_group VARCHAR2(16) NOT NULL
3134 );
32 -CREATE UNIQUE INDEX user_groups_unique ON user_groups (ug_user, ug_group);
 35+CREATE UNIQUE INDEX &mw_prefix.user_groups_u01 ON &mw_prefix.user_groups (ug_user,ug_group);
 36+CREATE INDEX &mw_prefix.user_groups_i01 ON &mw_prefix.user_groups (ug_group);
3337
34 -CREATE TABLE user_newtalk (
35 - user_id INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
36 - user_ip VARCHAR(40) NULL
 38+CREATE TABLE &mw_prefix.user_newtalk (
 39+ user_id NUMBER NOT NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE,
 40+ user_ip VARCHAR2(40) NULL,
 41+ user_last_timestamp TIMESTAMP(6) WITH TIME ZONE
3742 );
38 -CREATE INDEX user_newtalk_id_idx ON user_newtalk (user_id);
39 -CREATE INDEX user_newtalk_ip_idx ON user_newtalk (user_ip);
 43+CREATE INDEX &mw_prefix.user_newtalk_i01 ON &mw_prefix.user_newtalk (user_id);
 44+CREATE INDEX &mw_prefix.user_newtalk_i02 ON &mw_prefix.user_newtalk (user_ip);
4045
 46+CREATE TABLE &mw_prefix.user_properties (
 47+ up_user NUMBER NOT NULL,
 48+ up_property VARCHAR2(32) NOT NULL,
 49+ up_value BLOB
 50+);
 51+CREATE UNIQUE INDEX &mw_prefix.user_properties_u01 on &mw_prefix.user_properties (up_user,up_property);
 52+CREATE INDEX &mw_prefix.user_properties_i01 on &mw_prefix.user_properties (up_property);
 53+
 54+
4155 CREATE SEQUENCE page_page_id_seq;
42 -CREATE TABLE page (
43 - page_id INTEGER NOT NULL PRIMARY KEY,
44 - page_namespace SMALLINT NOT NULL,
45 - page_title VARCHAR(255) NOT NULL,
46 - page_restrictions CLOB,
47 - page_counter INTEGER DEFAULT 0 NOT NULL,
48 - page_is_redirect CHAR DEFAULT 0 NOT NULL,
49 - page_is_new CHAR DEFAULT 0 NOT NULL,
50 - page_random NUMERIC(15,14) NOT NULL,
51 - page_touched TIMESTAMP WITH TIME ZONE,
52 - page_latest INTEGER NOT NULL, -- FK?
53 - page_len INTEGER NOT NULL
 56+CREATE TABLE &mw_prefix.page (
 57+ page_id NUMBER NOT NULL,
 58+ page_namespace NUMBER NOT NULL,
 59+ page_title VARCHAR2(255) NOT NULL,
 60+ page_restrictions VARCHAR2(255),
 61+ page_counter NUMBER DEFAULT 0 NOT NULL,
 62+ page_is_redirect CHAR(1) DEFAULT 0 NOT NULL,
 63+ page_is_new CHAR(1) DEFAULT 0 NOT NULL,
 64+ page_random NUMBER(15,14) NOT NULL,
 65+ page_touched TIMESTAMP(6) WITH TIME ZONE,
 66+ page_latest NUMBER NOT NULL, -- FK?
 67+ page_len NUMBER NOT NULL
5468 );
55 -CREATE UNIQUE INDEX page_unique_name ON page (page_namespace, page_title);
56 -CREATE INDEX page_random_idx ON page (page_random);
57 -CREATE INDEX page_len_idx ON page (page_len);
 69+ALTER TABLE &mw_prefix.page ADD CONSTRAINT &mw_prefix.page_pk PRIMARY KEY (page_id);
 70+CREATE UNIQUE INDEX &mw_prefix.page_u01 ON &mw_prefix.page (page_namespace,page_title);
 71+CREATE INDEX &mw_prefix.page_i01 ON &mw_prefix.page (page_random);
 72+CREATE INDEX &mw_prefix.page_i02 ON &mw_prefix.page (page_len);
5873
59 -CREATE TRIGGER page_set_random BEFORE INSERT ON page
 74+CREATE TRIGGER &mw_prefix.page_set_random BEFORE INSERT ON &mw_prefix.page
6075 FOR EACH ROW WHEN (new.page_random IS NULL)
6176 BEGIN
62 - SELECT dbms_random.value INTO :new.page_random FROM dual;
 77+ SELECT dbms_random.value INTO :NEW.page_random FROM dual;
6378 END;
6479 /
6580
6681 CREATE SEQUENCE rev_rev_id_val;
67 -CREATE TABLE revision (
68 - rev_id INTEGER NOT NULL PRIMARY KEY,
69 - rev_page INTEGER NULL REFERENCES page (page_id) ON DELETE CASCADE,
70 - rev_text_id INTEGER NULL, -- FK
71 - rev_comment CLOB,
72 - rev_user INTEGER NOT NULL REFERENCES mwuser(user_id),
73 - rev_user_text VARCHAR(255) NOT NULL,
74 - rev_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
75 - rev_minor_edit CHAR DEFAULT '0' NOT NULL,
76 - rev_deleted CHAR DEFAULT '0' NOT NULL,
77 - rev_len INTEGER NULL,
78 - rev_parent_id INTEGER DEFAULT NULL
 82+CREATE TABLE &mw_prefix.revision (
 83+ rev_id NUMBER NOT NULL,
 84+ rev_page NUMBER NULL REFERENCES &mw_prefix.page (page_id) ON DELETE CASCADE,
 85+ rev_text_id NUMBER NULL,
 86+ rev_comment VARCHAR2(255),
 87+ rev_user NUMBER NOT NULL REFERENCES &mw_prefix.mwuser(user_id),
 88+ rev_user_text VARCHAR2(255) NOT NULL,
 89+ rev_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 90+ rev_minor_edit CHAR(1) DEFAULT '0' NOT NULL,
 91+ rev_deleted CHAR(1) DEFAULT '0' NOT NULL,
 92+ rev_len NUMBER NULL,
 93+ rev_parent_id NUMBER DEFAULT NULL
7994 );
80 -CREATE UNIQUE INDEX revision_unique ON revision (rev_page, rev_id);
81 -CREATE INDEX rev_text_id_idx ON revision (rev_text_id);
82 -CREATE INDEX rev_timestamp_idx ON revision (rev_timestamp);
83 -CREATE INDEX rev_user_idx ON revision (rev_user);
84 -CREATE INDEX rev_user_text_idx ON revision (rev_user_text);
 95+ALTER TABLE &mw_prefix.revision ADD CONSTRAINT &mw_prefix.revision_pk PRIMARY KEY (rev_id);
 96+CREATE UNIQUE INDEX &mw_prefix.revision_u01 ON &mw_prefix.revision (rev_page, rev_id);
 97+CREATE INDEX &mw_prefix.revision_i01 ON &mw_prefix.revision (rev_timestamp);
 98+CREATE INDEX &mw_prefix.revision_i02 ON &mw_prefix.revision (rev_page,rev_timestamp);
 99+CREATE INDEX &mw_prefix.revision_i03 ON &mw_prefix.revision (rev_user,rev_timestamp);
 100+CREATE INDEX &mw_prefix.revision_i04 ON &mw_prefix.revision (rev_user_text,rev_timestamp);
85101
86 -
87102 CREATE SEQUENCE text_old_id_val;
88 -CREATE TABLE pagecontent ( -- replaces reserved word 'text'
89 - old_id INTEGER NOT NULL PRIMARY KEY,
 103+CREATE TABLE &mw_prefix.pagecontent ( -- replaces reserved word 'text'
 104+ old_id NUMBER NOT NULL,
90105 old_text CLOB,
91 - old_flags CLOB
 106+ old_flags VARCHAR2(255)
92107 );
 108+ALTER TABLE &mw_prefix.pagecontent ADD CONSTRAINT &mw_prefix.pagecontent_pk PRIMARY KEY (old_id);
93109
94 -
95 -CREATE SEQUENCE pr_id_val;
96 -CREATE TABLE page_restrictions (
97 - pr_id INTEGER NOT NULL UNIQUE,
98 - pr_page INTEGER NULL REFERENCES page (page_id) ON DELETE CASCADE,
99 - pr_type VARCHAR(255) NOT NULL,
100 - pr_level VARCHAR(255) NOT NULL,
101 - pr_cascade SMALLINT NOT NULL,
102 - pr_user INTEGER NULL,
103 - pr_expiry TIMESTAMP WITH TIME ZONE NULL
104 -);
105 -ALTER TABLE page_restrictions ADD CONSTRAINT page_restrictions_pk PRIMARY KEY (pr_page,pr_type);
106 -
107 -CREATE TABLE archive (
108 - ar_namespace SMALLINT NOT NULL,
109 - ar_title VARCHAR(255) NOT NULL,
 110+CREATE TABLE &mw_prefix.archive (
 111+ ar_namespace NUMBER NOT NULL,
 112+ ar_title VARCHAR2(255) NOT NULL,
110113 ar_text CLOB,
111 - ar_comment CLOB,
112 - ar_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
113 - ar_user_text CLOB NOT NULL,
114 - ar_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
115 - ar_minor_edit CHAR DEFAULT '0' NOT NULL,
116 - ar_flags CLOB,
117 - ar_rev_id INTEGER,
118 - ar_text_id INTEGER,
119 - ar_deleted INTEGER DEFAULT '0' NOT NULL
 114+ ar_comment VARCHAR2(255),
 115+ ar_user NUMBER NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL,
 116+ ar_user_text VARCHAR2(255) NOT NULL,
 117+ ar_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 118+ ar_minor_edit CHAR(1) DEFAULT '0' NOT NULL,
 119+ ar_flags VARCHAR2(255),
 120+ ar_rev_id NUMBER,
 121+ ar_text_id NUMBER,
 122+ ar_deleted NUMBER DEFAULT '0' NOT NULL
120123 );
121 -CREATE INDEX archive_name_title_timestamp ON archive (ar_namespace,ar_title,ar_timestamp);
 124+CREATE INDEX &mw_prefix.archive_i01 ON &mw_prefix.archive (ar_namespace,ar_title,ar_timestamp);
 125+CREATE INDEX &mw_prefix.archive_i02 ON &mw_prefix.archive (ar_user_text,ar_timestamp);
122126
123 -CREATE TABLE redirect (
124 - rd_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
125 - rd_namespace SMALLINT NOT NULL,
126 - rd_title VARCHAR(255) NOT NULL
 127+
 128+CREATE TABLE &mw_prefix.pagelinks (
 129+ pl_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE,
 130+ pl_namespace NUMBER NOT NULL,
 131+ pl_title VARCHAR2(255) NOT NULL
127132 );
128 -CREATE INDEX redirect_ns_title ON redirect (rd_namespace,rd_title,rd_from);
 133+CREATE UNIQUE INDEX &mw_prefix.pagelinks_u01 ON &mw_prefix.pagelinks (pl_from,pl_namespace,pl_title);
 134+CREATE UNIQUE INDEX &mw_prefix.pagelinks_u02 ON &mw_prefix.pagelinks (pl_namespace,pl_title,pl_from);
129135
130 -
131 -CREATE TABLE pagelinks (
132 - pl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
133 - pl_namespace SMALLINT NOT NULL,
134 - pl_title VARCHAR(255) NOT NULL
 136+CREATE TABLE &mw_prefix.templatelinks (
 137+ tl_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE,
 138+ tl_namespace NUMBER NOT NULL,
 139+ tl_title VARCHAR2(255) NOT NULL
135140 );
136 -CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title);
 141+CREATE UNIQUE INDEX &mw_prefix.templatelinks_u01 ON &mw_prefix.templatelinks (tl_from,tl_namespace,tl_title);
 142+CREATE UNIQUE INDEX &mw_prefix.templatelinks_u02 ON &mw_prefix.templatelinks (tl_namespace,tl_title,tl_from);
137143
138 -CREATE TABLE templatelinks (
139 - tl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
140 - tl_namespace INTEGER NOT NULL,
141 - tl_title VARCHAR(255) NOT NULL
 144+CREATE TABLE &mw_prefix.imagelinks (
 145+ il_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE,
 146+ il_to VARCHAR2(255) NOT NULL
142147 );
143 -CREATE UNIQUE INDEX templatelinks_unique ON templatelinks (tl_namespace,tl_title,tl_from);
 148+CREATE UNIQUE INDEX &mw_prefix.imagelinks_u01 ON &mw_prefix.imagelinks (il_from,il_to);
 149+CREATE UNIQUE INDEX &mw_prefix.imagelinks_u02 ON &mw_prefix.imagelinks (il_to,il_from);
144150
145 -CREATE TABLE imagelinks (
146 - il_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
147 - il_to VARCHAR(255) NOT NULL
 151+
 152+CREATE TABLE &mw_prefix.categorylinks (
 153+ cl_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE,
 154+ cl_to VARCHAR2(255) NOT NULL,
 155+ cl_sortkey VARCHAR2(255),
 156+ cl_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL
148157 );
149 -CREATE UNIQUE INDEX il_from ON imagelinks (il_to,il_from);
 158+CREATE UNIQUE INDEX &mw_prefix.categorylinks_u01 ON &mw_prefix.categorylinks (cl_from,cl_to);
 159+CREATE INDEX &mw_prefix.categorylinks_i01 ON &mw_prefix.categorylinks (cl_to,cl_sortkey,cl_from);
 160+CREATE INDEX &mw_prefix.categorylinks_i02 ON &mw_prefix.categorylinks (cl_to,cl_timestamp);
150161
151 -CREATE TABLE categorylinks (
152 - cl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
153 - cl_to VARCHAR(255) NOT NULL,
154 - cl_sortkey VARCHAR(86),
155 - cl_timestamp TIMESTAMP WITH TIME ZONE NOT NULL
 162+CREATE SEQUENCE category_cat_id_val;
 163+CREATE TABLE &mw_prefix.category (
 164+ cat_id NUMBER NOT NULL,
 165+ cat_title VARCHAR2(255) NOT NULL,
 166+ cat_pages NUMBER DEFAULT 0 NOT NULL,
 167+ cat_subcats NUMBER DEFAULT 0 NOT NULL,
 168+ cat_files NUMBER DEFAULT 0 NOT NULL,
 169+ cat_hidden NUMBER DEFAULT 0 NOT NULL
156170 );
157 -CREATE UNIQUE INDEX cl_from ON categorylinks (cl_from, cl_to);
158 -CREATE INDEX cl_sortkey ON categorylinks (cl_to, cl_sortkey);
 171+ALTER TABLE &mw_prefix.category ADD CONSTRAINT &mw_prefix.category_pk PRIMARY KEY (cat_id);
 172+CREATE UNIQUE INDEX &mw_prefix.category_u01 ON &mw_prefix.category (cat_title);
 173+CREATE INDEX &mw_prefix.category_i01 ON &mw_prefix.category (cat_pages);
159174
160 -CREATE TABLE externallinks (
161 - el_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
162 - el_to VARCHAR(2048) NOT NULL,
163 - el_index CLOB NOT NULL
 175+CREATE TABLE &mw_prefix.externallinks (
 176+ el_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE,
 177+ el_to VARCHAR2(2048) NOT NULL,
 178+ el_index VARCHAR2(2048) NOT NULL
164179 );
 180+CREATE INDEX &mw_prefix.externallinks_i01 ON &mw_prefix.externallinks (el_from, el_to);
 181+CREATE INDEX &mw_prefix.externallinks_i02 ON &mw_prefix.externallinks (el_to, el_from);
 182+CREATE INDEX &mw_prefix.externallinks_i03 ON &mw_prefix.externallinks (el_index);
165183
166 -CREATE TABLE langlinks (
167 - ll_from INTEGER NOT NULL REFERENCES page (page_id) ON DELETE CASCADE,
168 - ll_lang VARCHAR(10),
169 - ll_title VARCHAR(255)
 184+CREATE TABLE &mw_prefix.langlinks (
 185+ ll_from NUMBER NOT NULL REFERENCES &mw_prefix.page (page_id) ON DELETE CASCADE,
 186+ ll_lang VARCHAR2(20),
 187+ ll_title VARCHAR2(255)
170188 );
171 -CREATE UNIQUE INDEX langlinks_unique ON langlinks (ll_from,ll_lang);
172 -CREATE INDEX langlinks_lang_title ON langlinks (ll_lang,ll_title);
 189+CREATE UNIQUE INDEX &mw_prefix.langlinks_u01 ON &mw_prefix.langlinks (ll_from, ll_lang);
 190+CREATE INDEX &mw_prefix.langlinks_i01 ON &mw_prefix.langlinks (ll_lang, ll_title);
173191
174 -
175 -CREATE TABLE site_stats (
176 - ss_row_id INTEGER NOT NULL UNIQUE,
177 - ss_total_views INTEGER DEFAULT 0,
178 - ss_total_edits INTEGER DEFAULT 0,
179 - ss_good_articles INTEGER DEFAULT 0,
180 - ss_total_pages INTEGER DEFAULT -1,
181 - ss_users INTEGER DEFAULT -1,
182 - ss_admins INTEGER DEFAULT -1,
183 - ss_images INTEGER DEFAULT 0
 192+CREATE TABLE &mw_prefix.site_stats (
 193+ ss_row_id NUMBER NOT NULL ,
 194+ ss_total_views NUMBER DEFAULT 0,
 195+ ss_total_edits NUMBER DEFAULT 0,
 196+ ss_good_articles NUMBER DEFAULT 0,
 197+ ss_total_pages NUMBER DEFAULT -1,
 198+ ss_users NUMBER DEFAULT -1,
 199+ ss_active_users NUMBER DEFAULT -1,
 200+ ss_admins NUMBER DEFAULT -1,
 201+ ss_images NUMBER DEFAULT 0
184202 );
 203+CREATE UNIQUE INDEX &mw_prefix.site_stats_u01 ON &mw_prefix.site_stats (ss_row_id);
185204
186 -CREATE TABLE hitcounter (
187 - hc_id INTEGER NOT NULL
 205+CREATE TABLE &mw_prefix.hitcounter (
 206+ hc_id NUMBER NOT NULL
188207 );
189208
190 -
191209 CREATE SEQUENCE ipblocks_ipb_id_val;
192 -CREATE TABLE ipblocks (
193 - ipb_id INTEGER NOT NULL PRIMARY KEY,
194 - ipb_address VARCHAR(255) NULL,
195 - ipb_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
196 - ipb_by INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
197 - ipb_reason VARCHAR(255) NOT NULL,
198 - ipb_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
199 - ipb_auto CHAR DEFAULT '0' NOT NULL,
200 - ipb_anon_only CHAR DEFAULT '0' NOT NULL,
201 - ipb_create_account CHAR DEFAULT '1' NOT NULL,
202 - ipb_enable_autoblock CHAR DEFAULT '1' NOT NULL,
203 - ipb_expiry TIMESTAMP WITH TIME ZONE NOT NULL,
204 - ipb_range_start CHAR(8),
205 - ipb_range_end CHAR(8),
206 - ipb_deleted INTEGER DEFAULT '0' NOT NULL
 210+CREATE TABLE &mw_prefix.ipblocks (
 211+ ipb_id NUMBER NOT NULL,
 212+ ipb_address VARCHAR2(255) NULL,
 213+ ipb_user NUMBER NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL,
 214+ ipb_by NUMBER NOT NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE,
 215+ ipb_by_text VARCHAR2(255) NOT NULL,
 216+ ipb_reason VARCHAR2(255) NOT NULL,
 217+ ipb_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 218+ ipb_auto CHAR(1) DEFAULT '0' NOT NULL,
 219+ ipb_anon_only CHAR(1) DEFAULT '0' NOT NULL,
 220+ ipb_create_account CHAR(1) DEFAULT '1' NOT NULL,
 221+ ipb_enable_autoblock CHAR(1) DEFAULT '1' NOT NULL,
 222+ ipb_expiry TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 223+ ipb_range_start VARCHAR2(255),
 224+ ipb_range_end VARCHAR2(255),
 225+ ipb_deleted CHAR(1) DEFAULT '0' NOT NULL,
 226+ ipb_block_email CHAR(1) DEFAULT '0' NOT NULL,
 227+ ipb_allow_usertalk CHAR(1) DEFAULT '0' NOT NULL
207228 );
208 -CREATE INDEX ipb_address ON ipblocks (ipb_address);
209 -CREATE INDEX ipb_user ON ipblocks (ipb_user);
210 -CREATE INDEX ipb_range ON ipblocks (ipb_range_start,ipb_range_end);
 229+ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_pk PRIMARY KEY (ipb_id);
 230+CREATE UNIQUE INDEX &mw_prefix.ipblocks_u01 ON &mw_prefix.ipblocks (ipb_address, ipb_user, ipb_auto, ipb_anon_only);
 231+CREATE INDEX &mw_prefix.ipblocks_i01 ON &mw_prefix.ipblocks (ipb_user);
 232+CREATE INDEX &mw_prefix.ipblocks_i02 ON &mw_prefix.ipblocks (ipb_range_start, ipb_range_end);
 233+CREATE INDEX &mw_prefix.ipblocks_i03 ON &mw_prefix.ipblocks (ipb_timestamp);
 234+CREATE INDEX &mw_prefix.ipblocks_i04 ON &mw_prefix.ipblocks (ipb_expiry);
211235
212 -
213236 CREATE TABLE image (
214 - img_name VARCHAR(255) NOT NULL PRIMARY KEY,
215 - img_size INTEGER NOT NULL,
216 - img_width INTEGER NOT NULL,
217 - img_height INTEGER NOT NULL,
 237+ img_name VARCHAR2(255) NOT NULL,
 238+ img_size NUMBER NOT NULL,
 239+ img_width NUMBER NOT NULL,
 240+ img_height NUMBER NOT NULL,
218241 img_metadata CLOB,
219 - img_bits SMALLINT,
220 - img_media_type CLOB,
221 - img_major_mime CLOB DEFAULT 'unknown',
222 - img_minor_mime CLOB DEFAULT 'unknown',
223 - img_description CLOB,
224 - img_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
225 - img_user_text CLOB NOT NULL,
226 - img_timestamp TIMESTAMP WITH TIME ZONE
 242+ img_bits NUMBER,
 243+ img_media_type VARCHAR2(32),
 244+ img_major_mime VARCHAR2(32) DEFAULT 'unknown',
 245+ img_minor_mime VARCHAR2(32) DEFAULT 'unknown',
 246+ img_description VARCHAR2(255),
 247+ img_user NUMBER NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL,
 248+ img_user_text VARCHAR2(255) NOT NULL,
 249+ img_timestamp TIMESTAMP(6) WITH TIME ZONE,
 250+ img_sha1 VARCHAR2(32)
227251 );
228 -CREATE INDEX img_size_idx ON image (img_size);
229 -CREATE INDEX img_timestamp_idx ON image (img_timestamp);
 252+ALTER TABLE &mw_prefix.image ADD CONSTRAINT &mw_prefix.image_pk PRIMARY KEY (img_name);
 253+CREATE INDEX &mw_prefix.image_i01 ON &mw_prefix.image (img_user_text,img_timestamp);
 254+CREATE INDEX &mw_prefix.image_i02 ON &mw_prefix.image (img_size);
 255+CREATE INDEX &mw_prefix.image_i03 ON &mw_prefix.image (img_timestamp);
 256+CREATE INDEX &mw_prefix.image_i04 ON &mw_prefix.image (img_sha1);
230257
231 -CREATE TABLE oldimage (
232 - oi_name VARCHAR(255) NOT NULL REFERENCES image(img_name),
233 - oi_archive_name VARCHAR(255),
234 - oi_size INTEGER NOT NULL,
235 - oi_width INTEGER NOT NULL,
236 - oi_height INTEGER NOT NULL,
237 - oi_bits SMALLINT NOT NULL,
238 - oi_description CLOB,
239 - oi_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
240 - oi_user_text CLOB NOT NULL,
241 - oi_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
242 - oi_metadata CLOB,
243 - oi_media_type VARCHAR(10) DEFAULT NULL,
244 - oi_major_mime VARCHAR(11) DEFAULT 'unknown',
245 - oi_minor_mime VARCHAR(32) DEFAULT 'unknown',
246 - oi_deleted INTEGER DEFAULT 0 NOT NULL
 258+
 259+CREATE TABLE &mw_prefix.oldimage (
 260+ oi_name VARCHAR2(255) NOT NULL REFERENCES &mw_prefix.image(img_name),
 261+ oi_archive_name VARCHAR2(255),
 262+ oi_size NUMBER NOT NULL,
 263+ oi_width NUMBER NOT NULL,
 264+ oi_height NUMBER NOT NULL,
 265+ oi_bits NUMBER NOT NULL,
 266+ oi_description VARCHAR2(255),
 267+ oi_user NUMBER NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL,
 268+ oi_user_text VARCHAR2(255) NOT NULL,
 269+ oi_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 270+ oi_metadata CLOB,
 271+ oi_media_type VARCHAR2(32) DEFAULT NULL,
 272+ oi_major_mime VARCHAR2(32) DEFAULT 'unknown',
 273+ oi_minor_mime VARCHAR2(32) DEFAULT 'unknown',
 274+ oi_deleted NUMBER DEFAULT 0 NOT NULL,
 275+ oi_sha1 VARCHAR2(32)
247276 );
248 -CREATE INDEX oi_name_timestamp ON oldimage (oi_name,oi_timestamp);
249 -CREATE INDEX oi_name_archive_name ON oldimage (oi_name,oi_archive_name);
 277+CREATE INDEX &mw_prefix.oldimage_i01 ON &mw_prefix.oldimage (oi_user_text,oi_timestamp);
 278+CREATE INDEX &mw_prefix.oldimage_i02 ON &mw_prefix.oldimage (oi_name,oi_timestamp);
 279+CREATE INDEX &mw_prefix.oldimage_i03 ON &mw_prefix.oldimage (oi_name,oi_archive_name);
 280+CREATE INDEX &mw_prefix.oldimage_i04 ON &mw_prefix.oldimage (oi_sha1);
250281
 282+
251283 CREATE SEQUENCE filearchive_fa_id_seq;
252 -CREATE TABLE filearchive (
253 - fa_id INTEGER NOT NULL PRIMARY KEY,
254 - fa_name VARCHAR(255) NOT NULL,
255 - fa_archive_name VARCHAR(255),
256 - fa_storage_group VARCHAR(16),
257 - fa_storage_key CHAR(64),
258 - fa_deleted_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
259 - fa_deleted_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
 284+CREATE TABLE &mw_prefix.filearchive (
 285+ fa_id NUMBER NOT NULL,
 286+ fa_name VARCHAR2(255) NOT NULL,
 287+ fa_archive_name VARCHAR2(255),
 288+ fa_storage_group VARCHAR2(16),
 289+ fa_storage_key VARCHAR2(64),
 290+ fa_deleted_user NUMBER NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL,
 291+ fa_deleted_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
260292 fa_deleted_reason CLOB,
261 - fa_size SMALLINT NOT NULL,
262 - fa_width SMALLINT NOT NULL,
263 - fa_height SMALLINT NOT NULL,
 293+ fa_size NUMBER NOT NULL,
 294+ fa_width NUMBER NOT NULL,
 295+ fa_height NUMBER NOT NULL,
264296 fa_metadata CLOB,
265 - fa_bits SMALLINT,
266 - fa_media_type CLOB,
267 - fa_major_mime CLOB DEFAULT 'unknown',
268 - fa_minor_mime CLOB DEFAULT 'unknown',
269 - fa_description CLOB NOT NULL,
270 - fa_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
271 - fa_user_text CLOB NOT NULL,
272 - fa_timestamp TIMESTAMP WITH TIME ZONE,
273 - fa_deleted INTEGER DEFAULT '0' NOT NULL
 297+ fa_bits NUMBER,
 298+ fa_media_type VARCHAR2(32) DEFAULT NULL,
 299+ fa_major_mime VARCHAR2(32) DEFAULT 'unknown',
 300+ fa_minor_mime VARCHAR2(32) DEFAULT 'unknown',
 301+ fa_description VARCHAR2(255) NOT NULL,
 302+ fa_user NUMBER NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL,
 303+ fa_user_text VARCHAR2(255) NOT NULL,
 304+ fa_timestamp TIMESTAMP(6) WITH TIME ZONE,
 305+ fa_deleted NUMBER DEFAULT '0' NOT NULL
274306 );
275 -CREATE INDEX fa_name_time ON filearchive (fa_name, fa_timestamp);
276 -CREATE INDEX fa_dupe ON filearchive (fa_storage_group, fa_storage_key);
277 -CREATE INDEX fa_notime ON filearchive (fa_deleted_timestamp);
278 -CREATE INDEX fa_nouser ON filearchive (fa_deleted_user);
 307+ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_pk PRIMARY KEY (fa_id);
 308+CREATE INDEX &mw_prefix.filearchive_i01 ON &mw_prefix.filearchive (fa_name, fa_timestamp);
 309+CREATE INDEX &mw_prefix.filearchive_i02 ON &mw_prefix.filearchive (fa_storage_group, fa_storage_key);
 310+CREATE INDEX &mw_prefix.filearchive_i03 ON &mw_prefix.filearchive (fa_deleted_timestamp);
 311+CREATE INDEX &mw_prefix.filearchive_i04 ON &mw_prefix.filearchive (fa_user_text,fa_timestamp);
279312
280 -
281313 CREATE SEQUENCE rc_rc_id_seq;
282 -CREATE TABLE recentchanges (
283 - rc_id INTEGER NOT NULL PRIMARY KEY,
284 - rc_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
285 - rc_cur_time TIMESTAMP WITH TIME ZONE NOT NULL,
286 - rc_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
287 - rc_user_text CLOB NOT NULL,
288 - rc_namespace SMALLINT NOT NULL,
289 - rc_title VARCHAR(255) NOT NULL,
290 - rc_comment VARCHAR(255),
291 - rc_minor CHAR DEFAULT '0' NOT NULL,
292 - rc_bot CHAR DEFAULT '0' NOT NULL,
293 - rc_new CHAR DEFAULT '0' NOT NULL,
294 - rc_cur_id INTEGER NULL REFERENCES page(page_id) ON DELETE SET NULL,
295 - rc_this_oldid INTEGER NOT NULL,
296 - rc_last_oldid INTEGER NOT NULL,
297 - rc_type CHAR DEFAULT '0' NOT NULL,
298 - rc_moved_to_ns SMALLINT,
299 - rc_moved_to_title CLOB,
300 - rc_patrolled CHAR DEFAULT '0' NOT NULL,
301 - rc_ip VARCHAR(15),
302 - rc_old_len INTEGER,
303 - rc_new_len INTEGER,
304 - rc_deleted INTEGER DEFAULT '0' NOT NULL,
305 - rc_logid INTEGER DEFAULT '0' NOT NULL,
306 - rc_log_type CLOB,
307 - rc_log_action CLOB,
308 - rc_params CLOB
 314+CREATE TABLE &mw_prefix.recentchanges (
 315+ rc_id NUMBER NOT NULL,
 316+ rc_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 317+ rc_cur_time TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 318+ rc_user NUMBER NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL,
 319+ rc_user_text VARCHAR2(255) NOT NULL,
 320+ rc_namespace NUMBER NOT NULL,
 321+ rc_title VARCHAR2(255) NOT NULL,
 322+ rc_comment VARCHAR2(255),
 323+ rc_minor CHAR(1) DEFAULT '0' NOT NULL,
 324+ rc_bot CHAR(1) DEFAULT '0' NOT NULL,
 325+ rc_new CHAR(1) DEFAULT '0' NOT NULL,
 326+ rc_cur_id NUMBER NULL REFERENCES &mw_prefix.page(page_id) ON DELETE SET NULL,
 327+ rc_this_oldid NUMBER NOT NULL,
 328+ rc_last_oldid NUMBER NOT NULL,
 329+ rc_type CHAR(1) DEFAULT '0' NOT NULL,
 330+ rc_moved_to_ns NUMBER,
 331+ rc_moved_to_title VARCHAR2(255),
 332+ rc_patrolled CHAR(1) DEFAULT '0' NOT NULL,
 333+ rc_ip VARCHAR2(15),
 334+ rc_old_len NUMBER,
 335+ rc_new_len NUMBER,
 336+ rc_deleted NUMBER DEFAULT '0' NOT NULL,
 337+ rc_logid NUMBER DEFAULT '0' NOT NULL,
 338+ rc_log_type VARCHAR2(255),
 339+ rc_log_action VARCHAR2(255),
 340+ rc_params CLOB
309341 );
310 -CREATE INDEX rc_timestamp ON recentchanges (rc_timestamp);
311 -CREATE INDEX rc_namespace_title ON recentchanges (rc_namespace, rc_title);
312 -CREATE INDEX rc_cur_id ON recentchanges (rc_cur_id);
313 -CREATE INDEX new_name_timestamp ON recentchanges (rc_new, rc_namespace, rc_timestamp);
314 -CREATE INDEX rc_ip ON recentchanges (rc_ip);
 342+ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_pk PRIMARY KEY (rc_id);
 343+CREATE INDEX &mw_prefix.recentchanges_i01 ON &mw_prefix.recentchanges (rc_timestamp);
 344+CREATE INDEX &mw_prefix.recentchanges_i02 ON &mw_prefix.recentchanges (rc_namespace, rc_title);
 345+CREATE INDEX &mw_prefix.recentchanges_i03 ON &mw_prefix.recentchanges (rc_cur_id);
 346+CREATE INDEX &mw_prefix.recentchanges_i04 ON &mw_prefix.recentchanges (rc_new,rc_namespace,rc_timestamp);
 347+CREATE INDEX &mw_prefix.recentchanges_i05 ON &mw_prefix.recentchanges (rc_ip);
 348+CREATE INDEX &mw_prefix.recentchanges_i06 ON &mw_prefix.recentchanges (rc_namespace, rc_user_text);
 349+CREATE INDEX &mw_prefix.recentchanges_i07 ON &mw_prefix.recentchanges (rc_user_text, rc_timestamp);
315350
316 -
317 -CREATE TABLE watchlist (
318 - wl_user INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
319 - wl_namespace SMALLINT DEFAULT 0 NOT NULL,
320 - wl_title VARCHAR(255) NOT NULL,
321 - wl_notificationtimestamp TIMESTAMP WITH TIME ZONE
 351+CREATE TABLE &mw_prefix.watchlist (
 352+ wl_user NUMBER NOT NULL REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE,
 353+ wl_namespace NUMBER DEFAULT 0 NOT NULL,
 354+ wl_title VARCHAR2(255) NOT NULL,
 355+ wl_notificationtimestamp TIMESTAMP(6) WITH TIME ZONE
322356 );
323 -CREATE UNIQUE INDEX wl_user_namespace_title ON watchlist (wl_namespace, wl_title, wl_user);
 357+CREATE UNIQUE INDEX &mw_prefix.watchlist_u01 ON &mw_prefix.watchlist (wl_user, wl_namespace, wl_title);
 358+CREATE INDEX &mw_prefix.watchlist_i01 ON &mw_prefix.watchlist (wl_namespace, wl_title);
324359
325360
326 -CREATE TABLE math (
327 - math_inputhash VARCHAR(16) NOT NULL UNIQUE,
328 - math_outputhash VARCHAR(16) NOT NULL,
329 - math_html_conservativeness SMALLINT NOT NULL,
 361+CREATE TABLE &mw_prefix.math (
 362+ math_inputhash VARCHAR2(16) NOT NULL,
 363+ math_outputhash VARCHAR2(16) NOT NULL,
 364+ math_html_conservativeness NUMBER NOT NULL,
330365 math_html CLOB,
331366 math_mathml CLOB
332367 );
 368+CREATE UNIQUE INDEX &mw_prefix.math_u01 ON &mw_prefix.math (math_inputhash);
333369
334 -
335 -CREATE TABLE interwiki (
336 - iw_prefix VARCHAR(32) NOT NULL UNIQUE,
337 - iw_url VARCHAR(127) NOT NULL,
338 - iw_local CHAR NOT NULL,
339 - iw_trans CHAR DEFAULT '0' NOT NULL
 370+CREATE TABLE &mw_prefix.searchindex (
 371+ si_page NUMBER NOT NULL,
 372+ si_title VARCHAR2(255) DEFAULT '' NOT NULL,
 373+ si_text CLOB NOT NULL
340374 );
 375+CREATE UNIQUE INDEX &mw_prefix.searchindex_u01 ON &mw_prefix.searchindex (si_page);
341376
342 -CREATE TABLE querycache (
343 - qc_type CHAR(32) NOT NULL,
344 - qc_value SMALLINT NOT NULL,
345 - qc_namespace SMALLINT NOT NULL,
346 - qc_title CHAR(255) NOT NULL
 377+CREATE TABLE &mw_prefix.interwiki (
 378+ iw_prefix VARCHAR2(32) NOT NULL,
 379+ iw_url VARCHAR2(127) NOT NULL,
 380+ iw_local CHAR(1) NOT NULL,
 381+ iw_trans CHAR(1) DEFAULT '0' NOT NULL
347382 );
348 -CREATE INDEX querycache_type_value ON querycache (qc_type, qc_value);
 383+CREATE UNIQUE INDEX &mw_prefix.interwiki_u01 ON &mw_prefix.interwiki (iw_prefix);
349384
350 -CREATE TABLE querycache_info (
351 - qci_type VARCHAR(32) UNIQUE,
352 - qci_timestamp TIMESTAMP WITH TIME ZONE NULL
 385+CREATE TABLE &mw_prefix.querycache (
 386+ qc_type VARCHAR2(32) NOT NULL,
 387+ qc_value NUMBER NOT NULL,
 388+ qc_namespace NUMBER NOT NULL,
 389+ qc_title VARCHAR2(255) NOT NULL
353390 );
 391+CREATE INDEX &mw_prefix.querycache_u01 ON &mw_prefix.querycache (qc_type,qc_value);
354392
355 -CREATE TABLE querycachetwo (
356 - qcc_type CHAR(32) NOT NULL,
357 - qcc_value SMALLINT DEFAULT 0 NOT NULL,
358 - qcc_namespace INTEGER DEFAULT 0 NOT NULL,
359 - qcc_title CHAR(255) DEFAULT '' NOT NULL,
360 - qcc_namespacetwo INTEGER DEFAULT 0 NOT NULL,
361 - qcc_titletwo CHAR(255) DEFAULT '' NOT NULL
362 -);
363 -CREATE INDEX querycachetwo_type_value ON querycachetwo (qcc_type, qcc_value);
364 -CREATE INDEX querycachetwo_title ON querycachetwo (qcc_type,qcc_namespace,qcc_title);
365 -CREATE INDEX querycachetwo_titletwo ON querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo);
366 -
367 -
368 -CREATE TABLE objectcache (
369 - keyname CHAR(255) UNIQUE,
 393+CREATE TABLE &mw_prefix.objectcache (
 394+ keyname VARCHAR2(255) ,
370395 value BLOB,
371 - exptime TIMESTAMP WITH TIME ZONE NOT NULL
 396+ exptime TIMESTAMP(6) WITH TIME ZONE NOT NULL
372397 );
373 -CREATE INDEX objectcacache_exptime ON objectcache (exptime);
 398+CREATE INDEX &mw_prefix.objectcache_i01 ON &mw_prefix.objectcache (exptime);
374399
375 -CREATE TABLE transcache (
376 - tc_url VARCHAR(255) NOT NULL UNIQUE,
 400+CREATE TABLE &mw_prefix.transcache (
 401+ tc_url VARCHAR2(255) NOT NULL,
377402 tc_contents CLOB NOT NULL,
378 - tc_time TIMESTAMP WITH TIME ZONE NOT NULL
 403+ tc_time TIMESTAMP(6) WITH TIME ZONE NOT NULL
379404 );
 405+CREATE UNIQUE INDEX &mw_prefix.transcache_u01 ON &mw_prefix.transcache (tc_url);
380406
381407
382408 CREATE SEQUENCE log_log_id_seq;
383 -CREATE TABLE logging (
384 - log_type VARCHAR(10) NOT NULL,
385 - log_action VARCHAR(10) NOT NULL,
386 - log_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
387 - log_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
388 - log_namespace SMALLINT NOT NULL,
389 - log_title VARCHAR(255) NOT NULL,
390 - log_comment VARCHAR(255),
 409+CREATE TABLE &mw_prefix.logging (
 410+ log_id NUMBER NOT NULL,
 411+ log_type VARCHAR2(10) NOT NULL,
 412+ log_action VARCHAR2(10) NOT NULL,
 413+ log_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 414+ log_user NUMBER REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL,
 415+ log_namespace NUMBER NOT NULL,
 416+ log_title VARCHAR2(255) NOT NULL,
 417+ log_comment VARCHAR2(255),
391418 log_params CLOB,
392 - log_deleted INTEGER DEFAULT '0' NOT NULL,
393 - log_id INTEGER NOT NULL PRIMARY KEY
 419+ log_deleted NUMBER DEFAULT '0' NOT NULL
394420 );
395 -CREATE INDEX logging_type_name ON logging (log_type, log_timestamp);
396 -CREATE INDEX logging_user_time ON logging (log_timestamp, log_user);
397 -CREATE INDEX logging_page_time ON logging (log_namespace, log_title, log_timestamp);
 421+ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_pk PRIMARY KEY (log_id);
 422+CREATE INDEX &mw_prefix.logging_i01 ON &mw_prefix.logging (log_type, log_timestamp);
 423+CREATE INDEX &mw_prefix.logging_i02 ON &mw_prefix.logging (log_user, log_timestamp);
 424+CREATE INDEX &mw_prefix.logging_i03 ON &mw_prefix.logging (log_namespace, log_title, log_timestamp);
 425+CREATE INDEX &mw_prefix.logging_i04 ON &mw_prefix.logging (log_timestamp);
398426
 427+CREATE TABLE &mw_prefix.log_search (
 428+ ls_field VARCHAR2(32) NOT NULL,
 429+ ls_value VARCHAR2(255) NOT NULL,
 430+ ls_log_id NuMBER DEFAULT 0 NOT NULL
 431+);
 432+ALTER TABLE log_search ADD CONSTRAINT log_search_pk PRIMARY KEY (ls_field,ls_value,ls_log_id);
 433+CREATE INDEX &mw_prefix.log_search_i01 ON &mw_prefix.log_search (ls_log_id);
 434+
399435 CREATE SEQUENCE trackbacks_tb_id_seq;
400 -CREATE TABLE trackbacks (
401 - tb_id INTEGER NOT NULL PRIMARY KEY,
402 - tb_page INTEGER REFERENCES page(page_id) ON DELETE CASCADE,
403 - tb_title VARCHAR(255) NOT NULL,
404 - tb_url VARCHAR(255) NOT NULL,
 436+CREATE TABLE &mw_prefix.trackbacks (
 437+ tb_id NUMBER NOT NULL,
 438+ tb_page NUMBER REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE,
 439+ tb_title VARCHAR2(255) NOT NULL,
 440+ tb_url VARCHAR2(255) NOT NULL,
405441 tb_ex CLOB,
406 - tb_name VARCHAR(255)
 442+ tb_name VARCHAR2(255)
407443 );
408 -CREATE INDEX trackback_page ON trackbacks (tb_page);
 444+ALTER TABLE &mw_prefix.trackbacks ADD CONSTRAINT &mw_prefix.trackbacks_pk PRIMARY KEY (tb_id);
 445+CREATE INDEX &mw_prefix.trackbacks_i01 ON &mw_prefix.trackbacks (tb_page);
409446
410447 CREATE SEQUENCE job_job_id_seq;
411 -CREATE TABLE job (
412 - job_id INTEGER NOT NULL PRIMARY KEY,
413 - job_cmd VARCHAR(255) NOT NULL,
414 - job_namespace SMALLINT NOT NULL,
415 - job_title VARCHAR(255) NOT NULL,
 448+CREATE TABLE &mw_prefix.job (
 449+ job_id NUMBER NOT NULL,
 450+ job_cmd VARCHAR2(60) NOT NULL,
 451+ job_namespace NUMBER NOT NULL,
 452+ job_title VARCHAR2(255) NOT NULL,
416453 job_params CLOB NOT NULL
417454 );
418 -CREATE INDEX job_cmd_namespace_title ON job (job_cmd, job_namespace, job_title);
 455+ALTER TABLE &mw_prefix.job ADD CONSTRAINT &mw_prefix.job_pk PRIMARY KEY (job_id);
 456+CREATE INDEX &mw_prefix.job_i01 ON &mw_prefix.job (job_cmd, job_namespace, job_title);
419457
 458+CREATE TABLE &mw_prefix.querycache_info (
 459+ qci_type VARCHAR2(32) NOT NULL,
 460+ qci_timestamp TIMESTAMP(6) WITH TIME ZONE NULL
 461+);
 462+CREATE UNIQUE INDEX &mw_prefix.querycache_info_u01 ON &mw_prefix.querycache_info (qci_type);
 463+
 464+CREATE TABLE &mw_prefix.redirect (
 465+ rd_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE,
 466+ rd_namespace NUMBER NOT NULL,
 467+ rd_title VARCHAR2(255) NOT NULL
 468+);
 469+CREATE INDEX &mw_prefix.redirect_i01 ON &mw_prefix.redirect (rd_namespace,rd_title,rd_from);
 470+
 471+CREATE TABLE &mw_prefix.querycachetwo (
 472+ qcc_type VARCHAR2(32) NOT NULL,
 473+ qcc_value NUMBER DEFAULT 0 NOT NULL,
 474+ qcc_namespace NUMBER DEFAULT 0 NOT NULL,
 475+ qcc_title VARCHAR2(255) DEFAULT '' NOT NULL,
 476+ qcc_namespacetwo NUMBER DEFAULT 0 NOT NULL,
 477+ qcc_titletwo VARCHAR2(255) DEFAULT '' NOT NULL
 478+);
 479+CREATE INDEX &mw_prefix.querycachetwo_i01 ON &mw_prefix.querycachetwo (qcc_type,qcc_value);
 480+CREATE INDEX &mw_prefix.querycachetwo_i02 ON &mw_prefix.querycachetwo (qcc_type,qcc_namespace,qcc_title);
 481+CREATE INDEX &mw_prefix.querycachetwo_i03 ON &mw_prefix.querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo);
 482+
 483+CREATE SEQUENCE pr_id_val;
 484+CREATE TABLE &mw_prefix.page_restrictions (
 485+ pr_id NUMBER NOT NULL,
 486+ pr_page NUMBER NULL REFERENCES &mw_prefix.page (page_id) ON DELETE CASCADE,
 487+ pr_type VARCHAR2(255) NOT NULL,
 488+ pr_level VARCHAR2(255) NOT NULL,
 489+ pr_cascade NUMBER NOT NULL,
 490+ pr_user NUMBER NULL,
 491+ pr_expiry TIMESTAMP(6) WITH TIME ZONE NULL
 492+);
 493+ALTER TABLE &mw_prefix.page_restrictions ADD CONSTRAINT &mw_prefix.page_restrictions_pk PRIMARY KEY (pr_page,pr_type);
 494+CREATE INDEX &mw_prefix.page_restrictions_i01 ON &mw_prefix.page_restrictions (pr_type,pr_level);
 495+CREATE INDEX &mw_prefix.page_restrictions_i02 ON &mw_prefix.page_restrictions (pr_level);
 496+CREATE INDEX &mw_prefix.page_restrictions_i03 ON &mw_prefix.page_restrictions (pr_cascade);
 497+
 498+CREATE TABLE &mw_prefix.protected_titles (
 499+ pt_namespace NUMBER NOT NULL,
 500+ pt_title VARCHAR2(255) NOT NULL,
 501+ pt_user NUMBER NOT NULL,
 502+ pt_reason VARCHAR2(255),
 503+ pt_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
 504+ pt_expiry VARCHAR2(14) NOT NULL,
 505+ pt_create_perm VARCHAR2(60) NOT NULL
 506+);
 507+CREATE UNIQUE INDEX &mw_prefix.protected_titles_u01 ON &mw_prefix.protected_titles (pt_namespace,pt_title);
 508+CREATE INDEX &mw_prefix.protected_titles_i01 ON &mw_prefix.protected_titles (pt_timestamp);
 509+
 510+CREATE TABLE &mw_prefix.page_props (
 511+ pp_page NUMBER NOT NULL,
 512+ pp_propname VARCHAR2(60) NOT NULL,
 513+ pp_value BLOB NOT NULL
 514+);
 515+CREATE UNIQUE INDEX &mw_prefix.page_props_u01 ON &mw_prefix.page_props (pp_page,pp_propname);
 516+
 517+
 518+CREATE TABLE &mw_prefix.updatelog (
 519+ ul_key VARCHAR2(255) NOT NULL
 520+);
 521+ALTER TABLE &mw_prefix.updatelog ADD CONSTRAINT &mw_prefix.updatelog_pk PRIMARY KEY (ul_key);
 522+
 523+CREATE TABLE &mw_prefix.change_tag (
 524+ ct_rc_id NUMBER NULL,
 525+ ct_log_id NUMBER NULL,
 526+ ct_rev_id NUMBER NULL,
 527+ ct_tag VARCHAR2(255) NOT NULL,
 528+ ct_params BLOB NULL
 529+);
 530+CREATE UNIQUE INDEX &mw_prefix.change_tag_u01 ON &mw_prefix.change_tag (ct_rc_id,ct_tag);
 531+CREATE UNIQUE INDEX &mw_prefix.change_tag_u02 ON &mw_prefix.change_tag (ct_log_id,ct_tag);
 532+CREATE UNIQUE INDEX &mw_prefix.change_tag_u03 ON &mw_prefix.change_tag (ct_rev_id,ct_tag);
 533+CREATE INDEX &mw_prefix.change_tag_i01 ON &mw_prefix.change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
 534+
 535+CREATE TABLE &mw_prefix.tag_summary (
 536+ ts_rc_id NUMBER NULL,
 537+ ts_log_id NUMBER NULL,
 538+ ts_rev_id NUMBER NULL,
 539+ ts_tags BLOB NOT NULL
 540+);
 541+CREATE UNIQUE INDEX &mw_prefix.tag_summary_u01 ON &mw_prefix.tag_summary (ts_rc_id);
 542+CREATE UNIQUE INDEX &mw_prefix.tag_summary_u02 ON &mw_prefix.tag_summary (ts_log_id);
 543+CREATE UNIQUE INDEX &mw_prefix.tag_summary_u03 ON &mw_prefix.tag_summary (ts_rev_id);
 544+
 545+CREATE TABLE &mw_prefix.valid_tag (
 546+ vt_tag VARCHAR2(255) NOT NULL
 547+);
 548+ALTER TABLE &mw_prefix.valid_tag ADD CONSTRAINT &mw_prefix.valid_tag_pk PRIMARY KEY (vt_tag);
 549+
420550 -- This table is not used unless profiling is turned on
 551+--CREATE TABLE &mw_prefix.profiling (
 552+-- pf_count NUMBER DEFAULT 0 NOT NULL,
421553 -- pf_time NUMERIC(18,10) DEFAULT 0 NOT NULL,
422554 -- pf_name CLOB NOT NULL,
423555 -- pf_server CLOB NULL
424556 --);
 557+--CREATE UNIQUE INDEX &mw_prefix.profiling_u01 ON &mw_prefix.profiling (pf_name, pf_server);
425558
426 -CREATE TABLE searchindex (
427 - si_page INTEGER UNIQUE NOT NULL,
428 - si_title VARCHAR(255) DEFAULT '' NOT NULL,
429 - si_text CLOB NOT NULL
 559+CREATE INDEX si_title_idx ON &mw_prefix.searchindex(si_title) INDEXTYPE IS ctxsys.context;
 560+CREATE INDEX si_text_idx ON &mw_prefix.searchindex(si_text) INDEXTYPE IS ctxsys.context;
 561+
 562+CREATE TABLE &mw_prefix.wiki_field_info_full (
 563+table_name VARCHAR2(35) NOT NULL,
 564+column_name VARCHAR2(35) NOT NULL,
 565+data_default VARCHAR2(4000),
 566+data_length NUMBER NOT NULL,
 567+data_type VARCHAR2(106),
 568+not_null CHAR(1) NOT NULL,
 569+prim NUMBER(1),
 570+uniq NUMBER(1),
 571+nonuniq NUMBER(1)
430572 );
 573+ALTER TABLE &mw_prefix.wiki_field_info_full ADD CONSTRAINT &mw_prefix.wiki_field_info_full_pk PRIMARY KEY (table_name, column_name);
431574
 575+CREATE PROCEDURE &mw_prefix.fill_wiki_info IS
 576+ BEGIN
 577+ DELETE &mw_prefix.wiki_field_info_full;
432578
433 -CREATE INDEX si_title_idx ON searchindex(si_title) INDEXTYPE IS ctxsys.context;
434 -CREATE INDEX si_text_idx ON searchindex(si_text) INDEXTYPE IS ctxsys.context;
 579+ FOR x_rec IN (SELECT '&mw_prefix.' || t.table_name table_name, t.column_name,
 580+ t.data_default, t.data_length, t.data_type,
 581+ DECODE (t.nullable, 'Y', '1', 'N', '0') not_null,
 582+ (SELECT 1
 583+ FROM user_cons_columns ucc,
 584+ user_constraints uc
 585+ WHERE ucc.table_name = t.table_name
 586+ AND ucc.column_name = t.column_name
 587+ AND uc.constraint_name = ucc.constraint_name
 588+ AND uc.constraint_type = 'P'
 589+ AND ROWNUM < 2) prim,
 590+ (SELECT 1
 591+ FROM user_ind_columns uic,
 592+ user_indexes ui
 593+ WHERE uic.table_name = t.table_name
 594+ AND uic.column_name = t.column_name
 595+ AND ui.index_name = uic.index_name
 596+ AND ui.uniqueness = 'UNIQUE'
 597+ AND ROWNUM < 2) uniq,
 598+ (SELECT 1
 599+ FROM user_ind_columns uic,
 600+ user_indexes ui
 601+ WHERE uic.table_name = t.table_name
 602+ AND uic.column_name = t.column_name
 603+ AND ui.index_name = uic.index_name
 604+ AND ui.uniqueness = 'NONUNIQUE'
 605+ AND ROWNUM < 2) nonuniq
 606+ FROM user_tab_columns t, user_tables ut
 607+ WHERE ut.table_name = t.table_name)
 608+ LOOP
 609+ INSERT INTO &mw_prefix.wiki_field_info_full
 610+ (table_name, column_name,
 611+ data_default, data_length,
 612+ data_type, not_null, prim,
 613+ uniq, nonuniq
 614+ )
 615+ VALUES (x_rec.table_name, x_rec.column_name,
 616+ x_rec.data_default, x_rec.data_length,
 617+ x_rec.data_type, x_rec.not_null, x_rec.prim,
 618+ x_rec.uniq, x_rec.nonuniq
 619+ );
 620+ END LOOP;
 621+ COMMIT;
 622+END;
 623+
 624+BEGIN
 625+ &mw_prefix.fill_wiki_info;
 626+END;
 627+
 628+CREATE OR REPLACE FUNCTION BITOR (x IN NUMBER, y IN NUMBER) RETURN NUMBER AS
 629+BEGIN
 630+ RETURN (x + y - BITAND(x, y));
 631+END;
Index: trunk/phase3/maintenance/ora/user.sql
@@ -0,0 +1,13 @@
 2+define WIKI_USER=&1
 3+define WIKI_PASS=&2
 4+define DEF_TS=&3
 5+define TEMP_TS=&4
 6+create user &&wiki_user identified by &&wiki_pass default tablespace &&def_ts temporary tablespace &&temp_ts quota unlimited on &&def_ts;
 7+grant connect, resource to &&wiki_user;
 8+grant alter session to &&wiki_user;
 9+grant ctxapp to &&wiki_user;
 10+grant execute on ctx_ddl to &&wiki_user;
 11+grant create view to &&wiki_user;
 12+grant create synonym to &&wiki_user;
 13+grant create table to &&wiki_user;
 14+grant create sequence to &&wiki_user;
Index: trunk/phase3/includes/GlobalFunctions.php
@@ -1831,8 +1831,8 @@
18321832 } elseif (preg_match('/^\d{1,13}$/D',$ts)) {
18331833 # TS_UNIX
18341834 $uts = $ts;
1835 - } elseif (preg_match('/^\d{1,2}-...-\d\d(?:\d\d)? \d\d\.\d\d\.\d\d/', $ts)) {
1836 - # TS_ORACLE
 1835+ } elseif (preg_match('/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts)) {
 1836+ # TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
18371837 $uts = strtotime(preg_replace('/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
18381838 str_replace("+00:00", "UTC", $ts)));
18391839 } elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z$/', $ts, $da)) {
@@ -1869,7 +1869,8 @@
18701870 case TS_RFC2822:
18711871 return gmdate( 'D, d M Y H:i:s', $uts ) . ' GMT';
18721872 case TS_ORACLE:
1873 - return gmdate( 'd-M-y h.i.s A', $uts) . ' +00:00';
 1873+ return gmdate( 'd-m-Y H:i:s.000000', $uts);
 1874+ //return gmdate( 'd-M-y h.i.s A', $uts) . ' +00:00';
18741875 case TS_POSTGRES:
18751876 return gmdate( 'Y-m-d H:i:s', $uts) . ' GMT';
18761877 case TS_DB2:
Index: trunk/phase3/includes/db/DatabaseOracle.php
@@ -31,40 +31,46 @@
3232 private $cursor;
3333 private $stmt;
3434 private $nrows;
35 - private $db;
3635
37 - function __construct(&$db, $stmt) {
 36+ private $unique;
 37+
 38+ function __construct(&$db, $stmt, $unique = false) {
3839 $this->db =& $db;
 40+
3941 if (($this->nrows = oci_fetch_all($stmt, $this->rows, 0, -1, OCI_FETCHSTATEMENT_BY_ROW | OCI_NUM)) === false) {
4042 $e = oci_error($stmt);
4143 $db->reportQueryError($e['message'], $e['code'], '', __FUNCTION__);
4244 return;
4345 }
4446
 47+ if ($unique) {
 48+ $this->rows = array_unique($this->rows);
 49+ $this->nrows = count($this->rows);
 50+ }
 51+
4552 $this->cursor = 0;
4653 $this->stmt = $stmt;
4754 }
4855
49 - function free() {
 56+ public function free() {
5057 oci_free_statement($this->stmt);
5158 }
5259
53 - function seek($row) {
 60+ public function seek($row) {
5461 $this->cursor = min($row, $this->nrows);
5562 }
5663
57 - function numRows() {
 64+ public function numRows() {
5865 return $this->nrows;
5966 }
6067
61 - function numFields() {
 68+ public function numFields() {
6269 return oci_num_fields($this->stmt);
6370 }
6471
65 - function fetchObject() {
 72+ public function fetchObject() {
6673 if ($this->cursor >= $this->nrows)
6774 return false;
68 -
6975 $row = $this->rows[$this->cursor++];
7076 $ret = new stdClass();
7177 foreach ($row as $k => $v) {
@@ -75,7 +81,7 @@
7682 return $ret;
7783 }
7884
79 - function fetchAssoc() {
 85+ public function fetchRow() {
8086 if ($this->cursor >= $this->nrows)
8187 return false;
8288
@@ -91,8 +97,62 @@
9298 }
9399
94100 /**
 101+ * Utility class.
95102 * @ingroup Database
96103 */
 104+class ORAField {
 105+ private $name, $tablename, $default, $max_length, $nullable,
 106+ $is_pk, $is_unique, $is_multiple, $is_key, $type;
 107+
 108+ function __construct($info) {
 109+ $this->name = $info['column_name'];
 110+ $this->tablename = $info['table_name'];
 111+ $this->default = $info['data_default'];
 112+ $this->max_length = $info['data_length'];
 113+ $this->nullable = $info['not_null'];
 114+ $this->is_pk = isset($info['prim']) && $info['prim'] == 1 ? 1 : 0;
 115+ $this->is_unique = isset($info['uniq']) && $info['uniq'] == 1 ? 1 : 0;
 116+ $this->is_multiple = isset($info['nonuniq']) && $info['nonuniq'] == 1 ? 1 : 0;
 117+ $this->is_key = ($this->is_pk || $this->is_unique || $this->is_multiple);
 118+ $this->type = $info['data_type'];
 119+ }
 120+
 121+ function name() {
 122+ return $this->name;
 123+ }
 124+
 125+ function tableName() {
 126+ return $this->tablename;
 127+ }
 128+
 129+ function defaultValue() {
 130+ return $this->default;
 131+ }
 132+
 133+ function maxLength() {
 134+ return $this->max_length;
 135+ }
 136+
 137+ function nullable() {
 138+ return $this->nullable;
 139+ }
 140+
 141+ function isKey() {
 142+ return $this->is_key;
 143+ }
 144+
 145+ function isMultipleKey() {
 146+ return $this->is_multiple;
 147+ }
 148+
 149+ function type() {
 150+ return $this->type;
 151+ }
 152+}
 153+
 154+/**
 155+ * @ingroup Database
 156+ */
97157 class DatabaseOracle extends Database {
98158 var $mInsertId = NULL;
99159 var $mLastResult = NULL;
@@ -101,20 +161,14 @@
102162 var $cursor = 0;
103163 var $mAffectedRows;
104164
 165+ var $ignore_DUP_VAL_ON_INDEX = false;
 166+
105167 function DatabaseOracle($server = false, $user = false, $password = false, $dbName = false,
106 - $failFunction = false, $flags = 0 )
 168+ $failFunction = false, $flags = 0, $tablePrefix = 'get from global' )
107169 {
108 -
109 - global $wgOut;
110 - # Can't get a reference if it hasn't been set yet
111 - if ( !isset( $wgOut ) ) {
112 - $wgOut = NULL;
113 - }
114 - $this->mOut =& $wgOut;
115 - $this->mFailFunction = $failFunction;
116 - $this->mFlags = $flags;
117 - $this->open( $server, $user, $password, $dbName);
118 -
 170+ $tablePrefix = $tablePrefix == 'get from global' ? $tablePrefix : strtoupper($tablePrefix);
 171+ parent::__construct($server, $user, $password, $dbName, $failFunction, $flags, $tablePrefix);
 172+ wfRunHooks( 'DatabaseOraclePostInit', array(&$this));
119173 }
120174
121175 function cascadingDeletes() {
@@ -153,8 +207,7 @@
154208 if ( !function_exists( 'oci_connect' ) ) {
155209 throw new DBConnectionError( $this, "Oracle functions missing, have you compiled PHP with the --with-oci8 option?\n (Note: if you recently installed PHP, you may need to restart your webserver and database)\n" );
156210 }
157 -
158 - # Needed for proper UTF-8 functionality
 211+
159212 putenv("NLS_LANG=AMERICAN_AMERICA.AL32UTF8");
160213
161214 $this->close();
@@ -167,8 +220,11 @@
168221 return;
169222 }
170223
171 - error_reporting( E_ALL );
172 - $this->mConn = oci_connect($user, $password, $dbName);
 224+ //error_reporting( E_ALL ); //whoever had this bright idea
 225+ if ( $this->mFlags & DBO_DEFAULT )
 226+ $this->mConn = oci_new_connect($user, $password, $dbName);
 227+ else
 228+ $this->mConn = oci_connect($user, $password, $dbName);
173229
174230 if ($this->mConn == false) {
175231 wfDebug("DB connection error\n");
@@ -178,6 +234,11 @@
179235 }
180236
181237 $this->mOpened = true;
 238+
 239+ #removed putenv calls because they interfere with the system globaly
 240+ $this->doQuery('ALTER SESSION SET NLS_TIMESTAMP_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'');
 241+ $this->doQuery('ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'');
 242+
182243 return $this->mConn;
183244 }
184245
@@ -204,18 +265,36 @@
205266 throw new MWException("SQL encoding is invalid");
206267 }
207268
 269+ //handle some oracle specifics
 270+ //remove AS column/table/subquery namings
 271+ $sql = preg_replace('/ as /i', ' ', $sql);
 272+ // Oracle has issues with UNION clause if the statement includes LOB fields
 273+ // So we do a UNION ALL and then filter the results array with array_unique
 274+ $union_unique = (preg_match('/\/\* UNION_UNIQUE \*\/ /', $sql) != 0);
 275+ //EXPLAIN syntax in Oracle is EXPLAIN PLAN FOR and it return nothing
 276+ //you have to select data from plan table after explain
 277+ $explain_id = date('dmYHis');
 278+ $sql = preg_replace('/^EXPLAIN /', 'EXPLAIN PLAN SET STATEMENT_ID = \''.$explain_id.'\' FOR', $sql, 1, $explain_count);
 279+
 280+
208281 if (($this->mLastResult = $stmt = oci_parse($this->mConn, $sql)) === false) {
209282 $e = oci_error($this->mConn);
210283 $this->reportQueryError($e['message'], $e['code'], $sql, __FUNCTION__);
211284 }
212285
 286+ $olderr = error_reporting(E_ERROR);
213287 if (oci_execute($stmt, $this->execFlags()) == false) {
214288 $e = oci_error($stmt);
215 - $this->reportQueryError($e['message'], $e['code'], $sql, __FUNCTION__);
 289+ if (!$this->ignore_DUP_VAL_ON_INDEX || $e['code'] != '1')
 290+ $this->reportQueryError($e['message'], $e['code'], $sql, __FUNCTION__);
216291 }
217 - if (oci_statement_type($stmt) == "SELECT")
218 - return new ORAResult($this, $stmt);
219 - else {
 292+ error_reporting($olderr);
 293+
 294+ if ($explain_count > 0) {
 295+ return $this->doQuery('SELECT id, cardinality "ROWS" FROM plan_table WHERE statement_id = \''.$explain_id.'\'');
 296+ } elseif (oci_statement_type($stmt) == "SELECT") {
 297+ return new ORAResult($this, $stmt, $union_unique);
 298+ } else {
220299 $this->mAffectedRows = oci_num_rows($stmt);
221300 return true;
222301 }
@@ -226,27 +305,47 @@
227306 }
228307
229308 function freeResult($res) {
230 - $res->free();
 309+ if ( $res instanceof ORAResult ) {
 310+ $res->free();
 311+ } else {
 312+ $res->result->free();
 313+ }
231314 }
232315
233316 function fetchObject($res) {
234 - return $res->fetchObject();
 317+ if ( $res instanceof ORAResult ) {
 318+ return $res->numRows();
 319+ } else {
 320+ return $res->result->fetchObject();
 321+ }
235322 }
236323
237324 function fetchRow($res) {
238 - return $res->fetchAssoc();
 325+ if ( $res instanceof ORAResult ) {
 326+ return $res->fetchRow();
 327+ } else {
 328+ return $res->result->fetchRow();
 329+ }
239330 }
240331
241332 function numRows($res) {
242 - return $res->numRows();
 333+ if ( $res instanceof ORAResult ) {
 334+ return $res->numRows();
 335+ } else {
 336+ return $res->result->numRows();
 337+ }
243338 }
244339
245340 function numFields($res) {
246 - return $res->numFields();
 341+ if ( $res instanceof ORAResult ) {
 342+ return $res->numFields();
 343+ } else {
 344+ return $res->result->numFields();
 345+ }
247346 }
248347
249348 function fieldName($stmt, $n) {
250 - return pg_field_name($stmt, $n);
 349+ return oci_field_name($stmt, $n);
251350 }
252351
253352 /**
@@ -257,7 +356,11 @@
258357 }
259358
260359 function dataSeek($res, $row) {
261 - $res->seek($row);
 360+ if ( $res instanceof ORAResult ) {
 361+ $res->seek($row);
 362+ } else {
 363+ $res->result->seek($row);
 364+ }
262365 }
263366
264367 function lastError() {
@@ -284,63 +387,56 @@
285388 * Returns information about an index
286389 * If errors are explicitly ignored, returns NULL on failure
287390 */
288 - function indexInfo( $table, $index, $fname = 'Database::indexExists' ) {
 391+ function indexInfo( $table, $index, $fname = 'DatabaseOracle::indexExists' ) {
289392 return false;
290393 }
291394
292 - function indexUnique ($table, $index, $fname = 'Database::indexUnique' ) {
 395+ function indexUnique ($table, $index, $fname = 'DatabaseOracle::indexUnique' ) {
293396 return false;
294397 }
295398
296 - function insert( $table, $a, $fname = 'Database::insert', $options = array() ) {
 399+ function insert( $table, $a, $fname = 'DatabaseOracle::insert', $options = array() ) {
 400+ if ( !count( $a ) )
 401+ return true;
 402+
297403 if (!is_array($options))
298404 $options = array($options);
299405
300 - #if (in_array('IGNORE', $options))
301 - # $oldIgnore = $this->ignoreErrors(true);
 406+ if (in_array('IGNORE', $options))
 407+ $this->ignore_DUP_VAL_ON_INDEX = true;
302408
303 - # IGNORE is performed using single-row inserts, ignoring errors in each
304 - # FIXME: need some way to distiguish between key collision and other types of error
305 - //$oldIgnore = $this->ignoreErrors(true);
306409 if (!is_array(reset($a))) {
307410 $a = array($a);
308411 }
309412 foreach ($a as $row) {
310413 $this->insertOneRow($table, $row, $fname);
311414 }
312 - //$this->ignoreErrors($oldIgnore);
313415 $retVal = true;
314416
315 - //if (in_array('IGNORE', $options))
316 - // $this->ignoreErrors($oldIgnore);
 417+ if (in_array('IGNORE', $options))
 418+ $this->ignore_DUP_VAL_ON_INDEX = false;
317419
318420 return $retVal;
319421 }
320422
321423 function insertOneRow($table, $row, $fname) {
 424+ global $wgLang;
 425+
322426 // "INSERT INTO tables (a, b, c)"
323427 $sql = "INSERT INTO " . $this->tableName($table) . " (" . join(',', array_keys($row)) . ')';
324428 $sql .= " VALUES (";
325429
326430 // for each value, append ":key"
327431 $first = true;
328 - $returning = '';
329432 foreach ($row as $col => $val) {
330 - if (is_object($val)) {
331 - $what = "EMPTY_BLOB()";
332 - assert($returning === '');
333 - $returning = " RETURNING $col INTO :bval";
334 - $blobcol = $col;
335 - } else
336 - $what = ":$col";
337 -
338433 if ($first)
339 - $sql .= "$what";
 434+ $sql .= ':'.$col;
340435 else
341 - $sql.= ", $what";
 436+ $sql.= ', :'.$col;
 437+
342438 $first = false;
343439 }
344 - $sql .= ") $returning";
 440+ $sql .= ')';
345441
346442 $stmt = oci_parse($this->mConn, $sql);
347443 foreach ($row as $col => $val) {
@@ -349,39 +445,136 @@
350446 $this->reportQueryError($this->lastErrno(), $this->lastError(), $sql, __METHOD__);
351447 }
352448 }
353 -
354 - if (($bval = oci_new_descriptor($this->mConn, OCI_D_LOB)) === false) {
355 - $e = oci_error($stmt);
356 - throw new DBUnexpectedError($this, "Cannot create LOB descriptor: " . $e['message']);
 449+
 450+ $stmt = oci_parse($this->mConn, $sql);
 451+ foreach ($row as $col => $val) {
 452+ $col_type=$this->fieldInfo($this->tableName($table), $col)->type();
 453+ if ($col_type != 'BLOB' && $col_type != 'CLOB') {
 454+ if (is_object($val))
 455+ $val = $val->getData();
 456+
 457+ if (preg_match('/^timestamp.*/i', $col_type) == 1 && strtolower($val) == 'infinity')
 458+ $val = '31-12-2030 12:00:00.000000';
 459+
 460+ if (oci_bind_by_name($stmt, ":$col", $wgLang->checkTitleEncoding($val)) === false)
 461+ $this->reportQueryError($this->lastErrno(), $this->lastError(), $sql, __METHOD__);
 462+ } else {
 463+ if (($lob[$col] = oci_new_descriptor($this->mConn, OCI_D_LOB)) === false) {
 464+ $e = oci_error($stmt);
 465+ throw new DBUnexpectedError($this, "Cannot create LOB descriptor: " . $e['message']);
 466+ }
 467+
 468+ if (is_object($val)) {
 469+ $lob[$col]->writeTemporary($val->getData());
 470+ oci_bind_by_name($stmt, ":$col", $lob[$col], -1, SQLT_BLOB);
 471+ } else {
 472+ $lob[$col]->writeTemporary($val);
 473+ oci_bind_by_name($stmt, ":$col", $lob[$col], -1, OCI_B_CLOB);
 474+ }
 475+ }
357476 }
358 -
359 - if (strlen($returning))
360 - oci_bind_by_name($stmt, ":bval", $bval, -1, SQLT_BLOB);
361 -
 477+
 478+ $olderr = error_reporting(E_ERROR);
362479 if (oci_execute($stmt, OCI_DEFAULT) === false) {
363480 $e = oci_error($stmt);
364 - $this->reportQueryError($e['message'], $e['code'], $sql, __METHOD__);
 481+
 482+ if (!$this->ignore_DUP_VAL_ON_INDEX || $e['code'] != '1')
 483+ $this->reportQueryError($e['message'], $e['code'], $sql, __METHOD__);
 484+ else
 485+ $this->mAffectedRows = oci_num_rows($stmt);
 486+ } else
 487+ $this->mAffectedRows = oci_num_rows($stmt);
 488+ error_reporting($olderr);
 489+
 490+ if (isset($lob)){
 491+ foreach ($lob as $lob_i => $lob_v) {
 492+ $lob_v->free();
 493+ }
365494 }
366 - if (strlen($returning)) {
367 - $bval->save($row[$blobcol]->getData());
368 - $bval->free();
369 - }
 495+
370496 if (!$this->mTrxLevel)
371497 oci_commit($this->mConn);
372 -
 498+
373499 oci_free_statement($stmt);
374500 }
375501
 502+ function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = 'DatabaseOracle::insertSelect',
 503+ $insertOptions = array(), $selectOptions = array() )
 504+ {
 505+ $destTable = $this->tableName( $destTable );
 506+ if( !is_array( $selectOptions ) ) {
 507+ $selectOptions = array( $selectOptions );
 508+ }
 509+ list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
 510+ if( is_array( $srcTable ) ) {
 511+ $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
 512+ } else {
 513+ $srcTable = $this->tableName( $srcTable );
 514+ }
 515+ $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
 516+ " SELECT $startOpts " . implode( ',', $varMap ) .
 517+ " FROM $srcTable $useIndex ";
 518+ if ( $conds != '*' ) {
 519+ $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
 520+ }
 521+ $sql .= " $tailOpts";
 522+
 523+ if (in_array('IGNORE', $insertOptions))
 524+ $this->ignore_DUP_VAL_ON_INDEX = true;
 525+
 526+ $retval = $this->query( $sql, $fname );
 527+
 528+ if (in_array('IGNORE', $insertOptions))
 529+ $this->ignore_DUP_VAL_ON_INDEX = false;
 530+
 531+ return $retval;
 532+ }
 533+
376534 function tableName( $name ) {
377 - # Replace reserved words with better ones
 535+ global $wgSharedDB, $wgSharedPrefix, $wgSharedTables;
 536+ /*
 537+ Replace reserved words with better ones
 538+ Useing uppercase, because that's the only way oracle can handle
 539+ quoted tablenames
 540+ */
378541 switch( $name ) {
379542 case 'user':
380 - return 'mwuser';
 543+ $name = 'MWUSER'; break;
381544 case 'text':
382 - return 'pagecontent';
383 - default:
384 - return $name;
 545+ $name = 'PAGECONTENT'; break;
385546 }
 547+
 548+ /*
 549+ The rest of procedure is equal to generic Databse class
 550+ except for the quoting style
 551+ */
 552+ if ( $name[0] == '"' && substr( $name, -1, 1 ) == '"' ) return $name;
 553+
 554+ if( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) return $name;
 555+ $dbDetails = array_reverse( explode( '.', $name, 2 ) );
 556+ if( isset( $dbDetails[1] ) ) @list( $table, $database ) = $dbDetails;
 557+ else @list( $table ) = $dbDetails;
 558+
 559+ $prefix = $this->mTablePrefix;
 560+
 561+ if( isset($database) ) $table = ( $table[0] == '`' ? $table : "`{$table}`" );
 562+
 563+ if( !isset( $database )
 564+ && isset( $wgSharedDB )
 565+ && $table[0] != '"'
 566+ && isset( $wgSharedTables )
 567+ && is_array( $wgSharedTables )
 568+ && in_array( $table, $wgSharedTables ) ) {
 569+ $database = $wgSharedDB;
 570+ $prefix = isset( $wgSharedPrefix ) ? $wgSharedPrefix : $prefix;
 571+ }
 572+
 573+ if( isset($database) ) $database = ( $database[0] == '"' ? $database : "\"{$database}\"" );
 574+ $table = ( $table[0] == '"' ? $table : "\"{$prefix}{$table}\"" );
 575+
 576+ $tableName = ( isset($database) ? "{$database}.{$table}" : "{$table}" );
 577+
 578+ return strtoupper($tableName);
386579 }
387580
388581 /**
@@ -411,7 +604,7 @@
412605 # It may be more efficient to leave off unique indexes which are unlikely to collide.
413606 # However if you do this, you run the risk of encountering errors which wouldn't have
414607 # occurred in MySQL
415 - function replace( $table, $uniqueIndexes, $rows, $fname = 'Database::replace' ) {
 608+ function replace( $table, $uniqueIndexes, $rows, $fname = 'DatabaseOracle::replace' ) {
416609 $table = $this->tableName($table);
417610
418611 if (count($rows)==0) {
@@ -454,16 +647,14 @@
455648 }
456649
457650 # Now insert the row
458 - $sql = "INSERT INTO $table (" . $this->makeList( array_keys( $row ), LIST_NAMES ) .') VALUES (' .
459 - $this->makeList( $row, LIST_COMMA ) . ')';
460 - $this->query($sql, $fname);
 651+ $this->insert( $table, $row, $fname );
461652 }
462653 }
463654
464655 # DELETE where the condition is a join
465 - function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin" ) {
 656+ function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "DatabaseOracle::deleteJoin" ) {
466657 if ( !$conds ) {
467 - throw new DBUnexpectedError($this, 'Database::deleteJoin() called with empty $conds' );
 658+ throw new DBUnexpectedError($this, 'DatabaseOracle::deleteJoin() called with empty $conds' );
468659 }
469660
470661 $delTable = $this->tableName( $delTable );
@@ -502,9 +693,15 @@
503694 function limitResult($sql, $limit, $offset) {
504695 if ($offset === false)
505696 $offset = 0;
506 - return "SELECT * FROM ($sql) WHERE rownum >= (1 + $offset) AND rownum < 1 + $limit + $offset";
 697+ return "SELECT * FROM ($sql) WHERE rownum >= (1 + $offset) AND rownum < (1 + $limit + $offset)";
507698 }
508699
 700+
 701+ function unionQueries($sqls, $all = false) {
 702+ $glue = ' UNION ALL ';
 703+ return 'SELECT * '.($all?'':'/* UNION_UNIQUE */ ').'FROM ('.implode( $glue, $sqls ).')' ;
 704+ }
 705+
509706 /**
510707 * Returns an SQL expression for a simple conditional.
511708 * Uses CASE on Oracle
@@ -540,12 +737,12 @@
541738 ++$this->mErrorCount;
542739
543740 if ($ignore || $tempIgnore) {
544 -echo "error ignored! query = [$sql]\n";
 741+//echo "error ignored! query = [$sql]\n";
545742 wfDebug("SQL ERROR (ignored): $error\n");
546743 $this->ignoreErrors( $ignore );
547744 }
548745 else {
549 -echo "error!\n";
 746+//echo "error!\n";
550747 $message = "A database error has occurred\n" .
551748 "Query: $sql\n" .
552749 "Function: $fname\n" .
@@ -572,24 +769,51 @@
573770 * Query whether a given table exists (in the given schema, or the default mw one if not given)
574771 */
575772 function tableExists($table) {
576 - $etable= $this->addQuotes($table);
577 - $SQL = "SELECT 1 FROM user_tables WHERE table_name='$etable'";
578 - $res = $this->query($SQL);
579 - $count = $res ? oci_num_rows($res) : 0;
580 - if ($res)
581 - $this->freeResult($res);
 773+ $SQL = "SELECT 1 FROM user_tables WHERE table_name='$table'";
 774+ $res = $this->doQuery($SQL);
 775+ if ($res) {
 776+ $count = $res->numRows();
 777+ $res->free();
 778+ } else {
 779+ $count = 0;
 780+ }
582781 return $count;
583782 }
584783
585784 /**
586785 * Query whether a given column exists in the mediawiki schema
 786+ * based on prebuilt table to simulate MySQL field info and keep query speed minimal
587787 */
588788 function fieldExists( $table, $field ) {
589 - return true; // XXX
 789+ if (!isset($this->fieldInfo_stmt))
 790+ $this->fieldInfo_stmt = oci_parse($this->mConn, 'SELECT * FROM wiki_field_info_full WHERE table_name = upper(:tab) and column_name = UPPER(:col)');
 791+
 792+ oci_bind_by_name($this->fieldInfo_stmt, ':tab', trim($table, '"'));
 793+ oci_bind_by_name($this->fieldInfo_stmt, ':col', $field);
 794+
 795+ if (oci_execute($this->fieldInfo_stmt, OCI_DEFAULT) === false) {
 796+ $e = oci_error($this->fieldInfo_stmt);
 797+ $this->reportQueryError($e['message'], $e['code'], 'fieldInfo QUERY', __METHOD__);
 798+ return false;
 799+ }
 800+ $res = new ORAResult($this,$this->fieldInfo_stmt);
 801+ return $res->numRows() != 0;
590802 }
591803
592804 function fieldInfo( $table, $field ) {
593 - return false; // XXX
 805+ if (!isset($this->fieldInfo_stmt))
 806+ $this->fieldInfo_stmt = oci_parse($this->mConn, 'SELECT * FROM wiki_field_info_full WHERE table_name = upper(:tab) and column_name = UPPER(:col)');
 807+
 808+ oci_bind_by_name($this->fieldInfo_stmt, ':tab', trim($table, '"'));
 809+ oci_bind_by_name($this->fieldInfo_stmt, ':col', $field);
 810+
 811+ if (oci_execute($this->fieldInfo_stmt, OCI_DEFAULT) === false) {
 812+ $e = oci_error($this->fieldInfo_stmt);
 813+ $this->reportQueryError($e['message'], $e['code'], 'fieldInfo QUERY', __METHOD__);
 814+ return false;
 815+ }
 816+ $res = new ORAResult($this,$this->fieldInfo_stmt);
 817+ return new ORAField($res->fetchRow());
594818 }
595819
596820 function begin( $fname = '' ) {
@@ -620,8 +844,9 @@
621845 }
622846
623847 function addQuotes( $s ) {
624 - global $wgLang;
625 - $s = $wgLang->checkTitleEncoding($s);
 848+ global $wgLang;
 849+ if (isset($wgLang->mLoaded) && $wgLang->mLoaded)
 850+ $s = $wgLang->checkTitleEncoding($s);
626851 return "'" . $this->strencode($s) . "'";
627852 }
628853
@@ -634,6 +859,15 @@
635860 return true;
636861 }
637862
 863+ function selectRow( $table, $vars, $conds, $fname = 'DatabaseOracle::selectRow', $options = array(), $join_conds = array() ) {
 864+ if (is_array($table))
 865+ foreach ($table as $tab)
 866+ $tab = $this->tableName($tab);
 867+ else
 868+ $table = $this->tableName($table);
 869+ return parent::selectRow($table, $vars, $conds, $fname, $options, $join_conds);
 870+ }
 871+
638872 /**
639873 * Returns an optional USE INDEX clause to go after the table, and a
640874 * string to go at the end of the query
@@ -658,12 +892,6 @@
659893 if ( isset( $options['GROUP BY'] ) ) $preLimitTail .= " GROUP BY {$options['GROUP BY']}";
660894 if ( isset( $options['ORDER BY'] ) ) $preLimitTail .= " ORDER BY {$options['ORDER BY']}";
661895
662 - if (isset($options['LIMIT'])) {
663 - // $tailOpts .= $this->limitResult('', $options['LIMIT'],
664 - // isset($options['OFFSET']) ? $options['OFFSET']
665 - // : false);
666 - }
667 -
668896 #if ( isset( $noKeyOptions['FOR UPDATE'] ) ) $tailOpts .= ' FOR UPDATE';
669897 #if ( isset( $noKeyOptions['LOCK IN SHARE MODE'] ) ) $tailOpts .= ' LOCK IN SHARE MODE';
670898 if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) $startOpts .= 'DISTINCT';
@@ -677,6 +905,38 @@
678906 return array( $startOpts, $useIndex, $preLimitTail, $postLimitTail );
679907 }
680908
 909+ public function makeList( $a, $mode = LIST_COMMA ) {
 910+ if ( !is_array( $a ) ) {
 911+ throw new DBUnexpectedError( $this, 'DatabaseOracle::makeList called with incorrect parameters' );
 912+ }
 913+ $a2 = array();
 914+ foreach ($a as $key => $value) {
 915+ if (strpos($key, ' & ') !== FALSE)
 916+ $a2[preg_replace('/(.*)\s&\s(.*)/', 'BITAND($1, $2)', $key)] = $value;
 917+ elseif (strpos($key, ' | ') !== FALSE)
 918+ $a2[preg_replace('/(.*)\s|\s(.*)/', 'BITOR($1, $2)', $key)] = $value;
 919+ elseif (!is_array($value)) {
 920+ if (strpos($value, ' = ') !== FALSE) {
 921+ if (strpos($value, ' & ') !== FALSE)
 922+ $a2[$key] = preg_replace('/(.*)\s&\s(.*?)\s=\s(.*)/', 'BITAND($1, $2) = $3', $value);
 923+ elseif (strpos($value, ' | ') !== FALSE)
 924+ $a2[$key] = preg_replace('/(.*)\s|\s(.*?)\s=\s(.*)/', 'BITOR($1, $2) = $3', $value);
 925+ else $a2[$key] = $value;
 926+ }
 927+ elseif (strpos($value, ' & ') !== FALSE)
 928+ $a2[$key] = preg_replace('/(.*)\s&\s(.*)/', 'BITAND($1, $2)', $value);
 929+ elseif (strpos($value, ' | ') !== FALSE)
 930+ $a2[$key] = preg_replace('/(.*)\s|\s(.*)/', 'BITOR($1, $2)', $value);
 931+ else
 932+ $a2[$key] = $value;
 933+ }
 934+ else
 935+ $a2[$key] = $value;
 936+ }
 937+
 938+ return parent::makeList($a2, $mode);
 939+ }
 940+
681941 public function setTimeout( $timeout ) {
682942 // @todo fixme no-op
683943 }
Index: trunk/phase3/includes/SearchOracle.php
@@ -38,6 +38,9 @@
3939 * @return OracleSearchResultSet
4040 */
4141 function searchText( $term ) {
 42+ if ($term == '')
 43+ return new OracleSearchResultSet(false, '');
 44+
4245 $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), true)));
4346 return new OracleSearchResultSet($resultSet, $this->searchTerms);
4447 }
@@ -49,6 +52,9 @@
5053 * @return ORacleSearchResultSet
5154 */
5255 function searchTitle($term) {
 56+ if ($term == '')
 57+ return new OracleSearchResultSet(false, '');
 58+
5359 $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), false)));
5460 return new MySQLSearchResultSet($resultSet, $this->searchTerms);
5561 }
@@ -214,6 +220,7 @@
215221 * @ingroup Search
216222 */
217223 class OracleSearchResultSet extends SearchResultSet {
 224+
218225 function __construct($resultSet, $terms) {
219226 $this->mResultSet = $resultSet;
220227 $this->mTerms = $terms;
@@ -224,10 +231,16 @@
225232 }
226233
227234 function numRows() {
228 - return $this->mResultSet->numRows();
 235+ if ($this->mResultSet === false )
 236+ return 0;
 237+ else
 238+ return $this->mResultSet->numRows();
229239 }
230240
231241 function next() {
 242+ if ($this->mResultSet === false )
 243+ return false;
 244+
232245 $row = $this->mResultSet->fetchObject();
233246 if ($row === false)
234247 return false;
Index: trunk/phase3/includes/specials/SpecialUnusedimages.php
@@ -25,9 +25,16 @@
2626 global $wgCountCategorizedImagesAsUsed, $wgDBtype;
2727 $dbr = wfGetDB( DB_SLAVE );
2828
29 - $epoch = $wgDBtype == 'mysql' ?
30 - 'UNIX_TIMESTAMP(img_timestamp)' :
31 - 'EXTRACT(epoch FROM img_timestamp)';
 29+ switch ($wgDBtype) {
 30+ case 'mysql':
 31+ $epoch = 'UNIX_TIMESTAMP(img_timestamp)';
 32+ break;
 33+ case 'oracle':
 34+ $epoch = '((trunc(img_timestamp) - to_date(\'19700101\',\'YYYYMMDD\')) * 86400)';
 35+ break;
 36+ default:
 37+ $epoch = 'EXTRACT(epoch FROM img_timestamp)';
 38+ }
3239
3340 if ( $wgCountCategorizedImagesAsUsed ) {
3441 list( $page, $image, $imagelinks, $categorylinks ) = $dbr->tableNamesN( 'page', 'image', 'imagelinks', 'categorylinks' );
Index: trunk/phase3/includes/specials/SpecialAncientpages.php
@@ -25,8 +25,18 @@
2626 $db = wfGetDB( DB_SLAVE );
2727 $page = $db->tableName( 'page' );
2828 $revision = $db->tableName( 'revision' );
29 - $epoch = $wgDBtype == 'mysql' ? 'UNIX_TIMESTAMP(rev_timestamp)' :
30 - 'EXTRACT(epoch FROM rev_timestamp)';
 29+
 30+ switch ($wgDBtype) {
 31+ case 'mysql':
 32+ $epoch = 'UNIX_TIMESTAMP(rev_timestamp)';
 33+ break;
 34+ case 'oracle':
 35+ $epoch = '((trunc(rev_timestamp) - to_date(\'19700101\',\'YYYYMMDD\')) * 86400)';
 36+ break;
 37+ default:
 38+ $epoch = 'EXTRACT(epoch FROM rev_timestamp)';
 39+ }
 40+
3141 return
3242 "SELECT 'Ancientpages' as type,
3343 page_namespace as namespace,
Index: trunk/phase3/RELEASE-NOTES
@@ -37,6 +37,8 @@
3838 which was already effectively treating the namespace as if it had subpages.
3939 * (bug 10837) $wgVariant is a user variant selected in the user's preferences
4040 if the $wgContLang does not have variant, then the $wgLang is used instead.
 41+* Oracle: maintenance/ora/user.sql script for creating DB user on oracle with
 42+ appropriate privileges
4143
4244 === New features in 1.16 ===
4345

Comments

#Comment by Catrope (talk | contribs)   15:18, 5 June 2009

The way $epoch is handled here is ugly, but a better way to handle this (one that doesn't need $epoch) is nearly finished in the querypage-work branch.

#Comment by Tim Starling (talk | contribs)   04:43, 6 June 2009

Reviewed common files, oracle-specific files deferred.

Status & tagging log