public function test_should_sharding_table_router_set_and_get_works_fine() { $table = \Myfox\App\Model\Table::instance('numsplit'); try { Router::set('numsplit', array(array('field' => array('thedate' => '20110610'), 'count' => 1201))); $this->assertTrue(false); } catch (\Exception $e) { $this->assertTrue($e instanceof \Myfox\Lib\Exception); $this->assertContains('Column "cid" required for table "numsplit"', $e->getMessage()); } $this->assertEquals(array('cid:1,thedate:20110610' => array(array('rows' => 1000, 'hosts' => '3,1', 'table' => 'numsplit_0.t_' . $table->get('autokid') . '_0'), array('rows' => 201, 'hosts' => '1,2', 'table' => 'numsplit_0.t_' . $table->get('autokid') . '_1')), 'cid:2,thedate:20110610' => array(array('rows' => 998, 'hosts' => '1,2', 'table' => 'numsplit_0.t_' . $table->get('autokid') . '_1'))), Router::set('numsplit', array(array('field' => array('thedate' => '2011-06-10', 'cid' => 1), 'count' => 1201), array('field' => array('thedate' => '2011-06-10', 'cid' => 2), 'count' => 998)))); $this->assertEquals(array(), Router::get('numsplit', array('thedate' => '2011-6-10', 'cid' => 1, 'blablala' => 2))); Router::effect('numsplit', array('thedate' => 20110610, 'cid' => 1), 'numsplit_0.t_' . $table->get('autokid') . '_1', '1,2') && Router::flush(); $routes = Router::get('numsplit', array('thedate' => '2011-6-10', 'cid' => 1, 'blablala' => 2)); $result = array(); foreach ($routes as $item) { unset($item['tabid'], $item['seqid']); $item['mtime'] = $item['mtime'] > 0 ? true : false; $result[] = $item; } $this->assertEquals(array(array('tbidx' => 'test_route_info_c', 'mtime' => true, 'hosts' => '1,2', 'table' => sprintf('numsplit_0.t_%d_1', $table->get('autokid')))), $result); }
/** * OPTIONS: * ---------------------------------------------------------------------- * @file : complete file url, such as "ftp://*****:*****@hostname/path" * @table : name of the logic table * @route : route value of the file, ex: thedate=20111001,cid=210 * @lines : * --------------------------------------------------------------------- */ public function execute() { if (!$this->isReady('table', 'route', 'lines', 'file', 'priority')) { return self::IGNO; } $table = Table::instance($this->option('table')); if (!$table->get('autokid')) { $this->setError(sprintf('Undefined table named as "%s".', $this->option('table'))); return self::IGNO; } try { $routes = Router::set($this->option('table'), array(array('field' => Router::parse($this->option('route'), $this->option('table')), 'count' => (int) $this->option('lines')))); if (!is_array($routes)) { $this->setError('route failed.'); return self::FAIL; } $config = Config::instance('default'); $fname = Fileset::getfile($this->option('file'), $config->get('path/download')); if (empty($fname)) { $this->setError(sprintf('getfile:%s', Fileset::lastError())); return self::FAIL; } $splits = array(); foreach ($routes as $key => $bucket) { foreach ($bucket as $item) { $splits[] = $item['rows']; } } $fsplit = new Fsplit($fname, "\n", 16777216); $chunks = $fsplit->split($splits, $config->get('path/filesplit')); if (empty($chunks)) { $this->setError(sprintf('fsplit failed,%s', $fsplit->lastError())); return self::FAIL; } if (preg_match('/^\\w+:/i', $this->option('file'))) { @unlink($fname); } $result = array(); $queque = Queque::instance(); foreach ($routes as $key => $bucket) { foreach ($bucket as $item) { $fname = array_shift($chunks); if (empty($fname)) { break 2; } $info = array('table' => $this->option('table'), 'route' => $key, 'file' => $fname, 'bucket' => $item['table'], 'hosts' => $item['hosts']); $option = array('openrace' => 0, 'priority' => (int) $this->option('priority'), 'trytimes' => 3, 'task_flag' => Queque::FLAG_WAIT, 'adduser' => 'rsplit'); if (!$queque->insert('import', $info, -1, $option)) { $this->setError(sprintf('queque: %s', $queque->lastError())); return self::FAIL; } $result[] = $queque->lastId(); } } $this->result = implode(',', $result); } catch (\Exception $e) { $this->setError($e->getMessage()); return self::FAIL; } return self::SUCC; }
/** * 计算特定路由的路由值并产生分片规则,外部程序切分文件前调用 * * @access protected * @return void */ protected function actionRoute($param, $post) { if (false === self::priority()) { self::output(1100, 'Access Denied.'); return false; } foreach (array('table', 'route', 'lines') as $key) { if (empty($param[$key])) { self::output(1200, sprintf('Param "%s" is required.', $key)); return false; } } $table = self::vars('table', $param); $route = array(array('field' => Router::parse(self::vars('route', $param), $table), 'count' => (int) self::vars('lines', $param))); try { $routes = Router::set($table, $route); if (!is_array($routes)) { self::output(1300, 'Route failed.'); return; } $output = array(); foreach ($routes as $key => $shard) { foreach ((array) $shard as $split) { $output[] = sprintf("%s\t%s\t%u\t%s\t%s", $param['table'], $key, $split['rows'], $split['hosts'], $split['table']); } } self::output(0, 'OK', implode("\n", $output)); } catch (\Exception $e) { self::output(1400, $e->getMessage()); } }
public function test_should_import_mirror_to_ib_works_fine() { self::cleanTable('default', 'route_info'); $route = \Myfox\App\Model\Router::set('mirror_v2', array()); $route = reset($route); $route = reset($route); $task = new \Myfox\App\Task\Import(10, array('table' => 'mirror_v2', 'route' => '', 'file' => realpath(__DIR__ . '/resource/mirror_import_data_file.txt'), 'bucket' => $route['table'], 'hosts' => '4,5', 'engine' => 'BRIGHTHOUSE'), '999999,-98'); $this->assertEquals(Task::WAIT, $task->execute()); $this->assertEquals(Task::SUCC, $task->wait()); $where = \Myfox\App\Model\Router::instance('mirror_v2')->where(null); $route = self::$mysql->getOne(self::$mysql->query(sprintf("SELECT hosts_list FROM %s WHERE table_name='mirror_v2' AND real_table='%s' AND route_flag = %d", $where['table'], $route['table'], \Myfox\App\Model\Router::FLAG_IMPORT_END))); $route = array_filter(explode(',', trim($route, '{}$'))); sort($route); $this->assertEquals(array(4, 5), $route); $this->assertEquals(true, self::check_table_exists('ibtest_1', 'mirror_v2_0.t_1_0')); $this->assertEquals(true, self::check_table_exists('ibtest_1', 'mirror_v2_0.t_1_1')); $this->assertEquals(true, self::check_table_exists('ibtest_1', 'mirror_v2_0.t_1_2')); $this->assertEquals(true, self::check_table_exists('ibtest_2', 'mirror_v2_0.t_1_0')); $this->assertEquals(true, self::check_table_exists('ibtest_2', 'mirror_v2_0.t_1_1')); $this->assertEquals(true, self::check_table_exists('ibtest_2', 'mirror_v2_0.t_1_2')); }