summaryrefslogtreecommitdiffstats
path: root/lib/migrate.php
diff options
context:
space:
mode:
authorTom Needham <needham.thomas@gmail.com>2012-03-09 23:33:11 +0000
committerTom Needham <needham.thomas@gmail.com>2012-03-09 23:33:11 +0000
commitc3dfcc5b21620476b6e5bf356b42aee9f0da5874 (patch)
treedfd283814afc627bf450f0480afc5d2e491d8262 /lib/migrate.php
parent691103acd5aad2673b6375726ba24fb56e88451b (diff)
downloadnextcloud-server-c3dfcc5b21620476b6e5bf356b42aee9f0da5874.tar.gz
nextcloud-server-c3dfcc5b21620476b6e5bf356b42aee9f0da5874.zip
First basic implementation of migration.db.
Diffstat (limited to 'lib/migrate.php')
-rw-r--r--lib/migrate.php314
1 files changed, 201 insertions, 113 deletions
diff --git a/lib/migrate.php b/lib/migrate.php
index f3dd3080d30..da7a5ea34ff 100644
--- a/lib/migrate.php
+++ b/lib/migrate.php
@@ -25,7 +25,10 @@
* provides an interface to all search providers
*/
class OC_Migrate{
+
+ static private $MDB2=false;
static private $providers=array();
+ static private $schema=false;
/**
* register a new migration provider
@@ -36,140 +39,225 @@ class OC_Migrate{
}
/**
- * export app data for a user
- * @param string userid
- * @return string xml of app data
+ * @breif creates a migration.db in the users data dir with their app data in
+ * @param @uid string userid of the user to export for
+ * @return bool whether operation was successfull
*/
- public static function export($uid){
+ public static function export( $uid ){
// Only export database users, otherwise we get chaos
- if(OC_User_Database::userExists($uid)){
+ if(!OC_User_Database::userExists( $uid )){
+ return false;
+ }
- $data = array();
- $data['userid'] = OC_User::getUser();
+ // Foreach provider
+ foreach( $providers as $provider ){
+
+ self::createAppTables( $provider->id );
+ // Run the export function
+ $provider->export( $uid );
- $query = OC_DB::prepare( "SELECT uid, password FROM *PREFIX*users WHERE uid LIKE ?" );
- $result = $query->execute( array( $uid));
+ }
+
+ return true;
+
+ }
+
+ /**
+ * @breif imports a new user
+ * @param $uid optional uid to use
+ * @return bool if the import succedded
+ */
+ public static function import( $uid=null ){
+
+ self::$uid = $uid;
+
+ // Connect to the db
+ if(!self::connectDB()){
+ return false;
+ }
+
+ // Create the user
+ if(!self::createUser($uid, $hash)){
+ return false;
+ }
+
+ // Now get the list of apps to import from migration.db
+ // Then check for migrate.php for these apps
+ // If present, run the import function for them.
+
+ return treu;
+
+ }
- $row = $result->fetchRow();
- if($row){
- $data['hash'] = $row['password'];
- } else {
+ // @breif connects to migration.db, or creates if not found
+ // @return bool whether the operation was successful
+ private static function connectDB(){
+
+ // Already connected
+ if(!self::$MDB2){
+ require_once('MDB2.php');
+
+ $datadir = OC_Config::getValue( "datadirectory", "$SERVERROOT/data" );
+
+ // Prepare options array
+ $options = array(
+ 'portability' => MDB2_PORTABILITY_ALL & (!MDB2_PORTABILITY_FIX_CASE),
+ 'log_line_break' => '<br>',
+ 'idxname_format' => '%s',
+ 'debug' => true,
+ 'quote_identifier' => true
+ );
+ $dsn = array(
+ 'phptype' => 'sqlite',
+ 'database' => $datadir.'/'.self::$uid.'/migration.db',
+ 'mode' => '0644'
+ );
+
+ // Try to establish connection
+ self::$MDB2 = MDB2::factory( $dsn, $options );
+
+ // Die if we could not connect
+ if( PEAR::isError( self::$MDB2 )){
+ OC_Log::write('migration', 'Failed to create migration.db',OC_Log::FATAL);
+ OC_Log::write('migration',self::$MDB2->getUserInfo(),OC_Log::FATAL);
+ OC_Log::write('migration',self::$MDB2->getMessage(),OC_Log::FATAL);
return false;
- exit();
}
- foreach(self::$providers as $provider){
-
- $data['apps'][$prodider->appid]['info'] = OC_App::getAppInfo($provider->appid);
- $data['apps'][$provider->appid]['data'] = $provider->export($uid);
+ // We always, really always want associative arrays
+ self::$MDB2->setFetchMode(MDB2_FETCHMODE_ASSOC);
+ }
+ return true;
+
+ }
- }
+ // @breif prepares the db
+ // @param $query the sql query to prepare
+ public static function prepareDB( $query ){
+
+ // Optimize the query
+ $query = self::processQuery( $query );
+
+ // Optimize the query
+ $query = self::$MDB2->prepare( $query );
+
+ // Die if we have an error (error means: bad query, not 0 results!)
+ if( PEAR::isError( $query )) {
+ $entry = 'DB Error: "'.$result->getMessage().'"<br />';
+ $entry .= 'Offending command was: '.$query.'<br />';
+ OC_Log::write('migration',$entry,OC_Log::FATAL);
+ return false;
+ } else {
+ return true;
+ }
+
+ }
- return self::indent(json_encode($data));
+ // @breif processes the db query
+ // @param $query the query to process
+ // @return string of processed query
+ private static function processQuery( $query ){
+ self::connectDB();
+ $type = 'sqlite';
+ $prefix = '';
+
+ $query = str_replace( '`', '\'', $query );
+ $query = str_replace( 'NOW()', 'datetime(\'now\')', $query );
+ $query = str_replace( 'now()', 'datetime(\'now\')', $query );
+
+ // replace table name prefix
+ $query = str_replace( '*PREFIX*', $prefix, $query );
+
+ return $query;
+
+ }
+
+ // @breif creates the tables in migration.db from an apps database.xml
+ // @param $appid string id of the app
+ // @return bool whether the operation was successful
+ private static function createAppTables( $appid ){
+ $file = OC::$SERVERROOT.'/apps/'.$appid.'appinfo/database.xml';
+ if(file_exists( $file )){
+ // There is a database.xml file
+ $content = file_get_contents( $file );
+
+ $file2 = 'static://db_scheme';
+ $content = str_replace( '*dbname*', 'migration', $content );
+ $content = str_replace( '*dbprefix*', '', $content );
+
+ file_put_contents( $file2, $content );
+
+ // Try to create tables
+ $definition = self::$schema->parseDatabaseDefinitionFile( $file2 );
+
+ unlink( $file2 );
+
+ // Die in case something went wrong
+ if( $definition instanceof MDB2_Schema_Error ){
+ OC_Log::write('migration','Failed to parse database.xml for: '.$appid,OC_Log::FATAL);
+ OC_Log::write('migration',$definition->getMessage().': '.$definition->getUserInfo(),OC_Log::FATAL);
+ return false;
+ }
+
+ $definition['overwrite'] = true;
+
+ $ret = self::$schema->createDatabase( $definition );
+ // Die in case something went wrong
+
+ if( $ret instanceof MDB2_Error ){
+ OC_Log::write('migration','Failed to create tables for: '.$appid,OC_Log::FATAL);
+ OC_Log::write('migration',$ret->getMessage().': '.$ret->getUserInfo(),OC_Log::FATAL);
+ return false;
+ }
+ return true;
+
} else {
+ // No database.xml
return false;
}
-
}
- /**
- * @breif imports a new user
- * @param $data json data for the user
- * @param $uid optional uid to use
- * @return json reply
+
+ /**
+ * @brief connects to a MDB2 database scheme
+ * @returns true/false
+ *
+ * Connects to a MDB2 database scheme
*/
- public function import($data,$uid=null){
-
- // Import the data
- $data = json_decode($data);
- if(is_null($data)){
- // TODO LOG
- return false;
- exit();
- }
-
- // Specified user or use original
- $uid = !is_null($uid) ? $uid : $data['userid'];
-
- // Check if userid exists
- if(OC_User::userExists($uid)){
- // TODO LOG
- return false;
- exit();
- }
-
- // Create the user
- $query = OC_DB::prepare( "INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )" );
- $result = $query->execute( array( $uid, $data['hash']));
- if(!$result){
- // TODO LOG
- return false;
- exit();
+ private static function connectScheme(){
+ // We need a mdb2 database connection
+ self::connectDB();
+ self::$MDB2->loadModule( 'Manager' );
+ self::$MDB2->loadModule( 'Reverse' );
+
+ // Connect if this did not happen before
+ if( !self::$schema ){
+ require_once('MDB2/Schema.php');
+ self::$schema=MDB2_Schema::factory( self::$MDB2 );
}
-
- foreach($data['app'] as $app){
- // Check if supports migration and is enabled
- if(in_array($app, self::$providers)){
- if(OC_App::isEnabled($app)){
- $provider->import($data['app'][$app],$uid);
- }
- }
-
- }
-
- }
-
- private static function indent($json){
- $result = '';
- $pos = 0;
- $strLen = strlen($json);
- $indentStr = ' ';
- $newLine = "\n";
- $prevChar = '';
- $outOfQuotes = true;
-
- for ($i=0; $i<=$strLen; $i++) {
-
- // Grab the next character in the string.
- $char = substr($json, $i, 1);
-
- // Are we inside a quoted string?
- if ($char == '"' && $prevChar != '\\') {
- $outOfQuotes = !$outOfQuotes;
-
- // If this character is the end of an element,
- // output a new line and indent the next line.
- } else if(($char == '}' || $char == ']') && $outOfQuotes) {
- $result .= $newLine;
- $pos --;
- for ($j=0; $j<$pos; $j++) {
- $result .= $indentStr;
- }
- }
-
- // Add the character to the result string.
- $result .= $char;
-
- // If the last character was the beginning of an element,
- // output a new line and indent the next line.
- if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) {
- $result .= $newLine;
- if ($char == '{' || $char == '[') {
- $pos ++;
- }
-
- for ($j = 0; $j < $pos; $j++) {
- $result .= $indentStr;
- }
- }
-
- $prevChar = $char;
+ return true;
+ }
+
+ // @breif creates a new user in the database
+ // @param $uid string user_id of the user to be created
+ // @param $hash string hash of the user to be created
+ // @return bool result of user creation
+ private static function createUser( $uid, $hash ){
+
+ // Check if userid exists
+ if(OC_User::userExists( $uid )){
+ return false;
}
- return $result;
- }
+ // Create the user
+ $query = OC_DB::prepare( "INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )" );
+ $result = $query->execute( array( $uid, $data['hash']));
+
+ return $result ? true : false;
+
+ }
}