Index: trunk/extensions/Wikidata/App.php |
— | — | @@ -39,8 +39,10 @@ |
40 | 40 | # The permission needed to do ... |
41 | 41 | $wgCommunityEditPermission="editwikidata-tt"; # only used for copy for now |
42 | 42 | $wgCommunity_dc="uw"; |
| 43 | +global $extra_debugging; |
43 | 44 | $extra_debugging=true; |
44 | 45 | |
| 46 | + |
45 | 47 | # The site prefix allows us to have multiple sets of customized |
46 | 48 | # messages (for different, typically site-specific UIs) |
47 | 49 | # in a single database. |
Index: trunk/extensions/Wikidata/OmegaWiki/Copy.php |
— | — | @@ -577,6 +577,8 @@ |
578 | 578 | |
579 | 579 | protected function read() { |
580 | 580 | $dmid=$this->dmid; |
| 581 | + if (is_null($dmid)) |
| 582 | + throw new Exception ("DefinedMeaningCopier: read(): cannot read a dmid that is null"); |
581 | 583 | $this->defined_meaning=CopyTools::getRow($this->dc1,"defined_meaning","where defined_meaning_id=$dmid"); |
582 | 584 | return $this->defined_meaning; # for convenience |
583 | 585 | } |
— | — | @@ -687,10 +689,6 @@ |
688 | 690 | $this->defined_meaning["defined_meaning_id"], |
689 | 691 | $this->save_meaning["defined_meaning_id"]); |
690 | 692 | $classMembershipCopier->dup(); |
691 | | - |
692 | | - |
693 | | - |
694 | | - |
695 | 693 | } |
696 | 694 | } |
697 | 695 | |
— | — | @@ -907,6 +905,7 @@ |
908 | 906 | protected $new_class_member_mid; |
909 | 907 | protected $dc1; |
910 | 908 | protected $dc2; |
| 909 | + protected $tableName="class_membership"; |
911 | 910 | |
912 | 911 | /** coming from the defined meaning(dm) we don't know the membership id, |
913 | 912 | * but we do have the dmid (defined meaning id) for the class member, so let's use that |
— | — | @@ -950,10 +949,13 @@ |
951 | 950 | } |
952 | 951 | $membership["class_membership_id"]=$newid; |
953 | 952 | $membership["class_member_mid"]=$new_class_member_mid; |
954 | | - # nope, that's not right. |
955 | | - $classAttributesCopier=new ClassAttributesCopier($membership["class_mid"], $dc1, $dc2); |
956 | | - $membership["class_mid"]=$classAttributesCopier->dup(); |
957 | | - $this->doDM($membership, "class_mid", true); |
| 953 | + $oldmid=$membership["class_mid"]; |
| 954 | + $this->doDM($membership,"class_mid", true); |
| 955 | + $newmid=$membership["class_mid"]; |
| 956 | + $classAttributesCopier=new ClassAttributesCopier($oldmid, $newmid, $dc1, $dc2); |
| 957 | + $classAttributesCopier->dup(); |
| 958 | + echo "What are we working with <br>\n"; |
| 959 | + var_dump($membership); |
958 | 960 | CopyTools::dc_insert_assoc($dc2, "class_membership", $membership); |
959 | 961 | return $newid; |
960 | 962 | } |
— | — | @@ -972,8 +974,9 @@ |
973 | 975 | |
974 | 976 | /** you saw that right, class_mid, not class_id, there's no such thing :-/ |
975 | 977 | */ |
976 | | - public function __construct($class_mid, $dc1, $dc2) { |
977 | | - $this->src_class_mid=$class_mid; |
| 978 | + public function __construct($src_class_mid, $dst_class_mid, $dc1, $dc2) { |
| 979 | + $this->src_class_mid=$src_class_mid; |
| 980 | + $this->dst_class_mid=$dst_class_mid; |
978 | 981 | $this->dc1=$dc1; |
979 | 982 | $this->dc2=$dc2; |
980 | 983 | } |
— | — | @@ -982,9 +985,11 @@ |
983 | 986 | * because in this case, the class_mid is the key characteristic |
984 | 987 | */ |
985 | 988 | public function dup() { |
| 989 | + if (is_null($this->src_class_mid)) |
| 990 | + throw new Exception ("ClassAttributesCopier: Can't copy class; is null!"); |
986 | 991 | $attributes=$this->read(); |
987 | 992 | $this->write($attributes); |
988 | | - return $this->dst_class_mid; |
| 993 | + return $this->dst_class_mid; # XXX currently broken: actually it'll return the src_class_mid... |
989 | 994 | } |
990 | 995 | |
991 | 996 | public function read() { |
— | — | @@ -1005,16 +1010,16 @@ |
1006 | 1011 | $dc2=$this->dc2; |
1007 | 1012 | $class_mid=$this->src_class_mid; |
1008 | 1013 | |
| 1014 | + |
1009 | 1015 | if ($this->doObject($attribute,"object_id")) |
1010 | 1016 | return $attribute["object_id"]; |
1011 | 1017 | |
1012 | | - $this->doDM($attribute,"class_mid"); |
| 1018 | + $attribute["class_mid"]=$this->dst_class_mid; |
1013 | 1019 | $this->doDM($attribute,"level_mid"); |
1014 | 1020 | $this->doDM($attribute,"attribute_mid"); |
1015 | 1021 | |
1016 | 1022 | CopyTools::dc_insert_assoc($dc2, "class_attributes", $attribute); |
1017 | 1023 | |
1018 | | - $this->dst_class_mid=$attribute["class_mid"]; |
1019 | 1024 | return $attribute["object_id"]; |
1020 | 1025 | } |
1021 | 1026 | |
— | — | @@ -1059,7 +1064,7 @@ |
1060 | 1065 | * or null, if no such id exists in this case (for instance, if we copied multiple |
1061 | 1066 | * items, there is no single unique id) |
1062 | 1067 | */ |
1063 | | - public abstract function write(); |
| 1068 | + //public abstract function write(); |
1064 | 1069 | |
1065 | 1070 | /** @returns true if the copied item was already present in the other dataset, false if it wasn't (and we just copied it over) , or null if don't know/error/other. |
1066 | 1071 | */ |
— | — | @@ -1085,6 +1090,8 @@ |
1086 | 1091 | * false if it did not, and we just created it |
1087 | 1092 | */ |
1088 | 1093 | protected function doDM(&$row, $dmid_column, $full=false) { |
| 1094 | + echo "IN COPIER<br>\n"; |
| 1095 | + var_dump($row); |
1089 | 1096 | $dmCopier=new DefinedMeaningCopier($row[$dmid_column], $this->dc1, $this->dc2); |
1090 | 1097 | if ($full) { |
1091 | 1098 | $row[$dmid_column]=$dmCopier->dup(); |
— | — | @@ -1118,7 +1125,8 @@ |
1119 | 1126 | $copier->setTableName($this->tableName); |
1120 | 1127 | $copier->setAutovivify($this->autovivifyObjects); |
1121 | 1128 | $row[$object_column]=$copier->dup(); |
1122 | | - return $copier->already_there(); |
| 1129 | + $this->already_there=$copier->already_there(); |
| 1130 | + return $this->already_there; |
1123 | 1131 | } |
1124 | 1132 | |
1125 | 1133 | protected function doInsert($row) { |
Index: trunk/extensions/Wikidata/util/copy.php |
— | — | @@ -1,779 +0,0 @@ |
2 | | -<?php |
3 | | - |
4 | | -# (C) 2007 Alan Smithee (licensed under the GPL v. 2, GPL v. 3 or any later version, though you're not likely to care) |
5 | | -# throwaway rapid prototype to copy defined meanings between tables. |
6 | | -# I didn't write this, nobody saw me, you can't prove a thing! |
7 | | -# Actually somewhat easier than fighting through multiple layers of |
8 | | -# code in the recordsets for now. |
9 | | -# probably will refactor this code into ulta-pretty helpers or |
10 | | -# other recordset improvements. |
11 | | -# |
12 | | -# Addendum: this might not actually be so throwaway as was hoped. |
13 | | -# Don't you love it when that happens? |
14 | | - |
15 | | - |
16 | | -# common abbreviations used in varnames and comments: |
17 | | -# dm = defined meaning. |
18 | | -# dmid = defined meaning id: unique identifier for each dm. |
19 | | -# dc = dataset context. datasets are implemented by having |
20 | | -# tables with different prefixes |
21 | | -# dc1 = dataset (context) 1 (we are copying FROM dc1 (so we READ) ) |
22 | | -# dc2 = dataset (context) 2 (we are copying TO dc2 (so we WRITE) ) |
23 | | -# |
24 | | -# naming conventions: |
25 | | -# Normal: Java Style |
26 | | -# * ClassName->methodName($variableName); /* comment */ |
27 | | -# * CopyTools::getRow(...); # comment |
28 | | -# Wrappers around PHP functions or extensions to PHP function set: Same style as the wrapped function |
29 | | -# * mysql_insert_assoc(...); # comment |
30 | | -# |
31 | | -# TODO: |
32 | | -# * Change to library |
33 | | -# some read/write/dup functions are still main namespace, should get their own |
34 | | -# classes |
35 | | - |
36 | | - |
37 | | -header("Content-type: text/html; charset=UTF-8"); |
38 | | - |
39 | | -define('MEDIAWIKI', true ); |
40 | | -require_once("../../../StartProfiler.php"); |
41 | | -include_once("../../../includes/Defines.php"); |
42 | | -include_once("../../../LocalSettings.php"); |
43 | | -require_once("Setup.php"); |
44 | | -require_once("../OmegaWiki/WikiDataAPI.php"); |
45 | | -require_once("../OmegaWiki/Transaction.php"); |
46 | | - |
47 | | - |
48 | | -global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname; |
49 | | - |
50 | | -$db1=$wgDBserver; # hostname |
51 | | -$db2=$wgDBuser; # user |
52 | | -$db3=$wgDBpassword; # pass |
53 | | -$db4=$wgDBname; # db-name |
54 | | - |
55 | | -$connection=MySQL_connect($db1,$db2,$db3); |
56 | | -if (!$connection)die("Cannot connect to SQL server. Try again later."); |
57 | | -MySQL_select_db($db4)or die("Cannot open database"); |
58 | | -mysql_query("SET NAMES 'utf8'"); |
59 | | - |
60 | | - |
61 | | -/** copies items in the objects table. |
62 | | - * As a "side-effect" |
63 | | - * also conveniently reports to see if something was already_there |
64 | | - * (we don't want to accidentally duplicate things umpteen times, so the |
65 | | - * side-effect is almost as important) |
66 | | - */ |
67 | | -class ObjectCopier { |
68 | | - |
69 | | - protected $id; |
70 | | - protected $dc1; |
71 | | - protected $dc2; |
72 | | - protected $object; |
73 | | - protected $already_there=null; |
74 | | - |
75 | | - function __construct($id, $dc1, $dc2) { |
76 | | - $this->id=$id; |
77 | | - $this->dc1=$dc1; |
78 | | - $this->dc2=$dc2; |
79 | | - } |
80 | | - |
81 | | - function getObject() { |
82 | | - return $this->object; |
83 | | - } |
84 | | - |
85 | | - function setObject($object) { |
86 | | - $this->object=$object; |
87 | | - } |
88 | | - |
89 | | - /** return true if the object was already present in the other dataset*/ |
90 | | - public function already_there(){ |
91 | | - return $this->already_there; |
92 | | - } |
93 | | - |
94 | | - protected function read() { |
95 | | - $dc1=$this->dc1; |
96 | | - $id=$this->id; |
97 | | - $this->object=CopyTools::getRow($dc1, "objects", "WHERE object_id=$id"); |
98 | | - } |
99 | | - |
100 | | - /* tries to retrieve the identical UUID from the destination |
101 | | - * (dc2) dataset, if it exists. |
102 | | - * @returns the associative array representing this object, |
103 | | - * if successful. Else returns an empty array. |
104 | | - */ |
105 | | - protected function identical() { |
106 | | - var_dump($this->object); |
107 | | - $uuid=mysql_escape_string($this->object["UUID"]); |
108 | | - $dc2=$this->dc2; |
109 | | - return CopyTools::getRow($dc2, "objects", "WHERE `UUID`='$uuid'"); |
110 | | - } |
111 | | - |
112 | | - /** Write copy of object into the objects table,taking into account |
113 | | - * necessary changes. |
114 | | - * possible TODO: Currently induces the target table from the original |
115 | | - * destination table name. |
116 | | - * Perhaps would be wiser to get the target table as an (override) parameter. |
117 | | - */ |
118 | | - function write() { |
119 | | - $dc2 = $this->dc2; |
120 | | - $object = $this->object; |
121 | | - unset($object["object_id"]); |
122 | | - |
123 | | - $tableName_exploded = explode("_", $object["table"]); |
124 | | - $tableName_exploded[0] = $dc2; |
125 | | - $tableName = implode("_", $tableName_exploded); |
126 | | - $object["table"]=$tableName; |
127 | | - |
128 | | - CopyTools::dc_insert_assoc($dc2,"objects",$object); |
129 | | - return mysql_insert_id(); |
130 | | - } |
131 | | - |
132 | | - function dup() { |
133 | | - $this->read(); |
134 | | - $object2=$this->identical(); |
135 | | - if (CopyTools::sane_key_exists("object_id",$object2)) { |
136 | | - $this->already_there=true; |
137 | | - $newid=$object2["object_id"]; |
138 | | - } else { |
139 | | - $this->already_there=false; |
140 | | - $newid=$this->write(); |
141 | | - } |
142 | | - return $newid; |
143 | | - } |
144 | | -} |
145 | | - |
146 | | - |
147 | | -/** obtain an expression definition from the database |
148 | | - * @param $expression_id the id of the expression |
149 | | - * @param $dc1 dataset to READ expression FROM |
150 | | - */ |
151 | | -function expression($expression_id, $dc1) { |
152 | | - return CopyTools::getRow($dc1, "expression", "WHERE expression_id=$expression_id"); |
153 | | -} |
154 | | - |
155 | | - |
156 | | -function getOldSyntrans($dc1, $dmid, $expid) { |
157 | | - return CopyTools::getRow($dc1, "syntrans", "where defined_meaning_id=$dmid and expression_id=$expid"); |
158 | | -} |
159 | | - |
160 | | -function writeSyntrans($syntrans, $newdmid, $newexpid, $dc2) { |
161 | | - $syntrans["defined_meaning_id"]=$newdmid; |
162 | | - $syntrans["expression_id"]=$newexpid; |
163 | | - CopyTools::dc_insert_assoc($dc2,"syntrans",$syntrans); |
164 | | -} |
165 | | - |
166 | | -function dupSyntrans($dc1, $dc2, $olddmid, $oldexpid, $newdmid, $newexpid) { |
167 | | - $syntrans=getOldSyntrans($dc1, $olddmid, $oldexpid); |
168 | | - $copier=new ObjectCopier($syntrans["syntrans_sid"], $dc1, $dc2); |
169 | | - $newid=$copier->dup(); |
170 | | - if ($copier->already_there()) { |
171 | | - return; |
172 | | - } |
173 | | - $syntrans["syntrans_sid"]=$newid; |
174 | | - writeSyntrans($syntrans, $newdmid, $newexpid, $dc2); |
175 | | -} |
176 | | - |
177 | | -function get_syntranses($dmid, $dc1) { |
178 | | - return CopyTools::getRows($dc1, "syntrans", "where defined_meaning_id=$dmid"); |
179 | | -} |
180 | | - |
181 | | - |
182 | | -/* some coy&paste happening here, might want to tidy even before we |
183 | | -* toss this throwaway code*/ |
184 | | -function write_expression($expression, $src_dmid, $dst_dmid, $dc1, $dc2) { |
185 | | - |
186 | | - $copier=new ObjectCopier($expression["expression_id"], $dc1, $dc2); |
187 | | - $target_expid1=$copier->dup(); |
188 | | - $save_expression=$expression; |
189 | | - $save_expression["expression_id"]=$target_expid1; |
190 | | - if (!($copier->already_there())) { |
191 | | - CopyTools::dc_insert_assoc($dc2,"expression",$save_expression); |
192 | | - } |
193 | | - dupsyntrans( |
194 | | - $dc1, |
195 | | - $dc2, |
196 | | - $src_dmid, |
197 | | - $expression["expression_id"], |
198 | | - $dst_dmid, |
199 | | - $save_expression["expression_id"] |
200 | | - ); |
201 | | - |
202 | | -} |
203 | | - |
204 | | -function write_syntranses($syntranses, $src_dmid, $dst_dmid, $dc1, $dc2) { |
205 | | - var_dump($syntranses); |
206 | | - print "<br>\nExpressions:"; |
207 | | - foreach ($syntranses as $syntrans) { |
208 | | - $expression=expression($syntrans["expression_id"],$dc1); |
209 | | - print $expression["spelling"].";"; |
210 | | - write_expression($expression, $src_dmid, $dst_dmid, $dc1, $dc2); |
211 | | - # ^- which incidentally also dups the syntrans |
212 | | - } |
213 | | -} |
214 | | - |
215 | | -function dup_syntranses($src_dmid, $dst_dmid, $dc1, $dc2) { |
216 | | - $syntranses=get_syntranses($src_dmid, $dc1); |
217 | | - write_syntranses($syntranses, $src_dmid, $dst_dmid, $dc1, $dc2); |
218 | | -} |
219 | | - |
220 | | -function read_translated_content($dc1,$tcid) { |
221 | | - return CopyTools::getRows($dc1,"translated_content","where translated_content_id=$tcid"); |
222 | | -} |
223 | | - |
224 | | -function write_translated_content($dc1, $dc2, $tcid, $content) { |
225 | | - $content["translated_content_id"]=$tcid; |
226 | | - $content["text_id"]=dup_text($dc1, $dc2, $content["text_id"]); |
227 | | - var_dump($content); |
228 | | - CopyTools::dc_insert_assoc($dc2, "translated_content", $content); |
229 | | -} |
230 | | - |
231 | | - |
232 | | -function dup_translated_content($dc1, $dc2, $tcid) { |
233 | | - $translated_content=read_translated_content($dc1, $tcid); |
234 | | - $copier=new ObjectCopier($tcid, $dc1, $dc2); |
235 | | - $new_tcid=$copier->dup(); |
236 | | - # note the issue where translated content is added later: |
237 | | - # since all translated content for a single dm |
238 | | - # shares one UUID, we can't check for that eventuality. |
239 | | - if ($copier->already_there()) { |
240 | | - return; |
241 | | - } |
242 | | - foreach ($translated_content as $item) { |
243 | | - write_translated_content($dc1, $dc2, $new_tcid, $item); |
244 | | - } |
245 | | - return $new_tcid; |
246 | | -} |
247 | | - |
248 | | -function read_text($dc1,$text_id) { |
249 | | - return CopyTools::getRow($dc1,"text","where text_id=$text_id"); |
250 | | -} |
251 | | - |
252 | | -function write_text($dc2,$text) { |
253 | | - unset($text["text_id"]); |
254 | | - # inconsistent, insert_assoc should accept dc, table |
255 | | - $target_table=mysql_real_escape_string("${dc2}_text"); |
256 | | - CopyTools::dc_insert_assoc($dc2, "text", $text); |
257 | | - return mysql_insert_id(); |
258 | | -} |
259 | | - |
260 | | -function dup_text($dc1, $dc2, $text_id) { |
261 | | - $text=read_text($dc1, $text_id); |
262 | | - $id=write_text($dc2, $text); |
263 | | - return $id; |
264 | | -} |
265 | | - |
266 | | -class RelationsCopier { |
267 | | - |
268 | | - protected $old_dmid; |
269 | | - protected $new_dmid; |
270 | | - protected $dc1; |
271 | | - protected $dc2; |
272 | | - |
273 | | - function __construct($dc1, $dc2, $old_dmid, $new_dmid) { |
274 | | - $this->old_dmid=$old_dmid; |
275 | | - $this->new_dmid=$new_dmid; |
276 | | - $this->dc1=$dc1; |
277 | | - $this->dc2=$dc2; |
278 | | - } |
279 | | - |
280 | | - function read() { |
281 | | - $dc1=$this->dc1; |
282 | | - $dmid=$this->old_dmid; |
283 | | - return CopyTools::getRows($dc1,"meaning_relations","where meaning1_mid=$dmid"); |
284 | | - } |
285 | | - |
286 | | - function write_single($relation) { |
287 | | - var_dump($relation); |
288 | | - $dc1=$this->dc1; |
289 | | - $dc2=$this->dc2; |
290 | | - $new_dmid=$this->new_dmid; |
291 | | - |
292 | | - $copier=new ObjectCopier($relation["relation_id"], $dc1, $dc2); |
293 | | - $relation["relation_id"]=$copier->dup(); |
294 | | - if ($copier->already_there()) { |
295 | | - return; |
296 | | - } |
297 | | - $relation["meaning1_mid"]=$new_dmid; |
298 | | - $dmcopier=new DefinedMeaningCopier($relation["meaning2_mid"],$dc1, $dc2); |
299 | | - $relation["meaning2_mid"]=$dmcopier->dup_stub(); |
300 | | - # Typically checks same values each time. Accelerated by query_cache: |
301 | | - $rtcopier=new DefinedMeaningCopier($relation["relationtype_mid"],$dc1, $dc2); |
302 | | - $relation["relationtype_mid"]=$rtcopier->dup_stub(); |
303 | | - var_dump($relation); |
304 | | - $copier=new ObjectCopier($relation["relation_id"], $dc1, $dc2); |
305 | | - $relation["relation_id"]=$copier->dup(); |
306 | | - if ($copier->already_there()) { |
307 | | - return; |
308 | | - } |
309 | | - CopyTools::dc_insert_assoc($dc2,"meaning_relations",$relation); |
310 | | - |
311 | | - } |
312 | | - |
313 | | - function dup() { |
314 | | - $rows=$this->read(); |
315 | | - echo "copying relations"; |
316 | | - foreach ($rows as $row) { |
317 | | - $this->write_single($row); |
318 | | - } |
319 | | - } |
320 | | -} |
321 | | - |
322 | | -class CollectionCopier { |
323 | | - protected $dmid; |
324 | | - protected $save_dmid; |
325 | | - protected $dc1; |
326 | | - protected $dc2; |
327 | | - protected $already_there=false; |
328 | | - |
329 | | - public function already_there() { |
330 | | - return $this->already_there; |
331 | | - } |
332 | | - |
333 | | - public function __construct ($dc1, $dc2, $dmid, $save_dmid) { |
334 | | - $this->dmid=$dmid; |
335 | | - $this->save_dmid=$save_dmid; |
336 | | - $this->dc1=$dc1; |
337 | | - $this->dc2=$dc2; |
338 | | - } |
339 | | - |
340 | | - public function read($dc=Null){ |
341 | | - if (is_null($dc)) { |
342 | | - $dc=$this->dc1; |
343 | | - } |
344 | | - $dmid=$this->dmid; |
345 | | - return CopyTools::getRows($dc, "collection_contents", "WHERE member_mid=$dmid"); |
346 | | - } |
347 | | - |
348 | | - |
349 | | - public function read_definition($collection_id) { |
350 | | - $dc1=$this->dc1; |
351 | | - return CopyTools::getRow($dc1,"collection","WHERE collection_id=$collection_id"); |
352 | | - } |
353 | | - |
354 | | - /** write collection definition (and associated dm) to dc2 |
355 | | - * if it doesn't already exist. |
356 | | - * If it already exists, will only look up the id. |
357 | | - * returns the id for dc2 either way. |
358 | | - */ |
359 | | - public function write_definition($definition){ |
360 | | - $dc1=$this->dc1; |
361 | | - $dc2=$this->dc2; |
362 | | - |
363 | | - print "<br>\nCopying collection</br>"; |
364 | | - var_dump($definition); |
365 | | - print $definition["collection_id"]; |
366 | | - $objcopier=new ObjectCopier($definition["collection_id"], $dc1, $dc2); |
367 | | - $definition["collection_id"]=$objcopier->dup(); |
368 | | - if (!$objcopier->already_there()) { |
369 | | - $dmid= $definition["collection_mid"]; |
370 | | - $dmcopier=new DefinedMeaningCopier($dmid,$dc1,$dc2); |
371 | | - $definition["collection_mid"]=$dmcopier->dup_stub(); |
372 | | - |
373 | | - CopyTools::dc_insert_assoc($dc2, "collection", $definition); |
374 | | - |
375 | | - } |
376 | | - return $definition["collection_id"]; |
377 | | - |
378 | | - } |
379 | | - |
380 | | - /** look up the collection definition in %_collection, |
381 | | - * and copy if doesn't already exist in dc2 |
382 | | - */ |
383 | | - public function dup_definition($collection_id) { |
384 | | - $definition=$this->read_definition($collection_id); |
385 | | - return $this->write_definition($definition); |
386 | | - } |
387 | | - |
388 | | - |
389 | | - # we create a mapping and THEN do collections, now we need to prevent ourselves dupping |
390 | | - # existing mappings |
391 | | - public function existing_mapping($member_id) { |
392 | | - $dc2=$this->dc2; |
393 | | - $query="SELECT ${dc2}_collection_contents.* FROM ${dc2}_collection_contents, ${dc2}_collection |
394 | | - WHERE ${dc2}_collection_contents.collection_id = ${dc2}_collection.collection_id |
395 | | - AND collection_type=\"MAPP\" |
396 | | - AND internal_member_id=\"${member_id}\""; |
397 | | - $mapping_here=CopyTools::doQuery($query); |
398 | | - |
399 | | - if ($mapping_here==false) |
400 | | - return false; |
401 | | - else |
402 | | - return true; # if anything is actually returned, we know the score. |
403 | | - } |
404 | | - |
405 | | - |
406 | | - /** write a single collection_contents row, |
407 | | - * (if the collection doesn't exist yet), also dup the definition |
408 | | - */ |
409 | | - public function write_single($row){ |
410 | | - $dc2=$this->dc2; |
411 | | - $save_dmid=$this->save_dmid; |
412 | | - $row["collection_id"]=$this->dup_definition($row["collection_id"]); |
413 | | - |
414 | | - if ( $this->existing_mapping($row["internal_member_id"]) ) |
415 | | - return; |
416 | | - |
417 | | - $row["member_mid"]=$save_dmid; |
418 | | - CopyTools::dc_insert_assoc($dc2, "collection_contents", $row); |
419 | | - } |
420 | | - |
421 | | - public function write($rows){ |
422 | | - foreach ($rows as $row) { |
423 | | - $this->write_single($row); |
424 | | - } |
425 | | - } |
426 | | - |
427 | | - /** writes a duplicate. does *NOT* return ids on return, as there |
428 | | - * are multiple ids |
429 | | - */ |
430 | | - public function dup() { |
431 | | - # Is there something already there? If so, do not dup. |
432 | | - $checkrows=$this->read($this->dc2); |
433 | | - foreach ($checkrows as $row) { |
434 | | - if ($row["member_mid"]==$this->save_dmid){ |
435 | | - $this->already_there=true; |
436 | | - return; |
437 | | - } |
438 | | - } |
439 | | - |
440 | | - #seems ok, let's dup. |
441 | | - $rows=$this->read($this->dc1); |
442 | | - $this->write($rows); |
443 | | - } |
444 | | -} |
445 | | - |
446 | | - |
447 | | -class DefinedMeaningCopier { |
448 | | - |
449 | | - protected $defined_meaning; |
450 | | - protected $save_meaning; |
451 | | - protected $dmid; |
452 | | - protected $dc1; |
453 | | - protected $dc2; |
454 | | - protected $already_there=false; |
455 | | - |
456 | | - public function __construct ($dmid, $dc1, $dc2) { |
457 | | - $this->dmid=$dmid; |
458 | | - $this->dc1=$dc1; |
459 | | - $this->dc2=$dc2; |
460 | | - } |
461 | | - |
462 | | - protected function read() { |
463 | | - $dmid=$this->dmid; |
464 | | - print "<".$dmid."-".$this->dc1.">"; |
465 | | - $this->defined_meaning=CopyTools::getRow($this->dc1,"defined_meaning","where defined_meaning_id=$dmid"); |
466 | | - return $this->defined_meaning; # for convenience |
467 | | - } |
468 | | - |
469 | | - |
470 | | - public function getDM() { |
471 | | - $dm=$this->defined_meaning; |
472 | | - if (is_null($dm)) { |
473 | | - $dm=$this->read(); |
474 | | - } |
475 | | - return $this->defined_meaning; |
476 | | - } |
477 | | - |
478 | | - public function already_there() { |
479 | | - return $this->already_there; |
480 | | - } |
481 | | - |
482 | | - public function dup() { |
483 | | - $this->dup_stub(); |
484 | | - $this->dup_rest(); |
485 | | - return $this->save_meaning["defined_meaning_id"]; |
486 | | - } |
487 | | - |
488 | | - public function dup_stub (){ |
489 | | - $dmid=$this->dmid; |
490 | | - $dc1=$this->dc1; |
491 | | - $dc2=$this->dc2; |
492 | | - |
493 | | - echo "<br><h3>copying dm $dmid</h3><br>\n"; |
494 | | - $this->read(); |
495 | | - |
496 | | - # bit of exp here too (defnitely need to tidy) |
497 | | - $defining_expression=expression($this->defined_meaning["expression_id"], $dc1); |
498 | | - $dm_target_table=mysql_real_escape_string("${dc2}_defined_meaning"); |
499 | | - $copier=new ObjectCopier($this->defined_meaning["defined_meaning_id"], $dc1, $dc2); |
500 | | - $target_dmid=$copier->dup(); |
501 | | - var_dump($target_dmid); |
502 | | - $this->save_meaning=$this->defined_meaning; |
503 | | - $this->save_meaning["defined_meaning_id"]=$target_dmid; |
504 | | - |
505 | | - $this->already_there=$copier->already_there(); |
506 | | - if (!($copier->already_there())) { |
507 | | - # exp |
508 | | - $target_table=mysql_real_escape_string("${dc2}_expression"); |
509 | | - $exp_copier=new ObjectCopier($defining_expression["expression_id"], $dc1, $dc2); |
510 | | - $target_expid1=$exp_copier->dup(); |
511 | | - var_dump($target_expid1); |
512 | | - $save_expression=$defining_expression; |
513 | | - $save_expression["expression_id"]=$target_expid1; |
514 | | - CopyTools::dc_insert_assoc($dc2, "expression", $save_expression); |
515 | | - # and insert that info into the dm |
516 | | - $this->save_meaning["expression_id"]=$target_expid1; |
517 | | - } |
518 | | - $this->save_meaning["meaning_text_tcid"]=dup_translated_content($dc1, $dc2, $this->defined_meaning["meaning_text_tcid"]); |
519 | | - |
520 | | - if (!($copier->already_there())) { |
521 | | - CopyTools::dc_insert_assoc($dc2, "defined_meaning", $this->save_meaning); |
522 | | - |
523 | | - $title_name=$defining_expression["spelling"]; |
524 | | - $title_number=$target_dmid; |
525 | | - $title=str_replace(" ","_",$title_name)."_(".$title_number.")"; |
526 | | - CopyTools::createPage($title); |
527 | | - |
528 | | - $concepts=array( |
529 | | - $dc1 => $this->defined_meaning["defined_meaning_id"], |
530 | | - $dc2 => $this->save_meaning["defined_meaning_id"]); |
531 | | - createConceptMapping($concepts); |
532 | | - } |
533 | | - |
534 | | - return $this->save_meaning["defined_meaning_id"]; |
535 | | - } |
536 | | - |
537 | | - function dup_rest() { |
538 | | - $dmid=$this->dmid; |
539 | | - $dc1=$this->dc1; |
540 | | - $dc2=$this->dc2; |
541 | | - dup_syntranses( |
542 | | - $this->defined_meaning["defined_meaning_id"], |
543 | | - $this->save_meaning["defined_meaning_id"], |
544 | | - $dc1, |
545 | | - $dc2 |
546 | | - ); |
547 | | - |
548 | | - $relationsCopier=new RelationsCopier( |
549 | | - $dc1, |
550 | | - $dc2, |
551 | | - $this->defined_meaning["defined_meaning_id"], |
552 | | - $this->save_meaning["defined_meaning_id"]); |
553 | | - $relationsCopier->dup(); |
554 | | - |
555 | | - # can't merge collections, since they're not entirely covered by |
556 | | - # the objects table. So we don't copy them more than once. |
557 | | - if (!$this->already_there()) { |
558 | | - $collectionCopier=new CollectionCopier( |
559 | | - $dc1, |
560 | | - $dc2, |
561 | | - $this->defined_meaning["defined_meaning_id"], |
562 | | - $this->save_meaning["defined_meaning_id"]); |
563 | | - $collectionCopier->dup(); |
564 | | - } |
565 | | - |
566 | | - } |
567 | | -} |
568 | | - |
569 | | -/** provide a namespace for copying tools (so we don't clutter up the main namespace with |
570 | | - * all our utility and tool functions) All functions here are public+static. |
571 | | - */ |
572 | | -class CopyTools { |
573 | | - /** create a relevant entry in the `page` table. */ |
574 | | - public static function createPage($title) { |
575 | | - # page is not a Wikidata table, so it needs to be treated differently (yet again :-/) |
576 | | - $escTitle=mysql_real_escape_string($title); |
577 | | - $existing_page_data=CopyTools::doQuery("SELECT * FROM page WHERE page_namespace=24 AND page_title=\"$escTitle\""); |
578 | | - print "<br>PAGE COUNT: ".count($existing_page_data)."<br>\n"; |
579 | | - if ($existing_page_data==false) { |
580 | | - $pagedata=array("page_namespace"=>24, "page_title"=>$title); |
581 | | - CopyTools::mysql_insert_assoc("page",$pagedata); |
582 | | - } |
583 | | - } |
584 | | - |
585 | | - /** Times our execution time, nifty! */ |
586 | | - public static function stopwatch(){ |
587 | | - list($usec, $sec) = explode(" ", microtime()); |
588 | | - return ((float)$usec + (float)$sec); |
589 | | - } |
590 | | - |
591 | | - /** start a new copy transaction |
592 | | - * Gets a virtual user id from the wikidata_sets table, if available |
593 | | - * (else uses user 0) |
594 | | - * There's still some issues with transactions especially wrt with user assignment |
595 | | - * where we intersect with the (old) "WikiDataAPI". |
596 | | - */ |
597 | | - public static function newCopyTransaction($dc1, $dc2) { |
598 | | - |
599 | | - $datasets=CopyTools::getRow_noDC("wikidata_sets", "WHERE set_prefix=\"$dc2\""); |
600 | | - if ( $datasets == false ) { |
601 | | - throw new Exception("Dataset info for $dc2 not found."); |
602 | | - } |
603 | | - |
604 | | - if ( array_key_exists("virtual_user_id", $datasets) ) { |
605 | | - $virtual_user_id=$datasets["virtual_user_id"]; |
606 | | - } else { |
607 | | - $virtual_user_id=0; |
608 | | - } |
609 | | - |
610 | | - print " VUID: $virtual_user_id"; |
611 | | - startNewTransaction( |
612 | | - $virtual_user_id, |
613 | | - "0.0.0.0", |
614 | | - "copying from $dc1 to $dc2", |
615 | | - $dc2 ); |
616 | | - print " UTID: ".getUpdateTransactionId(); |
617 | | - } |
618 | | - |
619 | | - /** retrieve a single row from the database as an associative array |
620 | | - * @param $dc the dataset prefix we need |
621 | | - * @param $table the name of the table (minus dataset prefix) |
622 | | - * @peram $where the actual WHERE clause we need to uniquely find our row |
623 | | - * @returns an associative array, representing our row. \ |
624 | | - * keys=column headers, values = row contents |
625 | | - */ |
626 | | - public static function getRow($dc, $table, $where) { |
627 | | - $target_table=mysql_real_escape_string("${dc}_${table}"); |
628 | | - $query="SELECT * FROM $target_table ".$where; |
629 | | - return CopyTools::doQuery($query); |
630 | | - } |
631 | | - |
632 | | - public static function getRow_noDC($table, $where) { |
633 | | - $target_table=mysql_real_escape_string("${table}"); |
634 | | - $query="SELECT * FROM $target_table ".$where; |
635 | | - return CopyTools::doQuery($query); |
636 | | - } |
637 | | - |
638 | | - /** retrieve multiple rows from the database, as an array of associative arrays. |
639 | | - * @param $dc the dataset prefix we need |
640 | | - * @param $table the name of the table (minus dataset prefix) |
641 | | - * @peram $where the actual WHERE clause we need to uniquely find our row |
642 | | - * @returns an array of associative arrays, representing our rows. \ |
643 | | - * each associative array is structured with: \ |
644 | | - * keys=column headers, values = row contents |
645 | | - */ |
646 | | - public static function getRows($dc, $table, $where) { |
647 | | - $target_table=mysql_real_escape_string("${dc}_${table}"); |
648 | | - $query="SELECT * FROM $target_table ".$where; |
649 | | - return CopyTools::doMultirowQuery($query); |
650 | | - } |
651 | | - |
652 | | - |
653 | | - /** Performs an arbitrary SQL query and returns an associative array |
654 | | - * Assumes that only 1 row can be returned! |
655 | | - * @param $query a valid SQL query |
656 | | - * @returns an associative array, representing our row. \ |
657 | | - * keys=column headers, values = row contents |
658 | | - * |
659 | | - */ |
660 | | - public static function doQuery($query) { |
661 | | - echo $query; |
662 | | - $result = mysql_query($query)or die ("error ".mysql_error()); |
663 | | - $data= mysql_fetch_assoc($result); |
664 | | - return $data; |
665 | | - } |
666 | | - /** Perform an arbitrary SQL query |
667 | | - * |
668 | | - * @param $query a valid SQL query |
669 | | - * @returns an array of associative arrays, representing our rows. \ |
670 | | - * each associative array is structured with: \ |
671 | | - * keys=column headers, values = row contents |
672 | | - */ |
673 | | - |
674 | | - public static function doMultirowQuery($query) { |
675 | | - $result = mysql_query($query)or die ("error ".mysql_error()); |
676 | | - $items=array(); |
677 | | - while ($nextexp=mysql_fetch_assoc($result)) { |
678 | | - $items[]=$nextexp; |
679 | | - } |
680 | | - return $items; |
681 | | - } |
682 | | - |
683 | | - /** identical to the php function array_key_exists(), but eats dirtier input |
684 | | - * returns false (rather than an error) on somewhat invalid input |
685 | | - */ |
686 | | - public static function sane_key_exists($key, $array) { |
687 | | - if (is_null($key) or $key==false){ |
688 | | - return false; |
689 | | - } |
690 | | - if (is_null($array) or $array==false) { |
691 | | - return false; |
692 | | - } |
693 | | - var_dump($array); |
694 | | - return array_key_exists($key, $array); |
695 | | - } |
696 | | - |
697 | | - /** |
698 | | - * inverse of mysql_fetch_assoc |
699 | | - * takes an associative array as parameter, and inserts data |
700 | | - * into table as a single row (keys=column names, values = data to be inserted) |
701 | | - /* see: http://www.php.net/mysql_fetch_assoc (Comment by R. Bradly, 14-Sep-2006) |
702 | | - */ |
703 | | - public static function mysql_insert_assoc ($my_table, $my_array) { |
704 | | - |
705 | | - // Find all the keys (column names) from the array $my_array |
706 | | - |
707 | | - // We compose the query |
708 | | - $sql = "insert into `$my_table` set"; |
709 | | - // implode the column names, inserting "\", \"" between each (but not after the last one) |
710 | | - // we add the enclosing quotes at the same time |
711 | | - $sql_comma=$sql; |
712 | | - foreach($my_array as $key=>$value) { |
713 | | - $sql=$sql_comma; |
714 | | - if (is_null($value)) { |
715 | | - $value="DEFAULT"; |
716 | | - } else { |
717 | | - $value="\"$value\""; |
718 | | - } |
719 | | - $sql.=" `$key`=$value"; |
720 | | - $sql_comma=$sql.","; |
721 | | - } |
722 | | - // Same with the values |
723 | | - echo $sql."; <br>\n"; |
724 | | - $result = mysql_query($sql); |
725 | | - |
726 | | - if ($result) |
727 | | - { |
728 | | - echo "The row was added sucessfully"; |
729 | | - return true; |
730 | | - } |
731 | | - else |
732 | | - { |
733 | | - echo ("The row was not added<br>The error was" . mysql_error()); |
734 | | - return false; |
735 | | - } |
736 | | - } |
737 | | - |
738 | | - /**convenience wrapper around mysql_insert_assoc |
739 | | - * like mysql_insert_assoc, but allows you to specify dc prefix+table name separately |
740 | | - * Also transparently handles the internal transaction (WHICH MUST ALREADY BE OPEN!) |
741 | | - */ |
742 | | - public static function dc_insert_assoc($dc, $table_name, $array) { |
743 | | - $target_table=mysql_real_escape_string("${dc}_${table_name}"); |
744 | | - if (CopyTools::sane_key_exists("add_transaction_id", $array)) { |
745 | | - $array["add_transaction_id"]=getUpdateTransactionId(); |
746 | | - } |
747 | | - return CopyTools::mysql_insert_assoc($target_table, $array); |
748 | | - } |
749 | | - |
750 | | - |
751 | | -} |
752 | | - |
753 | | - |
754 | | -$start=CopyTools::stopwatch(); |
755 | | - |
756 | | -$dmid_dirty=$_REQUEST['dmid']; |
757 | | -$dc1_dirty=$_REQUEST['dc1']; |
758 | | -$dc2_dirty=$_REQUEST['dc2']; |
759 | | - |
760 | | -$dmid=mysql_real_escape_string($dmid_dirty); |
761 | | -$dc1=mysql_real_escape_string($dc1_dirty); |
762 | | -$dc2=mysql_real_escape_string($dc2_dirty); |
763 | | - |
764 | | -CopyTools::newCopyTransaction($dc1, $dc2); |
765 | | -$dmc=new DefinedMeaningCopier($dmid, $dc1, $dc2); #sorry, not a [[delorean]] |
766 | | -$dmc->dup(); |
767 | | - |
768 | | -mysql_query("COMMIT"); # Ok, that should not be nescesaty |
769 | | - # but on wikiproteins it is? |
770 | | - |
771 | | - |
772 | | - |
773 | | -echo" |
774 | | -<hr> |
775 | | -<div align=\"right\"> |
776 | | -<small>Page time: ".substr((CopyTools::stopwatch()-$start),0,5)." seconds</small> |
777 | | -</div> |
778 | | -"; |
779 | | - |
780 | | -?> |