1 -- $Id: psql-initialize.sql,v 1.17 2007-01-28 23:35:59 rurban Exp $
5 --================================================================
6 -- Prefix for table names.
8 -- You should set this to the same value you specify for
9 -- DATABASE_PREFIX in config/config.ini
13 --================================================================
14 -- Which postgresql user gets access to the tables?
16 -- You should set this to the name of the postgresql
17 -- user who will be accessing the tables.
18 -- See DATABASE_DSN in config.ini
20 -- NOTE: To be able to vacuum the tables from ordinary page requests
21 -- :httpd_user must be the table owner.
22 -- To run autovacuum and disable page requests vacuums edit the
23 -- pqsql backend optimize method in lib/WikiDB/backend/*_psql.php
25 -- Commonly, connections from php are made under
26 -- the user name of 'nobody', 'apache' or 'www'.
28 \set httpd_user 'wikiuser'
30 \set qprefix '\'' :prefix '\''
31 \set qhttp_user '\'' :httpd_user '\''
33 \echo At first init the database with:
34 \echo '$ createdb phpwiki'
35 \echo '$ createuser -S -R -d ' :qhttp_user
36 \echo '$ psql -U ' :qhttp_user ' ' :qprefix 'phpwiki < /usr/share/postgresql/contrib/tsearch2.sql'
37 \echo 'Did you customize the ispell and synonym dictionaries in psql-initialize.sql ?'
38 \echo '$ psql -U ' :qhttp_user ' ' :qprefix 'phpwiki < psql-initialize.sql'
39 -- remove the quit line below
42 --================================================================
44 -- Don't modify below this point unless you know what you are doing.
46 --================================================================
49 \echo Initializing PhpWiki tables with:
50 \echo ' prefix = ' :qprefix
51 \echo ' httpd_user = ' :qhttp_user
53 \echo 'Expect some \'NOTICE: CREATE ... will create implicit sequence/index ...\' messages '
55 \set page_tbl :prefix 'page'
56 \set page_id_seq :prefix 'page_id_seq'
57 \set page_id_idx :prefix 'page_id_idx'
58 \set page_name_idx :prefix 'page_name_idx'
60 \set version_tbl :prefix 'version'
61 \set vers_id_idx :prefix 'vers_id_idx'
62 \set vers_mtime_idx :prefix 'vers_mtime_idx'
64 \set recent_tbl :prefix 'recent'
65 \set recent_id_idx :prefix 'recent_id_idx'
66 \set recent_lv_idx :prefix 'recent_lv_idx'
68 \set nonempty_tbl :prefix 'nonempty'
69 \set nonmt_id_idx :prefix 'nonmt_id_idx'
71 \set link_tbl :prefix 'link'
72 \set link_from_idx :prefix 'link_from_idx'
73 \set link_to_idx :prefix 'link_to_idx'
74 \set relation_idx :prefix 'relation_idx'
76 \set pagedata_tbl :prefix 'pagedata'
77 \set pagedata_id_idx :prefix 'pagedata_id_idx'
78 \set versiondata_tbl :prefix 'versiondata'
79 \set pageperm_tbl :prefix 'pageperm'
80 \set pageperm_id_idx :prefix 'pageperm_id_idx'
81 \set pageperm_access_idx :prefix 'pageperm_access_idx'
82 \set existing_page_view :prefix 'existing_page'
83 \set curr_page_view :prefix 'curr_page'
85 \set session_tbl :prefix 'session'
86 \set sess_id_idx :prefix 'sess_id_idx'
87 \set sess_date_idx :prefix 'sess_date_idx'
88 \set sess_ip_idx :prefix 'sess_ip_idx'
90 \set pref_tbl :prefix 'pref'
91 \set pref_id_idx :prefix 'pref_id_idx'
92 --\set user_tbl :prefix 'users'
93 --\set user_id_idx :prefix 'users_id_idx'
94 \set member_tbl :prefix 'member'
95 \set member_id_idx :prefix 'member_id_idx'
96 \set member_group_idx :prefix 'member_group_idx'
98 \set rating_tbl :prefix 'rating'
99 \set rating_id_idx :prefix 'rating_id_idx'
101 \set accesslog_tbl :prefix 'accesslog'
102 \set accesslog_time_idx :prefix 'log_time_idx'
103 \set accesslog_host_idx :prefix 'log_host_idx'
105 \set update_recent_fn :prefix 'update_recent'
106 \set prepare_rename_fn :prefix 'prepare_rename_page'
108 \echo Creating :page_tbl
109 CREATE TABLE :page_tbl (
110 id SERIAL PRIMARY KEY,
111 pagename VARCHAR(100) NOT NULL UNIQUE CHECK (pagename <> ''),
112 hits INT4 NOT NULL DEFAULT 0,
113 pagedata TEXT NOT NULL DEFAULT '',
114 cached_html bytea DEFAULT ''
116 -- CREATE UNIQUE INDEX :page_id_idx ON :page_tbl (id);
117 -- CREATE UNIQUE INDEX :page_name_idx ON :page_tbl (pagename);
119 -- we use 0 <=> global_data to satisfy the relation = 0 constraint
120 INSERT INTO :page_tbl VALUES (0,'global_data',0,'','');
122 \echo Creating :version_tbl
123 CREATE TABLE :version_tbl (
124 id INT4 REFERENCES :page_tbl,
125 version INT4 NOT NULL,
127 -- FIXME: should use boolean, but that returns 't' or 'f'. not 0 or 1.
128 minor_edit INT2 DEFAULT 0,
129 -- use bytea instead?
130 content TEXT NOT NULL DEFAULT '',
131 versiondata TEXT NOT NULL DEFAULT ''
133 CREATE UNIQUE INDEX :vers_id_idx ON :version_tbl (id, version);
134 CREATE INDEX :vers_mtime_idx ON :version_tbl (mtime);
135 -- deletion order: version, recent, nonempty
137 \echo Creating :recent_tbl
138 CREATE TABLE :recent_tbl (
139 id INT4 REFERENCES :page_tbl,
143 FOREIGN KEY (id, latestversion) REFERENCES :version_tbl (id, version),
144 CHECK (latestminor >= latestmajor)
146 CREATE UNIQUE INDEX :recent_id_idx ON :recent_tbl (id);
147 CREATE INDEX :recent_lv_idx ON :recent_tbl (latestversion);
149 \echo Creating :nonempty_tbl
150 CREATE TABLE :nonempty_tbl (
151 id INT4 NOT NULL REFERENCES :page_tbl
153 CREATE UNIQUE INDEX :nonmt_id_idx ON :nonempty_tbl (id);
155 \echo Creating experimental pagedata (not yet used)
156 CREATE TABLE :pagedata_tbl (
157 id INT4 NOT NULL REFERENCES :page_tbl,
160 rest TEXT NOT NULL DEFAULT ''
162 CREATE INDEX :pagedata_id_idx ON pagedata (id);
164 \echo Creating experimental versiondata (not yet used)
165 CREATE TABLE :versiondata_tbl (
167 version INT4 NOT NULL,
168 markup INT2 DEFAULT 2,
170 author_id VARCHAR(48),
171 pagetype VARCHAR(20) DEFAULT 'wikitext',
172 rest TEXT NOT NULL DEFAULT '',
173 FOREIGN KEY (id, version) REFERENCES :version_tbl (id, version)
175 \echo Creating experimental pageperm (not yet used)
176 CREATE TABLE :pageperm_tbl (
177 id INT4 NOT NULL REFERENCES :page_tbl(id),
178 -- view,edit,create,list,remove,change,dump
179 access CHAR(12) NOT NULL,
180 groupname VARCHAR(48),
183 CREATE INDEX :pageperm_id_idx ON pageperm (id);
184 CREATE INDEX :pageperm_access_idx ON pageperm (access);
186 \echo Creating experimental page views (not yet used)
188 -- nonempty versiondata
189 CREATE VIEW :existing_page_view AS
190 SELECT * FROM :page_tbl P INNER JOIN :nonempty_tbl N USING (id);
192 -- latest page version
193 CREATE VIEW :curr_page_view AS
194 SELECT P.id,P.pagename,P.hits,P.pagedata,P.cached_html,
195 V.version,V.mtime,V.minor_edit,V.content,V.versiondata
197 JOIN :version_tbl V USING (id)
198 JOIN :recent_tbl R ON (V.id=R.id AND V.version=R.latestversion);
200 \echo Creating :link_tbl
201 CREATE TABLE :link_tbl (
202 linkfrom INT4 NOT NULL REFERENCES :page_tbl,
203 linkto INT4 NOT NULL REFERENCES :page_tbl,
206 CREATE INDEX :link_from_idx ON :link_tbl (linkfrom);
207 CREATE INDEX :link_to_idx ON :link_tbl (linkto);
208 CREATE INDEX :relation_idx ON :link_tbl (relation);
210 -- ALTER TABLE link DROP CONSTRAINT link_relation_fkey;
212 -- if you plan to use the wikilens theme
213 \echo Creating :rating_tbl
214 CREATE TABLE :rating_tbl (
215 dimension INTEGER NOT NULL,
216 raterpage INT8 NOT NULL REFERENCES :page_tbl,
217 rateepage INT8 NOT NULL REFERENCES :page_tbl,
218 ratingvalue FLOAT NOT NULL,
219 rateeversion INT8 NOT NULL,
220 tstamp TIMESTAMP NOT NULL
222 CREATE UNIQUE INDEX :rating_id_idx ON :rating_tbl (dimension, raterpage, rateepage);
224 --================================================================
225 -- end of page relations
226 --================================================================
228 \echo Creating :session_tbl
229 CREATE TABLE :session_tbl (
230 sess_id CHAR(32) PRIMARY KEY,
231 sess_data bytea NOT NULL,
233 sess_ip CHAR(40) NOT NULL
235 -- CREATE UNIQUE INDEX :sess_id_idx ON :session_tbl (sess_id);
236 CREATE INDEX :sess_date_idx ON :session_tbl (sess_date);
237 CREATE INDEX :sess_ip_idx ON :session_tbl (sess_ip);
239 -- Optional DB Auth and Prefs
240 -- For these tables below the default table prefix must be used
241 -- in the DBAuthParam SQL statements also.
243 \echo Creating :pref_tbl
244 CREATE TABLE :pref_tbl (
245 userid CHAR(48) PRIMARY KEY,
246 prefs TEXT NULL DEFAULT '',
247 passwd CHAR(48) DEFAULT '',
248 groupname CHAR(48) DEFAULT 'users'
250 -- CREATE UNIQUE INDEX :pref_id_idx ON :pref_tbl (userid);
251 CREATE INDEX pref_group_idx ON :pref_tbl (groupname);
253 -- Use the member table, if you need it for n:m user-group relations,
254 -- and adjust your DBAUTH_AUTH_ SQL statements.
255 CREATE TABLE :member_tbl (
256 userid CHAR(48) NOT NULL REFERENCES :pref_tbl,
257 groupname CHAR(48) NOT NULL DEFAULT 'users'
259 CREATE INDEX :member_id_idx ON :member_tbl (userid);
260 CREATE INDEX :member_group_idx ON :member_tbl (groupname);
262 -- if ACCESS_LOG_SQL > 0
263 -- only if you need fast log-analysis (spam prevention, recent referrers)
264 -- see http://www.outoforder.cc/projects/apache/mod_log_sql/docs-2.0/#id2756178
265 \echo Creating :accesslog_tbl
266 CREATE TABLE :accesslog_tbl (
268 remote_host VARCHAR(100),
269 remote_user VARCHAR(50),
270 request_method VARCHAR(10),
271 request_line VARCHAR(255),
272 request_args VARCHAR(255),
273 request_file VARCHAR(255),
274 request_uri VARCHAR(255),
275 request_time CHAR(28),
278 referer VARCHAR(255),
280 request_duration FLOAT
282 CREATE INDEX :accesslog_time_idx ON :accesslog_tbl (time_stamp);
283 CREATE INDEX :accesslog_host_idx ON :accesslog_tbl (remote_host);
284 -- create extra indices on demand (usually referer. see plugin/AccessLogSql)
286 --================================================================
288 -- Use the tsearch2 fulltextsearch extension: (recommended) 7.4, 8.0, 8.1, 8.2
289 -- At first init it for the database:
290 -- $ psql phpwiki < /usr/share/postgresql/contrib/tsearch2.sql
292 -- Example of ISpell dictionary:
293 -- UPDATE pg_ts_dict SET dict_initoption='DictFile="/usr/local/share/ispell/russian.dict" ,AffFile ="/usr/local/share/ispell/russian.aff", StopFile="/usr/local/share/ispell/russian.stop"' WHERE dict_name='ispell_template';
294 -- Example of synonym dict:
295 -- UPDATE pg_ts_dict SET dict_initoption='/usr/local/share/ispell/english.syn' WHERE dict_id=5;
297 \echo Initializing tsearch2 indices
298 GRANT SELECT ON pg_ts_dict, pg_ts_parser, pg_ts_cfg, pg_ts_cfgmap TO :httpd_user;
299 ALTER TABLE :version_tbl ADD COLUMN idxFTI tsvector;
300 UPDATE :version_tbl SET idxFTI=to_tsvector('default', content);
302 CREATE INDEX idxFTI_idx ON :version_tbl USING gist(idxFTI);
304 CREATE TRIGGER tsvectorupdate BEFORE UPDATE OR INSERT ON :version_tbl
305 FOR EACH ROW EXECUTE PROCEDURE tsearch2(idxFTI, content);
307 --================================================================
309 \echo You might want to ignore the following errors or run
310 \echo /usr/sbin/createuser -S -R -d :httpd_user
312 \echo Applying permissions for role :httpd_user
313 GRANT SELECT,INSERT,UPDATE,DELETE ON :page_tbl TO :httpd_user;
314 GRANT SELECT,INSERT,UPDATE,DELETE ON :version_tbl TO :httpd_user;
315 GRANT SELECT,INSERT,UPDATE,DELETE ON :recent_tbl TO :httpd_user;
316 GRANT SELECT,INSERT,UPDATE,DELETE ON :nonempty_tbl TO :httpd_user;
317 GRANT SELECT,INSERT,UPDATE,DELETE ON :link_tbl TO :httpd_user;
319 GRANT SELECT,INSERT,UPDATE,DELETE ON :session_tbl TO :httpd_user;
320 -- you may want to fine tune this:
321 GRANT SELECT,INSERT,UPDATE,DELETE ON :pref_tbl TO :httpd_user;
322 -- GRANT SELECT ON :user_tbl TO :httpd_user;
323 GRANT SELECT ON :member_tbl TO :httpd_user;
324 GRANT SELECT,INSERT,UPDATE,DELETE ON :rating_tbl TO :httpd_user;
325 GRANT SELECT,INSERT,UPDATE,DELETE ON :accesslog_tbl TO :httpd_user;
327 --================================================================
328 -- some stored procedures to put unneccesary syntax into the server
330 \echo Initializing stored procedures
333 CREATE OR REPLACE FUNCTION :update_recent_fn (INT4, INT4)
334 RETURNS integer AS $$
335 DELETE FROM recent WHERE id = $1;
336 INSERT INTO recent (id, latestversion, latestmajor, latestminor)
337 SELECT id, MAX(version) AS latestversion,
338 MAX(CASE WHEN minor_edit = 0 THEN version END) AS latestmajor,
339 MAX(CASE WHEN minor_edit <> 0 THEN version END) AS latestminor
340 FROM version WHERE id = $2 GROUP BY id;
341 DELETE FROM nonempty WHERE id = $1;
342 INSERT INTO nonempty (id)
345 WHERE recent.id = version.id
346 AND version = latestversion
349 SELECT id FROM nonempty WHERE id = $1;
353 CREATE OR REPLACE FUNCTION :prepare_rename_fn (INT4, INT4)
355 DELETE FROM page WHERE id = $2;
356 DELETE FROM version WHERE id = $2;
357 DELETE FROM recent WHERE id = $2;
358 DELETE FROM nonempty WHERE id = $2;
359 -- We have to fix all referring tables to the old id
360 UPDATE link SET linkfrom = $1 WHERE linkfrom = $2;
361 UPDATE link SET linkto = $1 WHERE linkto = $2;