2f903e2001-03-04Per Hedbor #include <config_interface.h> #include <config.h> #include <roxen.h> //<locale-token project="roxen_config">_</locale-token> #define _(X,Y) _STR_LOCALE("roxen_config",X,Y)
9570352001-08-09Per Hedbor mapping actions = ([
adcd212001-08-13Per Hedbor  // name title function must be internal
a74f072017-12-21Karl Gustav Sterneberg  "configure_ext_db_con": ({ _(1145,"Configure database connection"),
e2d8df2017-12-21Karl Gustav Sterneberg  configure_ext_db_con, 0 }),
9fa11d2001-08-24Martin Nilsson  "delete": ({ _(402,"Delete this database"), delete_db, 0 }),
1128652001-09-03Martin Nilsson  "group": ({ _(324,"Change group for this database"), change_group, 0 }),
9fa11d2001-08-24Martin Nilsson  "clear": ({ _(403,"Delete all tables"), clear_db, 0 }), "backup": ({ _(404,"Make a backup"), backup_db, 1 }),
fe07f52008-01-10Jonas Wallden  "charset":({ _(536, "Change default character set"), change_charset, 0 }), "repair": ({ _(537, "Repair all tables"), repair_db, 0 }), "optimize":({ _(538, "Optimize all tables"), optimize_db, 0 }),
0c7a1e2016-09-27Anders Johansson  "schedule":({ _(1109, "Change backup schedule"), change_schedule, 2 }),
9570352001-08-09Per Hedbor ]);
2f4c982001-09-03Per Hedbor 
a3b9102002-08-16Anders Johansson #define CU_AUTH id->misc->config_user->auth
c403b32015-04-02Jonas Walldén // Size limit for single field and aggregated fields (per column) #define MAX_FIELD_FORMATTED_SIZE (32 * 1024) // 32 K #define MAX_TOTAL_FORMATTED_SIZE (1024 * 1024) // 1 MB
adcd212001-08-13Per Hedbor #define VERIFY(X) do { \ if( !id->variables["yes.x"] ) \ { \ return \ ("<table><tr><td colspan='2'>\n"+ \ sprintf((string)(X), db)+ \ "</td><tr><td><input type=hidden name=action value='&form.action;' />"\
f2b0872004-02-18Anders Johansson  "<submit-gbutton2 name='yes' align='center' " \ " width='&usr.gbutton-width;'>"+_(0,"Yes")+ \ "</submit-gbutton2></td>\n" \
e1fff72016-01-15Henrik Grubbström (Grubba)  "<td align=right><cf-no href='"+Roxen.html_encode_string(id->not_query)+\ "?db="+Roxen.html_encode_string(id->variables->db)+ \ "&amp;&usr.set-wiz-id;' />"+ \
80cd682003-11-17Anders Johansson  "</td>\n</table>\n"); \ } \
9570352001-08-09Per Hedbor } while(0)
2f4c982001-09-03Per Hedbor mixed change_group( string db, RequestID id ) { if( !id->variables->group ) { string res ="<br /><blockquote>" "<input type=hidden name=action value='&form.action;' />"
1128652001-09-03Martin Nilsson  "<h2>"+sprintf(_(423,"Changing group for %s"), db )+"</h2>" "<b>"+_(445,"Old group")+":</b> " +
2f4c982001-09-03Per Hedbor  DBManager.get_group(DBManager.db_group(db))->lname+"<br />"
1128652001-09-03Martin Nilsson  "<b>"+_(504,"New group")+":</b> <select name='group'>";
2f4c982001-09-03Per Hedbor  foreach( DBManager.list_groups(), string g ) if( g == DBManager.db_group( db ) ) res += "<option selected value='"+g+"'>"+DBManager.get_group( g )->lname; else res += "<option value='"+g+"'>"+DBManager.get_group( g )->lname;
3f40442004-02-03Anders Johansson  return res + "</select><submit-gbutton2 name='ok'>"+(201,"OK")+
2f4c982001-09-03Per Hedbor  "</submit-gbutton2>"; } DBManager.set_db_group( db, id->variables->group ); return 0; }
0d30602007-01-17Henrik Grubbström (Grubba) mixed change_charset( string db, RequestID id ) { if( !id->variables->default_charset ) { string old_charset = DBManager.get_db_default_charset(db); string res ="<br /><blockquote>" "<input type=hidden name=action value='&form.action;' />"
fe07f52008-01-10Jonas Wallden  "<h2>"+sprintf(_(539,"Changing default character set for %s"), db )+
0d30602007-01-17Henrik Grubbström (Grubba)  "</h2>"+
fe07f52008-01-10Jonas Wallden  (old_charset?("<b>"+_(540, "Old default character set")+":</b> " +
0d30602007-01-17Henrik Grubbström (Grubba)  old_charset+"<br />"):"")+
fe07f52008-01-10Jonas Wallden  "<b>"+_(541,"New default character set")+":</b> "
0d30602007-01-17Henrik Grubbström (Grubba)  "<input type='string' name='default_charset' value='" + Roxen.html_encode_string(old_charset||"") +"' />"; return res + "</select><submit-gbutton2 name='ok'>"+(201,"OK")+ "</submit-gbutton2>"; } DBManager.set_db_default_charset( db, id->variables->default_charset ); return 0; }
c199a02015-10-21Henrik Grubbström (Grubba) mixed change_schedule( string db, RequestID id ) { Sql.Sql sql = connect_to_my_mysql(0, "roxen"); if( !id->variables->backup_schedule ) { string old_schedule, old_schedule_id; array q = sql->query("SELECT schedule_id, schedule FROM dbs, db_schedules " " WHERE db_schedules.id = dbs.schedule_id " " AND dbs.name = %s", db); if (sizeof(q)) { old_schedule = q[0]->schedule; old_schedule_id = q[0]->schedule_id; } string res ="<br /><blockquote>" "<input type=hidden name=action value='&form.action;' />"
0c7a1e2016-09-27Anders Johansson  "<h2>"+sprintf(_(1110,"Changing backup schedule for %s"), db )+
c199a02015-10-21Henrik Grubbström (Grubba)  "</h2>"+
0c7a1e2016-09-27Anders Johansson  (old_schedule?("<b>"+_(1111, "Old backup schedule")+":</b> " +
c199a02015-10-21Henrik Grubbström (Grubba)  Roxen.html_encode_string(old_schedule)+"<br />"):"")+
0c7a1e2016-09-27Anders Johansson  "<b>"+_(1112,"New backup schedule")+":</b> "
c199a02015-10-21Henrik Grubbström (Grubba)  "<default name='backup_schedule' value='" + old_schedule_id + "'>" "<select name='backup_schedule'>"; foreach(sql->query("SELECT schedule, id FROM db_schedules " " ORDER BY schedule"), mapping(string:string) schedule) { res += sprintf("<option value='%s'>%s</option>", schedule->id, Roxen.html_encode_string(schedule->schedule)); } res += sprintf("<option value='0'>%s</option>",
0c7a1e2016-09-27Anders Johansson  Roxen.html_encode_string(_(1113, "None"))) +
c199a02015-10-21Henrik Grubbström (Grubba)  "</select></default>"; return res + "<submit-gbutton2 name='ok'>"+(201,"OK")+ "</submit-gbutton2>"; } if (id->variables->backup_schedule == "0") { sql->query("UPDATE dbs SET schedule_id = NULL " " WHERE name = %s", db); } else { sql->query("UPDATE dbs SET schedule_id = %d " " WHERE name = %s", (int)id->variables->backup_schedule, db); } return 0; }
e6f6392007-05-26Martin Stjernholm mixed repair_db( string db, RequestID id ) { // CSS stylesheet string res = "<style type='text/css'>" "#tbl {" " font-size: smaller;" " text-align: left;" "}\n" "#tbl tr > td {" " padding-left: 1em;" " border-bottom: 1px solid &usr.matrix22;;" "}\n" "#tbl tr > th {" " font-weight: bold;" " background-color: &usr.matrix12;;" " padding-left: 1em;" "}\n" "#tbl tr > *:first-child {" " padding-left: 0;" "}\n" "</style>"
e1fff72016-01-15Henrik Grubbström (Grubba)  "<a href='browser.pike?db=" + db + "&amp;&usr.set-wiz-id;'><gbutton>Back</gbutton></a><br/><br/>"
e6f6392007-05-26Martin Stjernholm  "<table id='tbl' cellspacing='0' cellpadding='1'>" "<thead>" "<tr>" "<th>Target</th>" "<th>Result</th>" "<th>Time</th>" "</tr>" "</thead>" "<tbody>"; mixed m = query("SHOW TABLE STATUS IN " + db); float t3 = 0; if (sizeof(m)) { foreach (m,m) { string result = ""; mixed q; int t = time(); float t1 = time(t); float t2; if ( mixed e = catch { q = query( "REPAIR TABLE `" + db + "`.`" + m->Name + "`" ); } ) { result = "<font color='red'>Error: " + describe_error(e) + "</font>"; } else { t2 = (time(t)-t1); t3 += t2; if (q->Msg_text = "OK") result = "<font color='green'>OK</font>"; else result = "<font color='red'>Failed: " + q->Msg_text + "</font>"; } res += "<tr>" +
e1fff72016-01-15Henrik Grubbström (Grubba)  "<td><a href='browser.pike?db=" + db + "&amp;&usr.set-wiz-id;'>" + db + "</a>.<a href='browser.pike?db=" + db + "&amp;table=" + m->Name + "&amp;&usr.set-wiz-id;'>" + m->Name + "</a></td>" +
e6f6392007-05-26Martin Stjernholm  "<td><b>" + result + "</b></td>" + "<td>" + t2 + " sec</td>" + "</tr>"; } } res += "<tr><td colspan='2'>Total:</td><td>" + t3 + " sec</td></tr></tbody></table><br/>"; return res; } mixed optimize_db( string db, RequestID id ) { // CSS stylesheet string res = "<style type='text/css'>" "#tbl {" " font-size: smaller;" " text-align: left;" "}\n" "#tbl tr > td {" " padding-left: 1em;" " border-bottom: 1px solid &usr.matrix22;;" "}\n" "#tbl tr > th {" " font-weight: bold;" " background-color: &usr.matrix12;;" " padding-left: 1em;" "}\n" "#tbl tr > *:first-child {" " padding-left: 0;" "}\n" "</style>"
e1fff72016-01-15Henrik Grubbström (Grubba)  "<a href='browser.pike?db=" + db + "&amp;&usr.set-wiz-id;'><gbutton>Back</gbutton></a><br/><br/>"
e6f6392007-05-26Martin Stjernholm  "<table id='tbl' cellspacing='0' cellpadding='1'>" "<thead>" "<tr>" "<th>Target</th>" "<th>Result</th>" "<th>Time</th>" "</tr>" "</thead>" "<tbody>"; mixed m = query("SHOW TABLE STATUS IN " + db); float t3 = 0; if (sizeof(m)) { foreach (m,m) { string result = ""; mixed q; int t = time(); float t1 = time(t); float t2; if ( mixed e = catch { q = query( "OPTIMIZE TABLE `" + db + "`.`" + m->Name + "`" ); } ) { result = "<font color='red'>Error: " + describe_error(e) + "</font>"; } else { t2 = (time(t)-t1); t3 += t2; if (q->Msg_text = "OK") result = "<font color='green'>OK</font>"; else result = "<font color='red'>Failed: " + q->Msg_text + "</font>"; } res += "<tr>" +
e1fff72016-01-15Henrik Grubbström (Grubba)  "<td><a href='browser.pike?db=" + db + "&amp;&usr.set-wiz-id;'>" + db + "</a>.<a href='browser.pike?db=" + db + "&amp;table=" + m->Name + "&amp;&usr.set-wiz-id;'>" + m->Name + "</a></td>" +
e6f6392007-05-26Martin Stjernholm  "<td><b>" + result + "</b></td>" + "<td>" + t2 + " sec</td>" + "</tr>"; } } res += "<tr><td colspan='2'>Total:</td><td>" + t3 + " sec</td></tr></table><br/>"; return res;} mixed query( mixed ... args ) { return connect_to_my_mysql( 0, "roxen" )->query( @args ); }
adcd212001-08-13Per Hedbor mixed backup_db( string db, RequestID id ) { if( id->variables["ok.x"] ) {
f770512010-11-25Henrik Grubbström (Grubba)  if (roxenloader->parse_mysql_location()->mysqldump) { DBManager.dump (db, id->variables->dir == "auto" ? 0 : id->variables->dir); } else { DBManager.backup (db, id->variables->dir == "auto" ? 0 : id->variables->dir); }
adcd212001-08-13Per Hedbor  return 0; } return
80cd682003-11-17Anders Johansson  "<b>"+_(405,"Directory")+":</b> <input name='dir' size='60' value='auto' /><br />"
6a32272011-12-21Jonas Wallden  "<i>" + sprintf (_(1061, #"\
9dd99a2010-01-28Martin Stjernholm The directory the backup will be saved in. If you chose auto, Roxen will generate a directory name that includes the database name and today's date in <tt>$VARDIR/backup</tt> (%s)."), combine_path (getcwd(), roxen_path ("$VARDIR/backup"))) + "</i>"
adcd212001-08-13Per Hedbor  "<table width='100%'><tr><td valign=top>" "<input type=hidden name=action value='&form.action;' />"
34448c2015-04-09Henrik Grubbström (Grubba)  "<cf-cancel href='"+ Roxen.html_encode_string(id->not_query)+
e1fff72016-01-15Henrik Grubbström (Grubba)  "?db="+Roxen.html_encode_string(id->variables->db)+"&amp;&usr.set-wiz-id;'/>"
34448c2015-04-09Henrik Grubbström (Grubba)  "<td valign=top align=right><submit-gbutton2 name='ok'>"+_(201,"OK")+ "</submit-gbutton2></td>\n"
80cd682003-11-17Anders Johansson  "</td>\n</table>\n";
adcd212001-08-13Per Hedbor }
e2d8df2017-12-21Karl Gustav Sterneberg mixed configure_ext_db_con( string db, RequestID id )
9570352001-08-09Per Hedbor {
e2d8df2017-12-21Karl Gustav Sterneberg  if( DBManager.is_internal( db ) ) { error("Configure external database connection not possible for internal " "databases."); }
adcd212001-08-13Per Hedbor  string warning=""; if( id->variables["ok.x"] ) {
e2d8df2017-12-21Karl Gustav Sterneberg  if( !strlen(id->variables->url) ) { warning= "<font color='&usr.warncolor;'>" +_(406,"Please specify an URL to define an external database")+ "</font>"; } else if( mixed err = catch( Sql.Sql( id->variables->url ) ) ) { warning = sprintf("<font color='&usr.warncolor;'>"+ _(407,"It is not possible to connect to %s.")+ "<br /> (%s)" "</font>", id->variables->url, describe_error(err));
adcd212001-08-13Per Hedbor  } if( !strlen( warning ) ) switch( id->variables->name ) { case "":
e6f6392007-05-26Martin Stjernholm  warning = "<font color='&usr.warncolor;'>"+
a2548f2018-01-12Karl Gustav Sterneberg  _(1146,"Please specify a name for the database connection.")+
adcd212001-08-13Per Hedbor  "</font>"; break; case "mysql": case "roxen": warning = sprintf("<font color='&usr.warncolor;'>"+
32b1082018-01-02Henrik Grubbström (Grubba)  _(1147,"<tt>%s</tt> is an internal database, used by Roxen. "
a2548f2018-01-12Karl Gustav Sterneberg  "Please select another name.")+
adcd212001-08-13Per Hedbor  "</font>", id->variables->name ); break; default:
407e832001-08-17Per Hedbor  if( Roxen.is_mysql_keyword( id->variables->name ) ) warning = sprintf("<font color='&usr.warncolor;'>"+
32b1082018-01-02Henrik Grubbström (Grubba)  _(1148,"<tt>%s</tt> is a MySQL keyword, used by MySQL. "
a2548f2018-01-12Karl Gustav Sterneberg  "Please select another name.")+
407e832001-08-17Per Hedbor  "</font>", id->variables->name );
c03fb22010-03-24Henrik Grubbström (Grubba)  catch {
2d981b2017-12-21Karl Gustav Sterneberg  // Check name first since DBManager.get_db_url_info() ignores // trailing spaces in db name. if( !(DBManager.valid_db_name( id->variables->name )) ) { warning = sprintf("<font color='&usr.warncolor;'>"+
32b1082018-01-02Henrik Grubbström (Grubba)  _(1149,"<span style=\"white-space: pre;\">"
2d981b2017-12-21Karl Gustav Sterneberg  "'<tt>%s</tt>'</span> "
a2548f2018-01-12Karl Gustav Sterneberg  "is not a valid database name. " "Please select another name.")+
2d080e2018-03-27Karl Gustav Sterneberg  "</font>", Roxen.html_encode_string(id->variables->name));
2d981b2017-12-21Karl Gustav Sterneberg  } else if( db != id->variables->name && DBManager.get_db_url_info( id->variables->name ) ) { warning = sprintf("<font color='&usr.warncolor;'>"+
a2548f2018-01-12Karl Gustav Sterneberg  _(529,"A database with name <tt>%s</tt> " "already exists. Please select another name.")+
2d981b2017-12-21Karl Gustav Sterneberg  "</font>", id->variables->name ); }
c03fb22010-03-24Henrik Grubbström (Grubba)  };
407e832001-08-17Per Hedbor  break;
adcd212001-08-13Per Hedbor  } if( !strlen( warning ) ) {
2d981b2017-12-21Karl Gustav Sterneberg  if( db != id->variables->name ) { DBManager.create_db( id->variables->name, id->variables->url, 0, id->variables->group );
e2d8df2017-12-21Karl Gustav Sterneberg  DBManager.copy_db_md( db, id->variables->name ); DBManager.drop_db( db );
5054982005-04-15Marcus Wellhardh  }
e2d8df2017-12-21Karl Gustav Sterneberg  else if( id->variables->url != DBManager.db_url( db ) )
adcd212001-08-13Per Hedbor  {
e2d8df2017-12-21Karl Gustav Sterneberg  // Only url has changed.
2d981b2017-12-21Karl Gustav Sterneberg  DBManager.set_url( db, id->variables->url, 0 );
adcd212001-08-13Per Hedbor  }
e2d8df2017-12-21Karl Gustav Sterneberg  // else nothing has changed...
adcd212001-08-13Per Hedbor  return Roxen.http_redirect( "/dbs/", id ); } }
2d981b2017-12-21Karl Gustav Sterneberg  if( !id->variables->name )
adcd212001-08-13Per Hedbor  id->variables->name = db;
e0bd902001-10-01Per Hedbor 
adcd212001-08-13Per Hedbor  if( !id->variables->url ) id->variables->url = DBManager.db_url( db ) || ""; return
e2d8df2017-12-21Karl Gustav Sterneberg  "<gtext scale=0.6>"+_(414,"Configure external database connection")+"</gtext><br />\n"
adcd212001-08-13Per Hedbor  +warning+ "<table>\n"
5054982005-04-15Marcus Wellhardh 
adcd212001-08-13Per Hedbor  " <tr>\n"
a2548f2018-01-12Karl Gustav Sterneberg  " <td><b>"+_(418,"Name")+":</b></td>\n"
5054982005-04-15Marcus Wellhardh  " <td><input name='name' value='&form.name;'/></td>\n" " </tr>\n" " <tr>\n" " <td valign=top colspan='2'>\n"
a2548f2018-01-12Karl Gustav Sterneberg  " <i>"+_(530,"The name for the database. It is recommended to "
2d981b2017-12-21Karl Gustav Sterneberg  "use only lowercase letters <tt>[a-z]</tt>, numbers " "and <tt>-</tt> (dash).")+"</i>\n"
5054982005-04-15Marcus Wellhardh  " </td>\n" " </tr>\n"+
e2d8df2017-12-21Karl Gustav Sterneberg  " <tr>\n" " <td><nbsp><b>URL:</b></nbsp></td>\n" " <td colspan='3'><input name='url' size=50 value='&form.url;'/></td>\n" " </tr>\n"+
5054982005-04-15Marcus Wellhardh 
adcd212001-08-13Per Hedbor  "</table>\n"+ "<table width='100%'><tr><td>" "<input type=hidden name=action value='&form.action;' />"
34448c2015-04-09Henrik Grubbström (Grubba)  "<cf-cancel href='" + Roxen.html_encode_string(id->not_query) +
ce77982016-01-15Henrik Grubbström (Grubba)  "?db=" + Roxen.html_encode_string(id->variables->db) + "&amp;&usr.set-wiz-id;'/></td>\n"
80cd682003-11-17Anders Johansson  "<td align=right>"
34448c2015-04-09Henrik Grubbström (Grubba)  "<submit-gbutton2 name='ok'>" + _(201,"OK") + "</submit-gbutton2>"
80cd682003-11-17Anders Johansson  "</td>\n</table>\n";
9570352001-08-09Per Hedbor } mixed delete_db( string db, RequestID id ) {
c6098c2001-09-03Per Hedbor  string msg; if( DBManager.is_internal( db ) )
a77be32001-09-03Henrik Grubbström (Grubba)  msg = (string)_(361, "Are you sure you want to delete the database %s "
c6098c2001-09-03Per Hedbor  "and the data?"); else
a77be32001-09-03Henrik Grubbström (Grubba)  msg = (string)_(362,"Are you sure you want to delete the database %s?"
d11bb42006-05-04Marcus Wellhardh  " No data will be deleted from the remote database.");
c6098c2001-09-03Per Hedbor  VERIFY(msg);
13c6092001-12-10Anders Johansson  report_notice( _(424,"The database %s was deleted by %s")+"\n",
9570352001-08-09Per Hedbor  db, id->misc->authenticated_user->name() ); DBManager.drop_db( db );
adcd212001-08-13Per Hedbor  return Roxen.http_redirect( "/dbs/", id );
9570352001-08-09Per Hedbor } mixed clear_db( string db, RequestID id ) {
9fa11d2001-08-24Martin Nilsson  VERIFY(_(425,"Are you sure you want to delete all tables in %s?"));
e0bd902001-10-01Per Hedbor 
9570352001-08-09Per Hedbor  Sql.Sql sq = DBManager.get( db );
e0bd902001-10-01Per Hedbor 
0a416e2009-04-02Henrik Grubbström (Grubba)  // Note: Drop table may fail due to foreign key references // in some databases. Thus the outer loop and the catch.
017e292009-04-03Henrik Grubbström (Grubba)  int table_cnt;
0a416e2009-04-02Henrik Grubbström (Grubba)  array(string) remaining_tables = DBManager.db_tables( db ); do { foreach( remaining_tables, string r ) { catch { sq->query( "DROP TABLE "+r ); }; } table_cnt = sizeof(remaining_tables); remaining_tables = DBManager.db_tables( db ); } while (sizeof(remaining_tables) && (table_cnt > sizeof(remaining_tables))); if (sizeof(remaining_tables)) { // We've failed to drop some tables, try forcing an error. sq->query( "DROP TABLE " + remaining_tables[0]); }
9570352001-08-09Per Hedbor  return 0; }
c488632001-03-04Per Hedbor int image_id = time() ^ gethrtime();
a32e962001-03-04Per Hedbor 
7042992001-03-04Per Hedbor string is_image( string x )
a32e962001-03-04Per Hedbor {
44d4172001-10-05Per Hedbor  if( !stringp(x) ) return 0;
8b89ed2001-07-24Johan Sundström  if( has_prefix( x, "GIF" ) )
7042992001-03-04Per Hedbor  return "gif"; if( has_value( x, "JFIF" ) ) return "jpeg";
8b89ed2001-07-24Johan Sundström  if( has_prefix( x, "\x89PNG" ) )
7042992001-03-04Per Hedbor  return "png"; }
a32e962001-03-04Per Hedbor 
b5a1522010-09-24Martin Jonsson int is_deflated (string what) { // This detection is an estimate - it may give false positives. if (!stringp (what) || sizeof (what) < 3) return 0; return ((what[0] & 0x0f) == 8) && !(((what[0] << 8) + what[1]) % 31); }
7ff5522001-03-05Per Hedbor  int is_encode_value( string what ) {
44d4172001-10-05Per Hedbor  if( !stringp(what) ) return 0;
d784262009-09-15Martin Stjernholm  return strlen(what) >= 5 && has_prefix (what, "¶ke");
7ff5522001-03-05Per Hedbor } string format_decode_value( string what ) {
e6f6392007-05-26Martin Stjernholm #if 0
7ff5522001-03-05Per Hedbor  string trim_comments( string what ) /* Needs work */ { string a, b; while( sscanf( what, "%s/*%*s*/%s", a, b ) ) what = a+b; return what; };
e6f6392007-05-26Martin Stjernholm #endif
7ff5522001-03-05Per Hedbor 
7bc5cc2001-09-03Per Hedbor  // Type is program or object? if( (what[4] & 15) == 5 || (what[4] & 15) == 3 ) return Roxen.html_encode_string( sprintf("<"+_(233,"bytecode data")+" ("+
1128652001-09-03Martin Nilsson  _(505,"%d bytes")+")>", strlen(what)));
7bc5cc2001-09-03Per Hedbor 
7ff5522001-03-05Per Hedbor  catch {
7bc5cc2001-09-03Per Hedbor  return "<pre>"+
e6f6392007-05-26Martin Stjernholm  Roxen.html_encode_string( String.trim_all_whites(sprintf("%O",decode_value(what))))+
7bc5cc2001-09-03Per Hedbor  "</pre>";
7ff5522001-03-05Per Hedbor  };
c8516a2001-03-16Per Hedbor  return Roxen.html_encode_string( what );
7ff5522001-03-05Per Hedbor }
7042992001-03-04Per Hedbor string store_image( string x ) {
a32e962001-03-04Per Hedbor  string id = (string)image_id++;
7bc5cc2001-09-03Per Hedbor  .State->images[ id ] = ([
c488632001-03-04Per Hedbor  "type":"image/"+(is_image( x )||"unknown"),
a32e962001-03-04Per Hedbor  "data":x, "len":strlen(x), ]); return id; }
0d7d3a2007-01-18 Erik Dahl string db_switcher( RequestID id ) { mapping q = DBManager.get_permission_map( ); if ( !sizeof( q )) return ""; string res = #" <script type='text/javascript'> function switch_db( objSel ) { if( objSel.selectedIndex == 0) { return; } var selValue = objSel.options[objSel.selectedIndex].value; if(selValue != '&form.db:js;') {
5ad5db2016-02-10Henrik Grubbström (Grubba)  window.location.href = window.location.pathname + '?db=' + escape( selValue ) + '\x26&usr.set-wiz-id:js;';
0d7d3a2007-01-18 Erik Dahl  } } </script>
615dac2007-01-18 Erik Dahl  <select name='db' onchange='switch_db(this)'>
0d7d3a2007-01-18 Erik Dahl  <option value=''>Switch to other DB</option>\n"; foreach( sort(indices(q)), string d ) { res += sprintf( "<option value='%s'%s>%s</option>\n", d, (d == id->variables->db)? "selected='selected'": "", d); } return res + "</select><noscript><input type='submit' value='Switch db'/></noscript>\n"; }
e6f6392007-05-26Martin Stjernholm string format_table_owner (mapping(string:string) mod_info, void|int skip_conf) { // Note: Code duplication in db_list.pike. if ((<0, "">)[mod_info->conf]) return 0; Configuration c = roxen.find_configuration( mod_info->conf ); RoxenModule m = c && !(<0, "">)[mod_info->module] && c->find_module( mod_info->module ); ModuleInfo i = !(<0, "">)[mod_info->module] && roxen.find_module( (mod_info->module/"#")[0] ); string mn; if (!skip_conf) { if (c) { mn = "<a href='../sites/site.html/" + Roxen.http_encode_url (mod_info->conf) + "/'>" + Roxen.html_encode_string (c->query_name()) + "</a>"; } else mn = Roxen.html_encode_string (
fe07f52008-01-10Jonas Wallden  sprintf ((string) _(542, "the deleted site %O"), mod_info->conf));
e6f6392007-05-26Martin Stjernholm  } if( m ) { string module = "<a href='../sites/site.html/"+ Roxen.http_encode_url(mod_info->conf)+"/n!n/"+ replace(mod_info->module,"#","!")+"/"+ "'>"+ Roxen.html_encode_string (i->get_name())+"</a>"; if (mn)
fe07f52008-01-10Jonas Wallden  mn = sprintf ((string) _(543, "%s in %s"), module, mn);
e6f6392007-05-26Martin Stjernholm  else mn = module; } else if( i ) { if (mn) mn = sprintf (
fe07f52008-01-10Jonas Wallden  (string) _(544, "the deleted module %s in %s"),
e6f6392007-05-26Martin Stjernholm  Roxen.html_encode_string (sprintf ("%O", (string) i->get_name())), mn); else mn = sprintf (
fe07f52008-01-10Jonas Wallden  (string) _(545, "the deleted module %s"),
e6f6392007-05-26Martin Stjernholm  Roxen.html_encode_string (sprintf ("%O", (string) i->get_name()))); } return mn; }
a32e962001-03-04Per Hedbor mapping|string parse( RequestID id )
b53a4a2001-01-09Per Hedbor {
7bc5cc2001-09-03Per Hedbor  if( id->variables->image ) return m_delete( .State->images, id->variables->image );
e0bd902001-10-01Per Hedbor 
a3b9102002-08-16Anders Johansson  if( !id->variables->db || !( CU_AUTH( "Edit Global Variables" ) ) )
7bc5cc2001-09-03Per Hedbor  return Roxen.http_redirect( "/dbs/", id );
9570352001-08-09Per Hedbor  string res =
719f172011-10-27Jonas Wallden  "<set variable='var.form-anchor' value='#dbquery'/>" "<use file='/template'/><tmpl>" "<topmenu base='../' selected='dbs'/>" "<content><cv-split><subtablist width='100%'><st-tabs>" "<insert file='subtabs.pike'/></st-tabs><st-page>" "<input type='hidden' name='sort' value='&form.sort:http;' />\n" "<style type='text/css'>\n"
e6f6392007-05-26Martin Stjernholm  ".num {" " text-align: right;"
be89b22007-05-26Martin Stjernholm  " white-space: nowrap;"
e6f6392007-05-26Martin Stjernholm  "}\n" "#tbls a {" " color: #0033aa;" " text-decoration: none;" "}\n" "#tbls a:hover {" " color: #0055ff;" " text-decoration: underline;" "}\n" "#tbls {" " font-size: smaller;" " text-align: left;" " border-collapse: collapse;" "}\n" "#tbls > * > tr > td {" " padding-left: 1em;" " border-bottom: 1px solid &usr.matrix22;;" "}\n" "#tbls > * > tr > th {" " font-weight: bold;"
be89b22007-05-26Martin Stjernholm  " white-space: nowrap;"
e6f6392007-05-26Martin Stjernholm  " background-color: &usr.matrix12;;" " padding-left: 1em;" "}\n" "#tbls > * > tr > *:first-child {" " padding-left: 0;" "}\n" "#tbls > * > tr.tbl-details > * {" " border-top-style: hidden;" "}\n" "#tbl-details {" " font-size: smaller;" "}\n" "#tbl-details > * > tr > * {" " padding-left: 1em;" "}\n" "#tbl-details > * > tr > *:first-child {" " padding-left: 0;" "}\n" "#res {" " font-size: smaller;" " text-align: left;" " border-collapse: collapse;" "}\n" "#res > * > tr {" " vertical-align: top;" "}\n" "#res > * > tr > * {" " border: 1px solid &usr.matrix22;;" "}\n" "#res > * > tr > th {" " font-weight: bold;" " background-color: &usr.matrix12;;" "}\n"
c403b32015-04-02Jonas Walldén  "#res span.warn_exp {" " color: &usr.warncolor;;" " white-space: nowrap;" "}\n"
719f172011-10-27Jonas Wallden  "</style>\n";
9570352001-08-09Per Hedbor  if( id->variables->action && actions[ id->variables->action ]) {
615dac2007-01-18 Erik Dahl  res += "<input type='hidden' name='db' value='&form.db:http;' />\n";
9570352001-08-09Per Hedbor  mixed tmp = actions[ id->variables->action ][1]( id->variables->db, id ); if( stringp( tmp ) ) return res+tmp+"\n</st-page></content></tmpl>";
adcd212001-08-13Per Hedbor  if( tmp ) return tmp;
9570352001-08-09Per Hedbor  }
2f903e2001-03-04Per Hedbor  string url = DBManager.db_url( id->variables->db );
6852922001-07-31Per Hedbor 
e7588f2010-03-31Martin Stjernholm  string charset = "unicode"; #if !constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
4ac0932010-04-06Martin Jonsson  if (DBManager.is_mysql (url)) {
e7588f2010-03-31Martin Stjernholm  // Ugly kludge for broken mysql client lib. Works most of the // time, at least.. charset = "broken-unicode"; } #endif Sql.Sql db; mixed db_connect_error = catch (db = DBManager.get (id->variables->db, 0, 0, 0, charset)); if (db_connect_error) // Try again without charset. db_connect_error = catch (db = DBManager.get (id->variables->db));
f770512010-11-25Henrik Grubbström (Grubba)  if (!db && !db_connect_error) { db_connect_error = ({ "Failed to connect to database.\n", ({}) }); }
e7588f2010-03-31Martin Stjernholm 
6852922001-07-31Per Hedbor  string qres=""; class QueryHistory { inherit Variable.Variable; constant type = "QueryHistory"; void create() { ::create( ([]), 65535 ); } }; object user = id->misc->config_user; QueryHistory hs; if( !(hs = user->settings->getvar( "db_history" ) ) ) { user->settings->defvar( "db_history", (hs = QueryHistory( )) ); user->settings->restore(); }
e6f6392007-05-26Martin Stjernholm  if( (!id->variables->query || id->variables["reset_q.x"]) )
6852922001-07-31Per Hedbor  {
e6f6392007-05-26Martin Stjernholm  array sel_t_columns = ({});
be89b22007-05-26Martin Stjernholm  if( !(<0, "">)[id->variables->table] ) {
e6f6392007-05-26Martin Stjernholm  if (mixed err = catch { sel_t_columns = DBManager.db_table_fields( id->variables->db, id->variables->table ) ->name; }) { report_debug ("Error listing fields for table %s.%s: %s", id->variables->db, id->variables->table, describe_error (err)); } }
6852922001-07-31Per Hedbor  mapping h = hs->query();
e6f6392007-05-26Martin Stjernholm  function(string:string) quote_name = lambda (string s) {return s;}; if (DBManager.is_mysql (id->variables->db)) // FIXME: Ought to be generalized and put into Sql.pmod. quote_name = lambda (string s) { if (db && db->master_sql->is_keyword (s)) return "`" + s + "`"; return s; }; if( !id->variables["reset_q.x"] && h[id->variables->db+"."+id->variables->table] ) id->variables->query = h[id->variables->db+"."+id->variables->table];
be89b22007-05-26Martin Stjernholm  else if( !(<0, "">)[id->variables->table] )
e6f6392007-05-26Martin Stjernholm  id->variables->query = "SELECT "+ (sizeof (sel_t_columns) ? map (sel_t_columns, quote_name) *", " : "*") + " FROM "+ quote_name (id->variables->table); else if( DBManager.is_mysql( id->variables->db ) ) id->variables->query = "SHOW TABLES"; else id->variables->query = "";
e0bd902001-10-01Per Hedbor  }
6852922001-07-31Per Hedbor 
e6f6392007-05-26Martin Stjernholm  if (id->variables["run_q.x"] || id->variables["reset_q.x"])
6852922001-07-31Per Hedbor  hs->query()[ id->variables->db+"."+id->variables->table ] = id->variables->query-"\r";
e6f6392007-05-26Martin Stjernholm  if(db && id->variables["run_q.x"]) {
6852922001-07-31Per Hedbor  user->settings->save(); string query = "";
ce0aea2011-04-07Martin Stjernholm  // Normalize. foreach( (id->variables->query-"\r")/"\n", string q )
6852922001-07-31Per Hedbor  {
ce0aea2011-04-07Martin Stjernholm  //q = (q/" "-({""}))*" "; q = String.trim_all_whites (q);
626aec2011-04-07Martin Stjernholm  if (q == "--") break;
ce0aea2011-04-07Martin Stjernholm  if (q != "") query = (query == "" ? q : query + "\n" + q);
6852922001-07-31Per Hedbor  }
ce0aea2011-04-07Martin Stjernholm 
6324f62011-04-07Martin Stjernholm  foreach( (query/";\n")-({""}); int i; string q )
6852922001-07-31Per Hedbor  {
6324f62011-04-07Martin Stjernholm  Sql.sql_result big_q; int h = gethrtime(); if (mixed err = catch (big_q = db->big_query( q ))) { qres += "<p><font color='&usr.warncolor;'>"+
6a32272011-12-21Jonas Wallden  sprintf((string)_(1062,"Error running query %d: %s"), i + 1,
6324f62011-04-07Martin Stjernholm  replace (Roxen.html_encode_string ( String.trim_all_whites (describe_error(err))), "\n", "<br/>\n"))+
08fa212012-03-26Martin Stjernholm  "</font></p>\n";
6324f62011-04-07Martin Stjernholm  continue; } float qtime = (gethrtime()-h)/1000000.0; if (!big_q) // Query had no result or was empty/commented out. continue;
f3c2002015-04-14Henrik Grubbström (Grubba)  do { int qrows; qres += "<p>\n"
a3bc452018-02-09Jonas Walldén  "<table id='res'><tr class='tr-sticky'>";
f3c2002015-04-14Henrik Grubbström (Grubba)  // FIXME: Using id='res' above is wrong, as the tag // can be generated multiple times in the same // document. See also similar code further below.
6852922001-07-31Per Hedbor  multiset right_columns = (<>);
f3c2002015-04-14Henrik Grubbström (Grubba)  int column; array(string) col_types = ({}); array(string) col_names = ({}); foreach( big_q->fetch_fields(), mapping field )
6852922001-07-31Per Hedbor  {
f3c2002015-04-14Henrik Grubbström (Grubba)  switch( field->type )
6852922001-07-31Per Hedbor  {
6324f62011-04-07Martin Stjernholm  case "char": // Actually a TINYINT.
f3c2002015-04-14Henrik Grubbström (Grubba)  case "tiny integer":
6324f62011-04-07Martin Stjernholm  case "short": case "int":
f3c2002015-04-14Henrik Grubbström (Grubba)  case "integer":
6324f62011-04-07Martin Stjernholm  case "long":
f3c2002015-04-14Henrik Grubbström (Grubba)  case "long integer":
6324f62011-04-07Martin Stjernholm  case "int24": case "longlong": right_columns[column]=1;
f3c2002015-04-14Henrik Grubbström (Grubba)  qres += "<th class='num'>"; col_types += ({"int"}); break; case "real":
6324f62011-04-07Martin Stjernholm  case "float": case "double": right_columns[column]=1;
f3c2002015-04-14Henrik Grubbström (Grubba)  qres += "<th class='num'>"; col_types += ({"float"}); break;
6324f62011-04-07Martin Stjernholm  case "decimal": case "numeric": qres += "<th class='num'>";
f3c2002015-04-14Henrik Grubbström (Grubba)  col_types += ({"string"}); break;
6324f62011-04-07Martin Stjernholm  case "bit": default: qres += "<th>";
f3c2002015-04-14Henrik Grubbström (Grubba)  col_types += ({"string"}); } qres += Roxen.html_encode_string (field->name) + "</th>\n"; col_names += ({ field->name }); column++;
6324f62011-04-07Martin Stjernholm  }
f3c2002015-04-14Henrik Grubbström (Grubba)  qres += "</tr>"; mapping(string:string) mod_info = DBManager.module_table_info (id->variables->db, ""); Configuration c = !(<0, "">)[mod_info->conf] && roxen.find_configuration (mod_info->conf); RoxenModule m = c && !(<0, "">)[mod_info->module] && c->find_module (mod_info->module); // Find any column formatter callback in the DB's owner // module. See function prototype in base_server/module.pike. function(string,string,string,array(string),array(string),array(string), RequestID:string) format_col_cb = m && m->format_db_browser_value; array(int) formatted_total_size = allocate(sizeof(col_names), 0); if (id->variables->exp_fields == "disabled") format_col_cb = 0;
c403b32015-04-02Jonas Walldén 
f3c2002015-04-14Henrik Grubbström (Grubba)  while( array q = big_q->fetch_row() ) { qrows++; qres += "<tr>"; for( int i = 0; i<sizeof(q); i++ ) { qres += right_columns[i] ? "<td class='num'>" : "<td>"; if( !q[i] ) qres += "<i>NULL</i>"; else if( intp( q[i] ) || col_types[i] == "int" ) qres += (string) (int) q[i]; else if( floatp( q[i] ) || col_types[i] == "float" ) qres += (string) (float) q[i]; else if( is_image( q[i] ) ) qres +=
ce77982016-01-15Henrik Grubbström (Grubba)  "<img src='browser.pike?image=" + store_image( q[i] ) + "&amp;&usr.set-wiz-id;' />";
f3c2002015-04-14Henrik Grubbström (Grubba)  else { mixed tmp = q[i]; int got_result; if (format_col_cb) { // Check for excessive amount of formatted data if (formatted_total_size[i] > MAX_TOTAL_FORMATTED_SIZE) {
c403b32015-04-02Jonas Walldén  qres += "<span class='warn_exp'>" +
f3c2002015-04-14Henrik Grubbström (Grubba)  "Total formatted data length exceeded &ndash; limit your query."
c403b32015-04-02Jonas Walldén  "</span>"; got_result = 1;
f3c2002015-04-14Henrik Grubbström (Grubba)  } else if (mixed formatted = format_col_cb (id->variables->db, id->variables->table, col_names[i], col_names, col_types, q, id)) { int formatted_len = sizeof(formatted); if ((formatted_len >= MAX_FIELD_FORMATTED_SIZE) && (id->variables->exp_fields == "auto")) { // This field alone is too big to display qres += "<span class='warn_exp'>" + "Skipping " + (formatted_len / 1024) + "K formatted data." "</span>"; got_result = 1; } else { formatted_total_size[i] += formatted_len; qres += formatted; got_result = 1; }
c403b32015-04-02Jonas Walldén  }
376d412013-11-13Martin Jonsson  }
6852922001-07-31Per Hedbor 
f3c2002015-04-14Henrik Grubbström (Grubba)  if (!got_result) { if (is_deflated (tmp)) { // is_deflated _may_ give false positives, hence the catch. catch { tmp = Gz.inflate()->inflate (tmp); }; }
376d412013-11-13Martin Jonsson 
f3c2002015-04-14Henrik Grubbström (Grubba)  if( is_encode_value( tmp ) ) qres += format_decode_value(tmp); else if (String.width (tmp) > 8) { // Let wide chars skip past the %q quoting, because // it'll quote them to \u escapes otherwise. string q = ""; int s; foreach (tmp; int i; int c) if (c >= 256) { if (s < i) q += sprintf ("%q", tmp[s..i - 1])[1..<1]; q += sprintf ("%c", c); s = i + 1; } q += sprintf ("%q", tmp[s..])[1..<1]; qres += Roxen.html_encode_string (q); }
097e8c2015-04-14Henrik Grubbström (Grubba)  else
f3c2002015-04-14Henrik Grubbström (Grubba)  qres += Roxen.html_encode_string(sprintf("%q", tmp)[1..<1]);
376d412013-11-13Martin Jonsson  }
dfa1592011-06-09Martin Stjernholm  }
f3c2002015-04-14Henrik Grubbström (Grubba)  qres += "</td>";
6852922001-07-31Per Hedbor  }
f3c2002015-04-14Henrik Grubbström (Grubba)  qres += "</tr>\n";
6852922001-07-31Per Hedbor  }
6324f62011-04-07Martin Stjernholm 
f3c2002015-04-14Henrik Grubbström (Grubba)  qres += "</table>"+ sprintf( _(426,"Query took %[0].3fs, %[1]d rows in the reply")+ "\n</p>\n", qtime, qrows); if (!big_q->next_result) break; h = gethrtime(); if (mixed err = catch (big_q = big_q->next_result())) { qres += "<p><font color='&usr.warncolor;'>"+ sprintf((string)_(1062,"Error running query %d: %s"), i + 1, replace (Roxen.html_encode_string ( String.trim_all_whites (describe_error(err))), "\n", "<br/>\n"))+ "</font></p>\n"; break; } qtime = (gethrtime()-h)/1000000.0; if (!big_q) break; // More results available. } while(1);
6852922001-07-31Per Hedbor  } }
be89b22007-05-26Martin Stjernholm  if( !(<0, "">)[id->variables->table] )
e6f6392007-05-26Martin Stjernholm  res += "<input type=hidden name='table' value='&form.table:http;' />\n";
2f903e2001-03-04Per Hedbor 
e6f6392007-05-26Martin Stjernholm  // DB switcher and title.
fcd0c12001-08-14Per Hedbor 
e6f6392007-05-26Martin Stjernholm  res += "<p>" "<table><tr valign='center'>" "<td><cimg border='0' format='gif' src='&usr.database-small;' alt='' " "max-height='20'/></td>" + "<td>" + db_switcher( id ) + "</td></tr></table>\n" "</p>\n" "<h3>Database " + Roxen.html_encode_string (id->variables->db) + "</h3>\n";
fcd0c12001-08-14Per Hedbor 
e7588f2010-03-31Martin Stjernholm  if (db_connect_error) res += "<p><font color='red'>" +
6a32272011-12-21Jonas Wallden  _(1063, "Error connecting to database: ") +
e7588f2010-03-31Martin Stjernholm  Roxen.html_encode_string (describe_error (db_connect_error)) + "</font></p>\n";
e6f6392007-05-26Martin Stjernholm  // Bullet list with generic database info.
fcd0c12001-08-14Per Hedbor 
e6f6392007-05-26Martin Stjernholm  res += "<p><ul>\n";
2f903e2001-03-04Per Hedbor 
1f9fb92017-10-18Henrik Grubbström (Grubba)  switch(id->variables->db) { case "local":
e6f6392007-05-26Martin Stjernholm  res += "<li>" +
fe07f52008-01-10Jonas Wallden  _(546, "Internal data that cannot be shared between servers.") + "</li>\n";
1f9fb92017-10-18Henrik Grubbström (Grubba)  break; case "shared":
e6f6392007-05-26Martin Stjernholm  res += "<li>" +
fe07f52008-01-10Jonas Wallden  _(547, "Internal data that may be shared between servers.") + "</li>\n";
1f9fb92017-10-18Henrik Grubbström (Grubba)  break; case "mysql": res += "<li>" +
bc131e2017-12-20Karl Gustav Sterneberg  _(1140, "MySQL/MariaDB-internal database.") + "</li>\n";
1f9fb92017-10-18Henrik Grubbström (Grubba)  break; case "roxen": res += "<li>" +
bc131e2017-12-20Karl Gustav Sterneberg  _(1141, "Roxen-internal database.") + "</li>\n";
1f9fb92017-10-18Henrik Grubbström (Grubba)  break; default: if( !url ) res += "<li>Internal database.</li>\n"; else res += "<li>Database URL: " + Roxen.html_encode_string(url)+"</li>\n"; break; }
e6f6392007-05-26Martin Stjernholm  mapping(string:string) db_info = DBManager.module_table_info (id->variables->db, ""); if (string owner = format_table_owner (db_info)) res += "<li>" + sprintf((string)_(428,"Defined by %s."), owner) + "</li>\n"; if (string c = db_info->comment) { c = String.trim_all_whites (c); if (c != "") res += "<li>" + Roxen.html_encode_string (c) + "</li>\n"; }
0d30602007-01-17Henrik Grubbström (Grubba)  string default_charset = DBManager.get_db_default_charset(id->variables->db); if (default_charset) {
fe07f52008-01-10Jonas Wallden  res += "<li>" + _(548,"Default charset:") +
e6f6392007-05-26Martin Stjernholm  Roxen.html_encode_string(default_charset) + "</li>";
0d30602007-01-17Henrik Grubbström (Grubba)  }
e6f6392007-05-26Martin Stjernholm  res +="<li>" +
2f4c982001-09-03Per Hedbor  sprintf( (string)
e6f6392007-05-26Martin Stjernholm  _(506,"Member of the %s database group."), "<a href='edit_group.pike?group="+ Roxen.http_encode_url(DBManager.db_group( id->variables->db ))+
e1fff72016-01-15Henrik Grubbström (Grubba)  "&amp;&usr.set-wiz-id;'>" +
2f4c982001-09-03Per Hedbor  DBManager.get_group( DBManager.db_group( id->variables->db ) )
e6f6392007-05-26Martin Stjernholm  ->lname + "</a>") + "</li>";
2f4c982001-09-03Per Hedbor 
c199a02015-10-21Henrik Grubbström (Grubba)  string schedule = DBManager.db_schedule(id->variables->db); if (schedule) { res += "<li>" +
0c7a1e2016-09-27Anders Johansson  sprintf( (string)_(1114, "Backuped via the %s backup schedule."),
c199a02015-10-21Henrik Grubbström (Grubba)  "<a href='schedules.html'>" + Roxen.html_encode_string(schedule) + "</a>") + "</li>"; } else { res += "<li><b>" +
0c7a1e2016-09-27Anders Johansson  _(1115, "Not a member of any backup schedule.") +
c199a02015-10-21Henrik Grubbström (Grubba)  "</b></li>"; }
e6f6392007-05-26Martin Stjernholm  res += "</ul></p>\n";
2f903e2001-03-04Per Hedbor 
e6f6392007-05-26Martin Stjernholm  if (db) { // The database table list.
e0bd902001-10-01Per Hedbor 
e6f6392007-05-26Martin Stjernholm  res += "<p><table id='tbls' border='0' cellpadding='2' cellspacing='0'>";
2f903e2001-03-04Per Hedbor 
e6f6392007-05-26Martin Stjernholm  array table_data = ({});
52c2792007-05-26Martin Stjernholm  int sort_ok, got_owner_column;
2f903e2001-03-04Per Hedbor 
e6f6392007-05-26Martin Stjernholm  string deep_table_info( string table ) { array(mapping(string:mixed)) data = DBManager.db_table_fields( id->variables->db, table ); if( !data ) return sprintf((string)_(507,"Cannot list fields in %s databases"), DBManager.db_driver(id->variables->db) ); multiset(string) props = (<>); foreach (data, mapping(string:mixed) r) foreach (r; string prop;) props[prop] = 1; props->name = 0; // Always listed first. props->type = 0; // Always listed second. props->table = 0; // Just our own table - ignored. array(string) sort_props = sort (indices (props)); string res = "<table id='tbl-details'>" "<tr>" "<th>Column</th>" "<th>Type</th>" + map (sort_props, lambda (string prop) { return "<th>" + Roxen.html_encode_string ( String.capitalize (prop)) + "</th>"; }) * "" + "</tr>\n"; foreach( data, mapping(string:mixed) r ) { res += "<tr>" "<td>" + Roxen.html_encode_string (r->name) + "</td>" "<td>" + Roxen.html_encode_string (r->type) + "</td>"; foreach (sort_props, string prop) { mixed val = r[prop]; if (zero_type (val)) res += "<td></td>"; else if (intp (val) || floatp (val)) res += "<td class='num'>" + val + "</td>"; else if (stringp (val)) res += "<td>" + Roxen.html_encode_string (val) + "</td>"; else if (arrayp (val) && !catch (val = (array(string)) val)) res += "<td>" + Roxen.html_encode_string (val * ", ") + "</td>"; else if (multisetp (val) && !catch (val = (array(string)) indices (val))) res += "<td>" + Roxen.html_encode_string (val * ", ") + "</td>"; else if (objectp (val)) res += "<td>" + Roxen.html_encode_string (sprintf ("%O", val)) + "</td>"; else res += "<td>" + Roxen.html_encode_string (sprintf ("<%t>", val)) + "</td>"; }
2f903e2001-03-04Per Hedbor 
e6f6392007-05-26Martin Stjernholm  res += "</tr>\n"; }
e0bd902001-10-01Per Hedbor 
e6f6392007-05-26Martin Stjernholm  return res+ "</table>"; };
e0bd902001-10-01Per Hedbor 
e6f6392007-05-26Martin Stjernholm  void add_table_info( string table, mapping tbi ) { mapping(string:string) tbl_info = DBManager.module_table_info (id->variables->db, table); int deep_info = id->variables->table == table;
8a890d2017-10-18Henrik Grubbström (Grubba)  string res = "<tr" + (tbl_info->inhibit_backups == "yes"?
3661442017-10-27Anders Johansson  " bgcolor='&usr.fade1;' fgcolor='&usr.top-fgcolor;'":"") +
8a890d2017-10-18Henrik Grubbström (Grubba)  ">"
52c2792007-05-26Martin Stjernholm  "<td style='white-space: nowrap'>" "<a href='browser.pike?sort=&form.sort:http;&amp;"
e1fff72016-01-15Henrik Grubbström (Grubba)  "db=&form.db:http;&amp;&usr.set-wiz-id;" +
e6f6392007-05-26Martin Stjernholm  (deep_info ? "" : "&amp;table="+Roxen.http_encode_url(table)) +"'>"+ "<cimg style='vertical-align: -2px' border='0' format='gif'"
be89b22007-05-26Martin Stjernholm  " src='&usr.table-small;' alt='' max-height='12'/> " + table+"</a></td>"
e6f6392007-05-26Martin Stjernholm  "<td class='num'>"+
4931c22007-11-19 Erik Dahl  (!tbi || zero_type (tbi->rows) ? "" : tbi->rows) + "</td>"
e6f6392007-05-26Martin Stjernholm  "<td class='num'>" +
4931c22007-11-19 Erik Dahl  (!tbi || zero_type (tbi->data_length) ? "" :
52c2792007-05-26Martin Stjernholm  sprintf ("%d KiB",
e6f6392007-05-26Martin Stjernholm  ((int)tbi->data_length+(int)tbi->index_length) / 1024)) + "</td>";
52c2792007-05-26Martin Stjernholm  string owner; if ((db_info->conf || "") != (tbl_info->conf || "")) owner = format_table_owner (tbl_info, 0); else if ((db_info->module || "") != (tbl_info->module || "")) owner = format_table_owner (tbl_info, 1);
b19f302017-10-18Henrik Grubbström (Grubba)  res += "<td>";
52c2792007-05-26Martin Stjernholm  if (owner) {
b19f302017-10-18Henrik Grubbström (Grubba)  res += owner;
52c2792007-05-26Martin Stjernholm  got_owner_column = 1; }
b19f302017-10-18Henrik Grubbström (Grubba)  res += "</td>";
52c2792007-05-26Martin Stjernholm 
e6f6392007-05-26Martin Stjernholm  if (deep_info) { res += "</tr>\n<tr class='tbl-details'><td colspan='5'>"; if (tbl_info->comment) sscanf( tbl_info->comment, "%s\0%s", tbl_info->tbl, tbl_info->comment ); if( tbl_info->tbl && tbl_info->tbl != table) if( tbl_info->tbl != (string)0 ) res += sprintf((string) _(429,"The table is known as %O " "in the module."), tbl_info->tbl ) + "<br/>\n"; else res += sprintf((string) _(430,"The table is an anonymous table defined " "by the module."), tbl_info->tbl ) + "<br/>\n"; if (string c = tbl_info->comment) { c = String.trim_all_whites (c); if (c != "" && c != "0") res += Roxen.html_encode_string (c) + "<br/>\n"; }
2f903e2001-03-04Per Hedbor 
8a890d2017-10-18Henrik Grubbström (Grubba)  if (tbl_info->inhibit_backups == "yes") {
bc131e2017-12-20Karl Gustav Sterneberg  res += _(1142, "The table is not included in backups of this database.") +
8a890d2017-10-18Henrik Grubbström (Grubba)  "<br />\n"; }
e6f6392007-05-26Martin Stjernholm  res += deep_table_info (table) + "</td></tr>\n"; } else res += "</tr>\n";
e0bd902001-10-01Per Hedbor 
e6f6392007-05-26Martin Stjernholm  if( tbi ) sort_ok = 1;
e0bd902001-10-01Per Hedbor 
e6f6392007-05-26Martin Stjernholm  table_data += ({({ table, (tbi ?(int)tbi->data_length+ (int)tbi->index_length:0), (tbi ?(int)tbi->rows:0), res })}); };
e0bd902001-10-01Per Hedbor 
e6f6392007-05-26Martin Stjernholm  foreach( DBManager.db_tables( id->variables->db )-({0}), string tb ) add_table_info(tb, DBManager.db_table_information(id->variables->db, tb));
e0bd902001-10-01Per Hedbor 
e6f6392007-05-26Martin Stjernholm  switch( id->variables->sort ) { default: sort( column( table_data, 0 ), table_data ); break; case "rows": sort( column( table_data, 2 ), table_data ); table_data = reverse( table_data ); break; case "size": sort( column( table_data, 1 ), table_data ); table_data = reverse( table_data ); break; } #define SEL(X,Y) \ ((id->variables->sort == X || (Y && !id->variables->sort)) ? \ "<img style='vertical-align: -2px' src='&usr.selected-indicator;'" \ " border='0' alt='&gt;'/>" : \ "")
2f903e2001-03-04Per Hedbor 
e6f6392007-05-26Martin Stjernholm  if( sort_ok ) {
52c2792007-05-26Martin Stjernholm  if (!got_owner_column) // Try to hide the owner column when it's empty. Doesn't work // in firefox 2.0, though. res += "<col span='3'/><col style='visiblity: collapse'/>\n";
e6f6392007-05-26Martin Stjernholm  res +=
a3bc452018-02-09Jonas Walldén  "<thead><tr class='tr-sticky'>"
e1fff72016-01-15Henrik Grubbström (Grubba)  "<th><a href='browser.pike?db=&form.db:http;&amp;table=&form.table:http;&amp;sort=name&amp;&usr.set-wiz-id;'>"+
e6f6392007-05-26Martin Stjernholm  SEL("name", 1) + _(376,"Name")+ "</a></th>\n"
e1fff72016-01-15Henrik Grubbström (Grubba)  "<th class='num'><a href='browser.pike?db=&form.db:http;&amp;table=&form.table:http;&amp;sort=rows&amp;&usr.set-wiz-id;'>"+
e6f6392007-05-26Martin Stjernholm  SEL("rows",0)+String.capitalize(_(374,"rows"))+ "</a></th>\n"
e1fff72016-01-15Henrik Grubbström (Grubba)  "<th class='num'><a href='browser.pike?db=&form.db:http;&amp;table=&form.table:http;&amp;sort=size&amp;&usr.set-wiz-id;'>"+
e6f6392007-05-26Martin Stjernholm  SEL("size",0)+_(377,"Size")+ "</a></th>\n" "<th>Owner</th>\n" "</tr></thead>\n"; }
2f903e2001-03-04Per Hedbor 
e6f6392007-05-26Martin Stjernholm  res += "<tbody>" + column( table_data, 3 )*"\n" + "</tbody></table></p>\n";
2f903e2001-03-04Per Hedbor 
e6f6392007-05-26Martin Stjernholm  // Query widget.
2f903e2001-03-04Per Hedbor 
c403b32015-04-02Jonas Walldén  string formatter_options = "<span style='font-size: smaller;'>Smart field formatters: </span>" "<default variable='form.exp_fields'>" "<select name='exp_fields'>" " <option value='auto'>Enabled for data &lt; " + (MAX_FIELD_FORMATTED_SIZE / 1024) + "K</option>" " <option value='disabled'>Disabled</option>" " <option value='force'>Force expansion of long fields</option>" "</select>" "</default>" "<br />"; int db_has_formatters = 0; if (id->variables->db) { mapping(string:string) mod_info = DBManager.module_table_info (id->variables->db, ""); Configuration c = !(<0, "">)[mod_info->conf] && roxen.find_configuration (mod_info->conf); RoxenModule m = c && !(<0, "">)[mod_info->module] && c->find_module (mod_info->module); db_has_formatters = m && m->format_db_browser_value; }
e6f6392007-05-26Martin Stjernholm  res +=
f4b1c32011-10-25 Erik Dahl  "<a name='dbquery'></a><p>"
3a29632008-11-27Martin Stjernholm  "<textarea rows='12' cols='90' wrap='soft' name='query' "
de32f72008-11-18Jonas Wallden  " style='font-size: 90%'>" +
c403b32015-04-02Jonas Walldén  Roxen.html_encode_string (id->variables->query) + "</textarea><br />" + (db_has_formatters ? formatter_options : "") +
626aec2011-04-07Martin Stjernholm  "<table><tr><td>"
e6f6392007-05-26Martin Stjernholm  "<submit-gbutton2 name=reset_q> "+_(378,"Reset query")+" </submit-gbutton2>"
626aec2011-04-07Martin Stjernholm  "</td><td>"
e6f6392007-05-26Martin Stjernholm  "<submit-gbutton2 name=run_q> "+_(379,"Run query")+" </submit-gbutton2>"
626aec2011-04-07Martin Stjernholm  "</td><td style='font-size: smaller; padding-left: 10px'>" +
6a32272011-12-21Jonas Wallden  _(1064, "Tip: Put '--' on a line to ignore everything below it.") +
626aec2011-04-07Martin Stjernholm  "</td></tr></table></p>";
e6f6392007-05-26Martin Stjernholm  // Query result. res += qres; }
8b89ed2001-07-24Johan Sundström 
e6f6392007-05-26Martin Stjernholm  // Actions.
9570352001-08-09Per Hedbor 
e6f6392007-05-26Martin Stjernholm  res += "<p>";
e0bd902001-10-01Per Hedbor 
c199a02015-10-21Henrik Grubbström (Grubba)  int flags = DBManager.is_internal(id->variables->db)*3; if (!flags) { mapping(string:mixed) url_info = DBManager.get_db_url_info(id->variables->db); if (url_info && has_prefix(url_info->path, "mysql://")) { // Is external mysql. flags = 2; } } #define ADD_ACTION(X) if(!actions[X][2] || (actions[X][2] & flags) ) \
e1fff72016-01-15Henrik Grubbström (Grubba)  res += sprintf("<a href='%s?db=%s&amp;action=%s&amp;&usr.set-wiz-id;'><gbutton>%s</gbutton></a>\n",\
9570352001-08-09Per Hedbor  id->not_query, id->variables->db, X, actions[X][0] )
2f903e2001-03-04Per Hedbor 
9570352001-08-09Per Hedbor  switch( id->variables->db ) { case "local":
e2d8df2017-12-21Karl Gustav Sterneberg  foreach( ({ "backup","optimize","repair","schedule" }), string x )
9570352001-08-09Per Hedbor  ADD_ACTION( x ); break; default:
e2d8df2017-12-21Karl Gustav Sterneberg  array(string) action_ids = sort( indices( actions ) ); if (DBManager.is_internal( id->variables->db )) { action_ids -= ({ "configure_ext_db_con" }); } foreach( action_ids, string x )
9570352001-08-09Per Hedbor  ADD_ACTION( x ); break;
e0bd902001-10-01Per Hedbor  }
e6f6392007-05-26Martin Stjernholm  return res+"</p></st-page></subtablist></cv-split></content></tmpl>";
b53a4a2001-01-09Per Hedbor }