Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1798 lines
83 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <?php
  2. use Friendica\Core\Config;
  3. require_once("boot.php");
  4. require_once("include/text.php");
  5. define('NEW_UPDATE_ROUTINE_VERSION', 1170);
  6. /*
  7. * Converts all tables from MyISAM to InnoDB
  8. */
  9. function convert_to_innodb() {
  10. global $db;
  11. $r = q("SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `engine` = 'MyISAM' AND `table_schema` = '%s'",
  12. dbesc($db->database_name()));
  13. if (!dbm::is_result($r)) {
  14. echo t('There are no tables on MyISAM.')."\n";
  15. return;
  16. }
  17. foreach ($r AS $table) {
  18. $sql = sprintf("ALTER TABLE `%s` engine=InnoDB;", dbesc($table['TABLE_NAME']));
  19. echo $sql."\n";
  20. $result = @$db->q($sql);
  21. if (!dbm::is_result($result)) {
  22. print_update_error($db, $sql);
  23. }
  24. }
  25. }
  26. /*
  27. * send the email and do what is needed to do on update fails
  28. *
  29. * @param update_id (int) number of failed update
  30. * @param error_message (str) error message
  31. */
  32. function update_fail($update_id, $error_message) {
  33. //send the administrators an e-mail
  34. $admin_mail_list = "'".implode("','", array_map(dbesc, explode(",", str_replace(" ", "", $a->config['admin_email']))))."'";
  35. $adminlist = q("SELECT uid, language, email FROM user WHERE email IN (%s)",
  36. $admin_mail_list
  37. );
  38. // No valid result?
  39. if (!dbm::is_result($adminlist)) {
  40. logger(sprintf('Cannot notify administrators about update_id=%d, error_message=%s', $update_id, $error_message), LOGGER_WARNING);
  41. // Don't continue
  42. return;
  43. }
  44. // every admin could had different language
  45. foreach ($adminlist as $admin) {
  46. $lang = (($admin['language'])?$admin['language']:'en');
  47. push_lang($lang);
  48. $preamble = deindent(t("
  49. The friendica developers released update %s recently,
  50. but when I tried to install it, something went terribly wrong.
  51. This needs to be fixed soon and I can't do it alone. Please contact a
  52. friendica developer if you can not help me on your own. My database might be invalid."));
  53. $body = t("The error message is\n[pre]%s[/pre]");
  54. $preamble = sprintf($preamble, $update_id);
  55. $body = sprintf($body, $error_message);
  56. notification(array(
  57. 'type' => "SYSTEM_EMAIL",
  58. 'to_email' => $admin['email'],
  59. 'preamble' => $preamble,
  60. 'body' => $body,
  61. 'language' => $lang,
  62. ));
  63. }
  64. /*
  65. $email_tpl = get_intltext_template("update_fail_eml.tpl");
  66. $email_msg = replace_macros($email_tpl, array(
  67. '$sitename' => $a->config['sitename'],
  68. '$siteurl' => App::get_baseurl(),
  69. '$update' => DB_UPDATE_VERSION,
  70. '$error' => sprintf(t('Update %s failed. See error logs.'), DB_UPDATE_VERSION)
  71. ));
  72. $subject=sprintf(t('Update Error at %s'), App::get_baseurl());
  73. require_once('include/email.php');
  74. $subject = email_header_encode($subject,'UTF-8');
  75. mail($a->config['admin_email'], $subject, $email_msg,
  76. 'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME']."\n"
  77. .'Content-type: text/plain; charset=UTF-8'."\n"
  78. .'Content-transfer-encoding: 8bit');
  79. */
  80. //try the logger
  81. logger("CRITICAL: Database structure update failed: ".$retval);
  82. }
  83. function table_structure($table) {
  84. $structures = q("DESCRIBE `%s`", $table);
  85. $full_columns = q("SHOW FULL COLUMNS FROM `%s`", $table);
  86. $indexes = q("SHOW INDEX FROM `%s`", $table);
  87. $table_status = q("SHOW TABLE STATUS WHERE `name` = '%s'", $table);
  88. if (dbm::is_result($table_status)) {
  89. $table_status = $table_status[0];
  90. } else {
  91. $table_status = array();
  92. }
  93. $fielddata = array();
  94. $indexdata = array();
  95. if (dbm::is_result($indexes))
  96. foreach ($indexes AS $index) {
  97. if ($index['Key_name'] != 'PRIMARY' && $index['Non_unique'] == '0' && !isset($indexdata[$index["Key_name"]])) {
  98. $indexdata[$index["Key_name"]] = array('UNIQUE');
  99. }
  100. $column = $index["Column_name"];
  101. // On utf8mb4 a varchar index can only have a length of 191
  102. // The "show index" command sometimes returns this value although this value wasn't added manually.
  103. // Because we don't want to add this number to every index, we ignore bigger numbers
  104. if (($index["Sub_part"] != "") AND (($index["Sub_part"] < 191) OR ($index["Key_name"] == "PRIMARY"))) {
  105. $column .= "(".$index["Sub_part"].")";
  106. }
  107. $indexdata[$index["Key_name"]][] = $column;
  108. }
  109. if (dbm::is_result($structures)) {
  110. foreach ($structures AS $field) {
  111. $fielddata[$field["Field"]]["type"] = $field["Type"];
  112. if ($field["Null"] == "NO") {
  113. $fielddata[$field["Field"]]["not null"] = true;
  114. }
  115. if (isset($field["Default"])) {
  116. $fielddata[$field["Field"]]["default"] = $field["Default"];
  117. }
  118. if ($field["Extra"] != "") {
  119. $fielddata[$field["Field"]]["extra"] = $field["Extra"];
  120. }
  121. if ($field["Key"] == "PRI") {
  122. $fielddata[$field["Field"]]["primary"] = true;
  123. }
  124. }
  125. }
  126. if (dbm::is_result($full_columns)) {
  127. foreach ($full_columns AS $column) {
  128. $fielddata[$column["Field"]]["Collation"] = $column["Collation"];
  129. }
  130. }
  131. return array("fields" => $fielddata, "indexes" => $indexdata, "table_status" => $table_status);
  132. }
  133. function print_structure($database) {
  134. echo "-- ------------------------------------------\n";
  135. echo "-- ".FRIENDICA_PLATFORM." ".FRIENDICA_VERSION." (".FRIENDICA_CODENAME,")\n";
  136. echo "-- DB_UPDATE_VERSION ".DB_UPDATE_VERSION."\n";
  137. echo "-- ------------------------------------------\n\n\n";
  138. foreach ($database AS $name => $structure) {
  139. echo "--\n";
  140. echo "-- TABLE $name\n";
  141. echo "--\n";
  142. db_create_table($name, $structure['fields'], true, false, $structure["indexes"]);
  143. echo "\n";
  144. }
  145. }
  146. /**
  147. * @brief Print out database error messages
  148. *
  149. * @param object $db Database object
  150. * @param string $message Message to be added to the error message
  151. *
  152. * @return string Error message
  153. */
  154. function print_update_error($db, $message) {
  155. echo sprintf(t("\nError %d occurred during database update:\n%s\n"),
  156. $db->errorno, $db->error);
  157. return t('Errors encountered performing database changes: ').$message.EOL;
  158. }
  159. function update_structure($verbose, $action, $tables=null, $definition=null) {
  160. global $a, $db;
  161. if ($action) {
  162. Config::set('system', 'maintenance', 1);
  163. Config::set('system', 'maintenance_reason', sprintf(t(': Database update'), dbm::date().' '.date('e')));
  164. }
  165. $errors = false;
  166. logger('updating structure', LOGGER_DEBUG);
  167. // Get the current structure
  168. $database = array();
  169. if (is_null($tables)) {
  170. $tables = q("SHOW TABLES");
  171. }
  172. if (dbm::is_result($tables)) {
  173. foreach ($tables AS $table) {
  174. $table = current($table);
  175. logger(sprintf('updating structure for table %s ...', $table), LOGGER_DEBUG);
  176. $database[$table] = table_structure($table);
  177. }
  178. }
  179. // Get the definition
  180. if (is_null($definition)) {
  181. $definition = db_definition();
  182. }
  183. // MySQL >= 5.7.4 doesn't support the IGNORE keyword in ALTER TABLE statements
  184. if ((version_compare($db->server_info(), '5.7.4') >= 0) AND
  185. !(strpos($db->server_info(), 'MariaDB') !== false)) {
  186. $ignore = '';
  187. } else {
  188. $ignore = ' IGNORE';
  189. }
  190. // Compare it
  191. foreach ($definition AS $name => $structure) {
  192. $is_new_table = False;
  193. $group_by = "";
  194. $sql3 = "";
  195. if (!isset($database[$name])) {
  196. $r = db_create_table($name, $structure["fields"], $verbose, $action, $structure['indexes']);
  197. if (!dbm::is_result($r)) {
  198. $errors .= print_update_error($db, $name);
  199. }
  200. $is_new_table = True;
  201. } else {
  202. $is_unique = false;
  203. $temp_name = $name;
  204. foreach ($structure["indexes"] AS $indexname => $fieldnames) {
  205. if (isset($database[$name]["indexes"][$indexname])) {
  206. $current_index_definition = implode(",",$database[$name]["indexes"][$indexname]);
  207. } else {
  208. $current_index_definition = "__NOT_SET__";
  209. }
  210. $new_index_definition = implode(",",$fieldnames);
  211. if ($current_index_definition != $new_index_definition) {
  212. if ($fieldnames[0] == "UNIQUE") {
  213. $is_unique = true;
  214. if ($ignore == "") {
  215. $temp_name = "temp-".$name;
  216. }
  217. }
  218. }
  219. }
  220. /*
  221. * Drop the index if it isn't present in the definition
  222. * or the definition differ from current status
  223. * and index name doesn't start with "local_"
  224. */
  225. foreach ($database[$name]["indexes"] as $indexname => $fieldnames) {
  226. $current_index_definition = implode(",",$fieldnames);
  227. if (isset($structure["indexes"][$indexname])) {
  228. $new_index_definition = implode(",",$structure["indexes"][$indexname]);
  229. } else {
  230. $new_index_definition = "__NOT_SET__";
  231. }
  232. if ($current_index_definition != $new_index_definition && substr($indexname, 0, 6) != 'local_') {
  233. $sql2=db_drop_index($indexname);
  234. if ($sql3 == "") {
  235. $sql3 = "ALTER".$ignore." TABLE `".$temp_name."` ".$sql2;
  236. } else {
  237. $sql3 .= ", ".$sql2;
  238. }
  239. }
  240. }
  241. // Compare the field structure field by field
  242. foreach ($structure["fields"] AS $fieldname => $parameters) {
  243. if (!isset($database[$name]["fields"][$fieldname])) {
  244. $sql2=db_add_table_field($fieldname, $parameters);
  245. if ($sql3 == "") {
  246. $sql3 = "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
  247. } else {
  248. $sql3 .= ", ".$sql2;
  249. }
  250. } else {
  251. // Compare the field definition
  252. $field_definition = $database[$name]["fields"][$fieldname];
  253. // Remove the relation data that is used for the referential integrity
  254. unset($parameters['relation']);
  255. // We change the collation after the indexes had been changed.
  256. // This is done to avoid index length problems.
  257. // So here we always ensure that there is no need to change it.
  258. unset($parameters['Collation']);
  259. unset($field_definition['Collation']);
  260. $current_field_definition = implode(",", $field_definition);
  261. $new_field_definition = implode(",", $parameters);
  262. if ($current_field_definition != $new_field_definition) {
  263. $sql2 = db_modify_table_field($fieldname, $parameters);
  264. if ($sql3 == "") {
  265. $sql3 = "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
  266. } else {
  267. $sql3 .= ", ".$sql2;
  268. }
  269. }
  270. }
  271. }
  272. }
  273. /*
  274. * Create the index if the index don't exists in database
  275. * or the definition differ from the current status.
  276. * Don't create keys if table is new
  277. */
  278. if (!$is_new_table) {
  279. foreach ($structure["indexes"] AS $indexname => $fieldnames) {
  280. if (isset($database[$name]["indexes"][$indexname])) {
  281. $current_index_definition = implode(",",$database[$name]["indexes"][$indexname]);
  282. } else {
  283. $current_index_definition = "__NOT_SET__";
  284. }
  285. $new_index_definition = implode(",",$fieldnames);
  286. if ($current_index_definition != $new_index_definition) {
  287. $sql2 = db_create_index($indexname, $fieldnames);
  288. // Fetch the "group by" fields for unique indexes
  289. if ($fieldnames[0] == "UNIQUE") {
  290. $group_by = db_group_by($indexname, $fieldnames);
  291. }
  292. if ($sql2 != "") {
  293. if ($sql3 == "") {
  294. $sql3 = "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
  295. } else {
  296. $sql3 .= ", ".$sql2;
  297. }
  298. }
  299. }
  300. }
  301. if (isset($database[$name]["table_status"]["Collation"])) {
  302. if ($database[$name]["table_status"]["Collation"] != 'utf8mb4_general_ci') {
  303. $sql2 = "DEFAULT COLLATE utf8mb4_general_ci";
  304. if ($sql3 == "") {
  305. $sql3 = "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
  306. } else {
  307. $sql3 .= ", ".$sql2;
  308. }
  309. }
  310. }
  311. if ($sql3 != "") {
  312. $sql3 .= "; ";
  313. }
  314. // Now have a look at the field collations
  315. // Compare the field structure field by field
  316. foreach ($structure["fields"] AS $fieldname => $parameters) {
  317. // Compare the field definition
  318. $field_definition = $database[$name]["fields"][$fieldname];
  319. // Define the default collation if not given
  320. if (!isset($parameters['Collation']) AND !is_null($field_definition['Collation'])) {
  321. $parameters['Collation'] = 'utf8mb4_general_ci';
  322. } else {
  323. $parameters['Collation'] = null;
  324. }
  325. if ($field_definition['Collation'] != $parameters['Collation']) {
  326. $sql2 = db_modify_table_field($fieldname, $parameters);
  327. if (($sql3 == "") OR (substr($sql3, -2, 2) == "; ")) {
  328. $sql3 .= "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
  329. } else {
  330. $sql3 .= ", ".$sql2;
  331. }
  332. }
  333. }
  334. }
  335. if ($sql3 != "") {
  336. if (substr($sql3, -2, 2) != "; ") {
  337. $sql3 .= ";";
  338. }
  339. if ($verbose) {
  340. // Ensure index conversion to unique removes duplicates
  341. if ($is_unique) {
  342. if ($ignore != "") {
  343. echo "SET session old_alter_table=1;\n";
  344. } else {
  345. echo "CREATE TABLE `".$temp_name."` LIKE `".$name."`;\n";
  346. }
  347. }
  348. echo $sql3."\n";
  349. if ($is_unique) {
  350. if ($ignore != "") {
  351. echo "SET session old_alter_table=0;\n";
  352. } else {
  353. echo "INSERT INTO `".$temp_name."` SELECT * FROM `".$name."`".$group_by.";\n";
  354. echo "DROP TABLE `".$name."`;\n";
  355. echo "RENAME TABLE `".$temp_name."` TO `".$name."`;\n";
  356. }
  357. }
  358. }
  359. if ($action) {
  360. Config::set('system', 'maintenance_reason', sprintf(t('%s: updating %s table.'), dbm::date().' '.date('e'), $name));
  361. // Ensure index conversion to unique removes duplicates
  362. if ($is_unique) {
  363. if ($ignore != "") {
  364. $db->q("SET session old_alter_table=1;");
  365. } else {
  366. $r = $db->q("CREATE TABLE `".$temp_name."` LIKE `".$name."`;");
  367. if (!dbm::is_result($r)) {
  368. $errors .= print_update_error($db, $sql3);
  369. return $errors;
  370. }
  371. }
  372. }
  373. $r = @$db->q($sql3);
  374. if (!dbm::is_result($r)) {
  375. $errors .= print_update_error($db, $sql3);
  376. }
  377. if ($is_unique) {
  378. if ($ignore != "") {
  379. $db->q("SET session old_alter_table=0;");
  380. } else {
  381. $r = $db->q("INSERT INTO `".$temp_name."` SELECT * FROM `".$name."`".$group_by.";");
  382. if (!dbm::is_result($r)) {
  383. $errors .= print_update_error($db, $sql3);
  384. return $errors;
  385. }
  386. $r = $db->q("DROP TABLE `".$name."`;");
  387. if (!dbm::is_result($r)) {
  388. $errors .= print_update_error($db, $sql3);
  389. return $errors;
  390. }
  391. $r = $db->q("RENAME TABLE `".$temp_name."` TO `".$name."`;");
  392. if (!dbm::is_result($r)) {
  393. $errors .= print_update_error($db, $sql3);
  394. return $errors;
  395. }
  396. }
  397. }
  398. }
  399. }
  400. }
  401. if ($action) {
  402. Config::set('system', 'maintenance', 0);
  403. Config::set('system', 'maintenance_reason', '');
  404. }
  405. return $errors;
  406. }
  407. function db_field_command($parameters, $create = true) {
  408. $fieldstruct = $parameters["type"];
  409. if (!is_null($parameters["Collation"])) {
  410. $fieldstruct .= " COLLATE ".$parameters["Collation"];
  411. }
  412. if ($parameters["not null"])
  413. $fieldstruct .= " NOT NULL";
  414. if (isset($parameters["default"])) {
  415. if (strpos(strtolower($parameters["type"]),"int")!==false) {
  416. $fieldstruct .= " DEFAULT ".$parameters["default"];
  417. } else {
  418. $fieldstruct .= " DEFAULT '".$parameters["default"]."'";
  419. }
  420. }
  421. if ($parameters["extra"] != "")
  422. $fieldstruct .= " ".$parameters["extra"];
  423. /*if (($parameters["primary"] != "") AND $create)
  424. $fieldstruct .= " PRIMARY KEY";*/
  425. return($fieldstruct);
  426. }
  427. function db_create_table($name, $fields, $verbose, $action, $indexes=null) {
  428. global $a, $db;
  429. $r = true;
  430. $sql = "";
  431. $sql_rows = array();
  432. $primary_keys = array();
  433. foreach ($fields AS $fieldname => $field) {
  434. $sql_rows[] = "`".dbesc($fieldname)."` ".db_field_command($field);
  435. if (x($field,'primary') and $field['primary']!='') {
  436. $primary_keys[] = $fieldname;
  437. }
  438. }
  439. if (!is_null($indexes)) {
  440. foreach ($indexes AS $indexname => $fieldnames) {
  441. $sql_index = db_create_index($indexname, $fieldnames, "");
  442. if (!is_null($sql_index)) $sql_rows[] = $sql_index;
  443. }
  444. }
  445. $sql = implode(",\n\t", $sql_rows);
  446. $sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT COLLATE utf8mb4_general_ci";
  447. if ($verbose)
  448. echo $sql.";\n";
  449. if ($action)
  450. $r = @$db->q($sql);
  451. return $r;
  452. }
  453. function db_add_table_field($fieldname, $parameters) {
  454. $sql = sprintf("ADD `%s` %s", dbesc($fieldname), db_field_command($parameters));
  455. return($sql);
  456. }
  457. function db_modify_table_field($fieldname, $parameters) {
  458. $sql = sprintf("MODIFY `%s` %s", dbesc($fieldname), db_field_command($parameters, false));
  459. return($sql);
  460. }
  461. function db_drop_index($indexname) {
  462. $sql = sprintf("DROP INDEX `%s`", dbesc($indexname));
  463. return($sql);
  464. }
  465. function db_create_index($indexname, $fieldnames, $method="ADD") {
  466. $method = strtoupper(trim($method));
  467. if ($method!="" && $method!="ADD") {
  468. throw new Exception("Invalid parameter 'method' in db_create_index(): '$method'");
  469. killme();
  470. }
  471. if ($fieldnames[0] == "UNIQUE") {
  472. array_shift($fieldnames);
  473. $method .= ' UNIQUE';
  474. }
  475. $names = "";
  476. foreach ($fieldnames AS $fieldname) {
  477. if ($names != "")
  478. $names .= ",";
  479. if (preg_match('|(.+)\((\d+)\)|', $fieldname, $matches)) {
  480. $names .= "`".dbesc($matches[1])."`(".intval($matches[2]).")";
  481. } else {
  482. $names .= "`".dbesc($fieldname)."`";
  483. }
  484. }
  485. if ($indexname == "PRIMARY") {
  486. return sprintf("%s PRIMARY KEY(%s)", $method, $names);
  487. }
  488. $sql = sprintf("%s INDEX `%s` (%s)", $method, dbesc($indexname), $names);
  489. return($sql);
  490. }
  491. function db_group_by($indexname, $fieldnames) {
  492. if ($fieldnames[0] != "UNIQUE") {
  493. return "";
  494. }
  495. array_shift($fieldnames);
  496. $names = "";
  497. foreach ($fieldnames AS $fieldname) {
  498. if ($names != "")
  499. $names .= ",";
  500. if (preg_match('|(.+)\((\d+)\)|', $fieldname, $matches)) {
  501. $names .= "`".dbesc($matches[1])."`";
  502. } else {
  503. $names .= "`".dbesc($fieldname)."`";
  504. }
  505. }
  506. $sql = sprintf(" GROUP BY %s", $names);
  507. return $sql;
  508. }
  509. function db_definition() {
  510. $database = array();
  511. $database["addon"] = array(
  512. "fields" => array(
  513. "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  514. "name" => array("type" => "varchar(190)", "not null" => "1", "default" => ""),
  515. "version" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  516. "installed" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  517. "hidden" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  518. "timestamp" => array("type" => "bigint(20)", "not null" => "1", "default" => "0"),
  519. "plugin_admin" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  520. ),
  521. "indexes" => array(
  522. "PRIMARY" => array("id"),
  523. "name" => array("UNIQUE", "name"),
  524. )
  525. );
  526. $database["attach"] = array(
  527. "fields" => array(
  528. "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  529. "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  530. "hash" => array("type" => "varchar(64)", "not null" => "1", "default" => ""),
  531. "filename" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  532. "filetype" => array("type" => "varchar(64)", "not null" => "1", "default" => ""),
  533. "filesize" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
  534. "data" => array("type" => "longblob", "not null" => "1"),
  535. "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  536. "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  537. "allow_cid" => array("type" => "mediumtext"),
  538. "allow_gid" => array("type" => "mediumtext"),
  539. "deny_cid" => array("type" => "mediumtext"),
  540. "deny_gid" => array("type" => "mediumtext"),
  541. ),
  542. "indexes" => array(
  543. "PRIMARY" => array("id"),
  544. )
  545. );
  546. $database["auth_codes"] = array(
  547. "fields" => array(
  548. "id" => array("type" => "varchar(40)", "not null" => "1", "primary" => "1"),
  549. "client_id" => array("type" => "varchar(20)", "not null" => "1", "default" => "", "relation" => array("clients" => "client_id")),
  550. "redirect_uri" => array("type" => "varchar(200)", "not null" => "1", "default" => ""),
  551. "expires" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
  552. "scope" => array("type" => "varchar(250)", "not null" => "1", "default" => ""),
  553. ),
  554. "indexes" => array(
  555. "PRIMARY" => array("id"),
  556. )
  557. );
  558. $database["cache"] = array(
  559. "fields" => array(
  560. "k" => array("type" => "varbinary(255)", "not null" => "1", "primary" => "1"),
  561. "v" => array("type" => "mediumtext"),
  562. "expire_mode" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
  563. "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  564. ),
  565. "indexes" => array(
  566. "PRIMARY" => array("k"),
  567. "expire_mode_updated" => array("expire_mode", "updated"),
  568. )
  569. );
  570. $database["challenge"] = array(
  571. "fields" => array(
  572. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  573. "challenge" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  574. "dfrn-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  575. "expire" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
  576. "type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  577. "last_update" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  578. ),
  579. "indexes" => array(
  580. "PRIMARY" => array("id"),
  581. )
  582. );
  583. $database["clients"] = array(
  584. "fields" => array(
  585. "client_id" => array("type" => "varchar(20)", "not null" => "1", "primary" => "1"),
  586. "pw" => array("type" => "varchar(20)", "not null" => "1", "default" => ""),
  587. "redirect_uri" => array("type" => "varchar(200)", "not null" => "1", "default" => ""),
  588. "name" => array("type" => "text"),
  589. "icon" => array("type" => "text"),
  590. "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  591. ),
  592. "indexes" => array(
  593. "PRIMARY" => array("client_id"),
  594. )
  595. );
  596. $database["config"] = array(
  597. "fields" => array(
  598. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  599. "cat" => array("type" => "varbinary(255)", "not null" => "1", "default" => ""),
  600. "k" => array("type" => "varbinary(255)", "not null" => "1", "default" => ""),
  601. "v" => array("type" => "mediumtext"),
  602. ),
  603. "indexes" => array(
  604. "PRIMARY" => array("id"),
  605. "cat_k" => array("UNIQUE", "cat", "k"),
  606. )
  607. );
  608. $database["contact"] = array(
  609. "fields" => array(
  610. "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  611. "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  612. "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  613. "self" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  614. "remote_self" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  615. "rel" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  616. "duplex" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  617. "network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  618. "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  619. "nick" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  620. "location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  621. "about" => array("type" => "text"),
  622. "keywords" => array("type" => "text"),
  623. "gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
  624. "xmpp" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  625. "attag" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  626. "avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  627. "photo" => array("type" => "text"),
  628. "thumb" => array("type" => "text"),
  629. "micro" => array("type" => "text"),
  630. "site-pubkey" => array("type" => "text"),
  631. "issued-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  632. "dfrn-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  633. "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  634. "nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  635. "addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  636. "alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  637. "pubkey" => array("type" => "text"),
  638. "prvkey" => array("type" => "text"),
  639. "batch" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  640. "request" => array("type" => "text"),
  641. "notify" => array("type" => "text"),
  642. "poll" => array("type" => "text"),
  643. "confirm" => array("type" => "text"),
  644. "poco" => array("type" => "text"),
  645. "aes_allow" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  646. "ret-aes" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  647. "usehub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  648. "subhub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  649. "hub-verify" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  650. "last-update" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  651. "success_update" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  652. "failure_update" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  653. "name-date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  654. "uri-date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  655. "avatar-date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  656. "term-date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  657. "last-item" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  658. "priority" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
  659. "blocked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
  660. "readonly" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  661. "writable" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  662. "forum" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  663. "prv" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  664. "contact-type" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
  665. "hidden" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  666. "archive" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  667. "pending" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
  668. "rating" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  669. "reason" => array("type" => "text"),
  670. "closeness" => array("type" => "tinyint(2)", "not null" => "1", "default" => "99"),
  671. "info" => array("type" => "mediumtext"),
  672. "profile-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
  673. "bdyear" => array("type" => "varchar(4)", "not null" => "1", "default" => ""),
  674. "bd" => array("type" => "date", "not null" => "1", "default" => "0001-01-01"),
  675. "notify_new_posts" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  676. "fetch_further_information" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  677. "ffi_keyword_blacklist" => array("type" => "text"),
  678. ),
  679. "indexes" => array(
  680. "PRIMARY" => array("id"),
  681. "uid_name" => array("uid", "name(190)"),
  682. "self_uid" => array("self", "uid"),
  683. "alias_uid" => array("alias(32)", "uid"),
  684. "pending_uid" => array("pending", "uid"),
  685. "blocked_uid" => array("blocked", "uid"),
  686. "uid_rel_network_poll" => array("uid", "rel", "network(4)", "poll(64)", "archive"),
  687. "uid_network_batch" => array("uid", "network(4)", "batch(64)"),
  688. "addr_uid" => array("addr(32)", "uid"),
  689. "nurl_uid" => array("nurl(32)", "uid"),
  690. "nick_uid" => array("nick(32)", "uid"),
  691. "dfrn-id" => array("dfrn-id"),
  692. "issued-id" => array("issued-id"),
  693. )
  694. );
  695. $database["conv"] = array(
  696. "fields" => array(
  697. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  698. "guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""),
  699. "recips" => array("type" => "text"),
  700. "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  701. "creator" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  702. "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  703. "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  704. "subject" => array("type" => "text"),
  705. ),
  706. "indexes" => array(
  707. "PRIMARY" => array("id"),
  708. "uid" => array("uid"),
  709. )
  710. );
  711. $database["conversation"] = array(
  712. "fields" => array(
  713. "item-uri" => array("type" => "varbinary(255)", "not null" => "1", "primary" => "1"),
  714. "reply-to-uri" => array("type" => "varbinary(255)", "not null" => "1", "default" => ""),
  715. "conversation-uri" => array("type" => "varbinary(255)", "not null" => "1", "default" => ""),
  716. "conversation-href" => array("type" => "varbinary(255)", "not null" => "1", "default" => ""),
  717. "protocol" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
  718. "source" => array("type" => "mediumtext"),
  719. "received" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  720. ),
  721. "indexes" => array(
  722. "PRIMARY" => array("item-uri"),
  723. "conversation-uri" => array("conversation-uri"),
  724. )
  725. );
  726. $database["event"] = array(
  727. "fields" => array(
  728. "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  729. "guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  730. "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  731. "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")),
  732. "uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  733. "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  734. "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  735. "start" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  736. "finish" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  737. "summary" => array("type" => "text"),
  738. "desc" => array("type" => "text"),
  739. "location" => array("type" => "text"),
  740. "type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  741. "nofinish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  742. "adjust" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
  743. "ignore" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
  744. "allow_cid" => array("type" => "mediumtext"),
  745. "allow_gid" => array("type" => "mediumtext"),
  746. "deny_cid" => array("type" => "mediumtext"),
  747. "deny_gid" => array("type" => "mediumtext"),
  748. ),
  749. "indexes" => array(
  750. "PRIMARY" => array("id"),
  751. "uid_start" => array("uid", "start"),
  752. )
  753. );
  754. $database["fcontact"] = array(
  755. "fields" => array(
  756. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  757. "guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  758. "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  759. "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  760. "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  761. "request" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  762. "nick" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  763. "addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  764. "batch" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  765. "notify" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  766. "poll" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  767. "confirm" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  768. "priority" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  769. "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
  770. "alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  771. "pubkey" => array("type" => "text"),
  772. "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  773. ),
  774. "indexes" => array(
  775. "PRIMARY" => array("id"),
  776. "addr" => array("addr(32)"),
  777. "url" => array("url"),
  778. )
  779. );
  780. $database["ffinder"] = array(
  781. "fields" => array(
  782. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  783. "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  784. "cid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")),
  785. "fid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("fcontact" => "id")),
  786. ),
  787. "indexes" => array(
  788. "PRIMARY" => array("id"),
  789. )
  790. );
  791. $database["fserver"] = array(
  792. "fields" => array(
  793. "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  794. "server" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  795. "posturl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  796. "key" => array("type" => "text"),
  797. ),
  798. "indexes" => array(
  799. "PRIMARY" => array("id"),
  800. "server" => array("server(32)"),
  801. )
  802. );
  803. $database["fsuggest"] = array(
  804. "fields" => array(
  805. "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  806. "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  807. "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")),
  808. "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  809. "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  810. "request" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  811. "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  812. "note" => array("type" => "text"),
  813. "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  814. ),
  815. "indexes" => array(
  816. "PRIMARY" => array("id"),
  817. )
  818. );
  819. $database["gcign"] = array(
  820. "fields" => array(
  821. "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  822. "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  823. "gcid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("gcontact" => "id")),
  824. ),
  825. "indexes" => array(
  826. "PRIMARY" => array("id"),
  827. "uid" => array("uid"),
  828. "gcid" => array("gcid"),
  829. )
  830. );
  831. $database["gcontact"] = array(
  832. "fields" => array(
  833. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  834. "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  835. "nick" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  836. "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  837. "nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  838. "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  839. "connect" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  840. "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  841. "updated" => array("type" => "datetime", "default" => NULL_DATE),
  842. "last_contact" => array("type" => "datetime", "default" => NULL_DATE),
  843. "last_failure" => array("type" => "datetime", "default" => NULL_DATE),
  844. "location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  845. "about" => array("type" => "text"),
  846. "keywords" => array("type" => "text"),
  847. "gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
  848. "birthday" => array("type" => "varchar(32)", "not null" => "1", "default" => "0001-01-01"),
  849. "community" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  850. "contact-type" => array("type" => "tinyint(1)", "not null" => "1", "default" => "-1"),
  851. "hide" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  852. "nsfw" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  853. "network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  854. "addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  855. "notify" => array("type" => "text"),
  856. "alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  857. "generation" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
  858. "server_url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  859. ),
  860. "indexes" => array(
  861. "PRIMARY" => array("id"),
  862. "nurl" => array("nurl(64)"),
  863. "name" => array("name(64)"),
  864. "nick" => array("nick(32)"),
  865. "addr" => array("addr(64)"),
  866. "hide_network_updated" => array("hide", "network(4)", "updated"),
  867. "updated" => array("updated"),
  868. )
  869. );
  870. $database["glink"] = array(
  871. "fields" => array(
  872. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  873. "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")),
  874. "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  875. "gcid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("gcontact" => "id")),
  876. "zcid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("gcontact" => "id")),
  877. "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  878. ),
  879. "indexes" => array(
  880. "PRIMARY" => array("id"),
  881. "cid_uid_gcid_zcid" => array("UNIQUE", "cid","uid","gcid","zcid"),
  882. "gcid" => array("gcid"),
  883. )
  884. );
  885. $database["group"] = array(
  886. "fields" => array(
  887. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  888. "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  889. "visible" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  890. "deleted" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  891. "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  892. ),
  893. "indexes" => array(
  894. "PRIMARY" => array("id"),
  895. "uid" => array("uid"),
  896. )
  897. );
  898. $database["group_member"] = array(
  899. "fields" => array(
  900. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  901. "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")),
  902. "gid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("group" => "id")),
  903. "contact-id" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")),
  904. ),
  905. "indexes" => array(
  906. "PRIMARY" => array("id"),
  907. "contactid" => array("contact-id"),
  908. "gid_contactid" => array("gid", "contact-id"),
  909. "uid_gid_contactid" => array("UNIQUE", "uid", "gid", "contact-id"),
  910. )
  911. );
  912. $database["gserver"] = array(
  913. "fields" => array(
  914. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  915. "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  916. "nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  917. "version" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  918. "site_name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  919. "info" => array("type" => "text"),
  920. "register_policy" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
  921. "poco" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  922. "noscrape" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  923. "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
  924. "platform" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  925. "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE),
  926. "last_poco_query" => array("type" => "datetime", "default" => NULL_DATE),
  927. "last_contact" => array("type" => "datetime", "default" => NULL_DATE),
  928. "last_failure" => array("type" => "datetime", "default" => NULL_DATE),
  929. ),
  930. "indexes" => array(
  931. "PRIMARY" => array("id"),
  932. "nurl" => array("nurl(32)"),
  933. )
  934. );
  935. $database["hook"] = array(
  936. "fields" => array(
  937. "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  938. "hook" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  939. "file" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  940. "function" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
  941. "priority" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
  942. ),
  943. "indexes" => array(
  944. "PRIMARY" => array("id"),
  945. "hook_file_function" => array("UNIQUE", "hook(50)","file(80)","function(60)"),
  946. )
  947. );
  948. $database["intro"] = array(
  949. "fields" => array(
  950. "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
  951. "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "<