Check-in [ca0faa88a4]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1 Hash:ca0faa88a4ef6ef2a636587a340fe340c690f6c5
Date: 2012-06-20 17:24:07
User: drh
Comment:Add the ability for an administrator to run raw SQL commands via the web interface.
Tags And Properties
Changes

Changes to src/setup.c

93 "Show artifacts that are shunned by this repository"); 93 "Show artifacts that are shunned by this repository"); 94 setup_menu_entry("Log", "rcvfromlist", 94 setup_menu_entry("Log", "rcvfromlist", 95 "A record of received artifacts and their sources"); 95 "A record of received artifacts and their sources"); 96 setup_menu_entry("User-Log", "access_log", 96 setup_menu_entry("User-Log", "access_log", 97 "A record of login attempts"); 97 "A record of login attempts"); 98 setup_menu_entry("Stats", "stat", 98 setup_menu_entry("Stats", "stat", 99 "Display repository statistics"); 99 "Display repository statistics"); > 100 setup_menu_entry("SQL", "admin_sql", > 101 "Enter raw SQL commands"); 100 @ </table> 102 @ </table> 101 103 102 style_footer(); 104 style_footer(); 103 } 105 } 104 106 105 /* 107 /* 106 ** WEBPAGE: setup_ulist 108 ** WEBPAGE: setup_ulist ................................................................................................................................................................................ 1527 @ 1529 @ 1528 @ <p><span class="note">Note:</span> Your browser has probably cached these 1530 @ <p><span class="note">Note:</span> Your browser has probably cached these 1529 @ images, so you may need to press the Reload button before changes will 1531 @ images, so you may need to press the Reload button before changes will 1530 @ take effect. </p> 1532 @ take effect. </p> 1531 style_footer(); 1533 style_footer(); 1532 db_end_transaction(0); 1534 db_end_transaction(0); 1533 } 1535 } > 1536 > 1537 > 1538 /* > 1539 ** WEBPAGE: admin_sql > 1540 ** > 1541 ** Run raw SQL commands against the database file using the web interface. > 1542 */ > 1543 void sql_page(void){ > 1544 const char *zQ = P("q"); > 1545 int go = P("go")!=0; > 1546 login_check_credentials(); > 1547 if( !g.perm.Setup ){ > 1548 login_needed(); > 1549 } > 1550 db_begin_transaction(); > 1551 style_header("Raw SQL Commands"); > 1552 @ <p><b>Caution:</b> There are no restrictions on the SQL that can be > 1553 @ run by this page. You can do serious and irrepairable damage to the > 1554 @ repository. Proceed with extreme caution.</p> > 1555 @ > 1556 @ <p>Database names:<ul><li>repository &rarr; %s(db_name("repository")) > 1557 if( g.configOpen ){ > 1558 @ <li>config &rarr; %s(db_name("configdb")) > 1559 } > 1560 if( g.localOpen ){ > 1561 @ <li>local-checkout &rarr; %s(db_name("localdb")) > 1562 } > 1563 @ </ul></p> > 1564 @ > 1565 @ <form method="post" action="%s(g.zTop)/admin_sql"> > 1566 login_insert_csrf_secret(); > 1567 @ SQL:<br /> > 1568 @ <textarea name="q" rows="5" cols="80">%h(zQ)</textarea><br /> > 1569 @ <input type="submit" name="go" value="Run SQL"> > 1570 @ <input type="submit" name="schema" value="Show Schema"> > 1571 @ <input type="submit" name="tablelist" value="List Tables"> > 1572 @ </form> > 1573 if( P("schema") ){ > 1574 zQ = sqlite3_mprintf( > 1575 "SELECT sql FROM %s.sqlite_master WHERE sql IS NOT NULL", > 1576 db_name("repository")); > 1577 go = 1; > 1578 }else if( P("tablelist") ){ > 1579 zQ = sqlite3_mprintf( > 1580 "SELECT name FROM %s.sqlite_master WHERE type='table'" > 1581 " ORDER BY name", > 1582 db_name("repository")); > 1583 go = 1; > 1584 } > 1585 if( go ){ > 1586 sqlite3_stmt *pStmt; > 1587 int rc; > 1588 const char *zTail; > 1589 int nCol; > 1590 int nRow = 0; > 1591 int i; > 1592 @ <hr /> > 1593 login_verify_csrf_secret(); > 1594 rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail); > 1595 if( rc!=SQLITE_OK ){ > 1596 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div> > 1597 sqlite3_finalize(pStmt); > 1598 }else if( pStmt==0 ){ > 1599 /* No-op */ > 1600 }else if( (nCol = sqlite3_column_count(pStmt))==0 ){ > 1601 sqlite3_step(pStmt); > 1602 rc = sqlite3_finalize(pStmt); > 1603 if( rc ){ > 1604 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div> > 1605 } > 1606 }else{ > 1607 @ <table border=1> > 1608 while( sqlite3_step(pStmt)==SQLITE_ROW ){ > 1609 if( nRow==0 ){ > 1610 @ <tr> > 1611 for(i=0; i<nCol; i++){ > 1612 @ <th>%h(sqlite3_column_name(pStmt, i))</th> > 1613 } > 1614 @ </tr> > 1615 } > 1616 nRow++; > 1617 @ <tr> > 1618 for(i=0; i<nCol; i++){ > 1619 switch( sqlite3_column_type(pStmt, i) ){ > 1620 case SQLITE_INTEGER: > 1621 case SQLITE_FLOAT: { > 1622 @ <td align="right" valign="top"> > 1623 @ %s(sqlite3_column_text(pStmt, i))</td> > 1624 break; > 1625 } > 1626 case SQLITE_NULL: { > 1627 @ <td valign="top" align="center"><i>NULL</i></td> > 1628 break; > 1629 } > 1630 case SQLITE_TEXT: { > 1631 int k; > 1632 const char *zText = (const char*)sqlite3_column_text(pStmt, i); > 1633 @ <td align="left" valign="top" > 1634 @ style="white-space:pre;">%h(zText)</td> > 1635 break; > 1636 } > 1637 case SQLITE_BLOB: { > 1638 @ <td valign="top" align="center"> > 1639 @ <i>%d(sqlite3_column_bytes(pStmt, i))-byte BLOB</i></td> > 1640 break; > 1641 } > 1642 } > 1643 } > 1644 @ </tr> > 1645 } > 1646 sqlite3_finalize(pStmt); > 1647 @ </table> > 1648 } > 1649 } > 1650 style_footer(); > 1651 }