Advertisement
Guest User

Untitled

a guest
Jun 2nd, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.84 KB | None | 0 0
  1. <?php
  2.  
  3. class Block
  4. {
  5.     private $startIpNum;
  6.     private $endIpNum;
  7.     private $locId;
  8.  
  9.     public function Block( $startIpNum, $endIpNum, $locId )
  10.     {
  11.         $this->startIpNum = (int)$startIpNum;
  12.         $this->endIpNum = (int)$endIpNum;
  13.         $this->locId = (int)$locId;
  14.     }
  15.  
  16.     public function getStartIpNum() { return $this->startIpNum; }
  17.     public function getEndIpNum() { return $this->endIpNum; }
  18.     public function getLocId() { return $this->locId; }
  19. }
  20.  
  21. class Location
  22. {
  23.     private $locId;
  24.     private $country;
  25.     private $region;
  26.     private $city;
  27.     private $postalCode;
  28.     private $latitude;
  29.     private $longitude;
  30.     private $metroCode;
  31.     private $areaCode;
  32.  
  33.     public function Location( $locId, $country, $region, $city, $postalCode, $latitude, $longitude, $metroCode, $areaCode )
  34.     {
  35.         $this->locId = (int)$locId;
  36.         $this->country = (string)$country;
  37.         $this->region = (string)$region;
  38.         $this->city = (string)$city;
  39.         $this->postalCode = (string)$postalCode;
  40.         $this->latitude = (double)$latitude;
  41.         $this->longitude = (double)$longitude;
  42.         $this->metroCode = (int)$metroCode;
  43.         $this->areaCode = (int)$areaCode;
  44.     }
  45.  
  46.     public function getLocId() { return $this->locId; }
  47.     public function getCountry() { return $this->country; }
  48.     public function getRegion() { return $this->region; }
  49.     public function getCity() { return $this->city; }
  50.     public function getPostalCode() { return $this->postalCode; }
  51.     public function getLatitude() { return $this->latitude; }
  52.     public function getLongitude() { return $this->longitude; }
  53.     public function getMetroCode() { return $this->metroCode; }
  54.     public function getAreaCode() { return $this->areaCode; }
  55. }
  56.  
  57. interface BlockReader
  58. {
  59.     /**
  60.       * @returns Block
  61.       */
  62.     public function readEntry();
  63. }
  64.  
  65. class CsvBlockReader implements BlockReader
  66. {
  67.     private $fd;
  68.  
  69.     public function CsvBlockReader( $filename )
  70.     {
  71.         $this->fd = fopen( $filename, "r" );
  72.         if( !$this->fd )
  73.             throw new Exception( "Could not open block csv file $filename" );
  74.  
  75.         // skip copyright line
  76.         fgets( $this->fd );
  77.         // skip header line
  78.         fgets( $this->fd );
  79.     }
  80.  
  81.     public function readEntry()
  82.     {
  83.         $entry = fgetcsv( $this->fd, 0, ",", "\"", "\\" );
  84.         if( !$entry )
  85.             return null;
  86.  
  87.         $startIpNum = (int)$entry[0];
  88.         $endIpNum = (int)$entry[1];
  89.         $locId = (int)$entry[2];
  90.  
  91.         $block = new Block( $startIpNum, $endIpNum, $locId );
  92.  
  93.         return $block;
  94.     }
  95. }
  96.  
  97. interface LocationReader
  98. {
  99.     /**
  100.       * @returns Location
  101.       */
  102.     public function readEntry();
  103. }
  104.  
  105. class CsvLocationReader implements LocationReader
  106. {
  107.     private $fd;
  108.  
  109.     public function CsvLocationReader( $filename )
  110.     {
  111.         $this->fd = fopen( $filename, "r" );
  112.         if( !$this->fd )
  113.             throw new Exception( "Could not open location csv file $filename" );
  114.  
  115.         // skip copyright line
  116.         fgets( $this->fd );
  117.         // skip header line
  118.         fgets( $this->fd );
  119.     }
  120.  
  121.     public function readEntry()
  122.     {
  123.         $entry = fgetcsv( $this->fd, 0, ",", "\"", "\\" );
  124.         if( !$entry )
  125.             return null;
  126.  
  127.         $locId = (int)$entry[0];
  128.         $country = (string)$entry[1];
  129.         $region = (string)$entry[2];
  130.         $city = (string)$entry[3];
  131.         $postalCode = (string)$entry[4];
  132.         $latitude = (double)$entry[5];
  133.         $longitude = (double)$entry[6];
  134.         $metroCode = (int)$entry[7];
  135.         $areaCode = (int)$entry[8];
  136.  
  137.         $location = new Location( $locId, $country, $region, $city, $postalCode, $latitude, $longitude, $metroCode, $areaCode );
  138.  
  139.         return $location;
  140.     }
  141. }
  142.  
  143. interface GeoLiteCityDao
  144. {
  145.     public function insertLocation( Location &$location );
  146.     public function insertBlock( Block &$block );
  147. }
  148.  
  149. class GeoLiteCityDaoException extends Exception
  150. {
  151.     private $debugInfo;
  152.  
  153.     public function __construct( $message, $debugInfo )
  154.     {
  155.         $this->debugInfo = $debugInfo;
  156.         parent::__construct( $message );
  157.     }
  158.  
  159.     public function getDebugInfo()
  160.     {
  161.         return $this->debugInfo;
  162.     }
  163. }
  164.  
  165. class SqlGeoLiteCityDao implements GeoLiteCityDao
  166. {
  167.     protected $conn;
  168.     private $insert_location_stmt = null;
  169.     private $insert_block_stmt = null;
  170.  
  171.     public function SqlGeoLiteCityDao( PDO &$conn )
  172.     {
  173.         $this->conn = $conn;
  174.     }
  175.  
  176.     public function insertLocation( Location &$location )
  177.     {
  178.         if( $this->insert_location_stmt === null )
  179.         {
  180.             $insert_location_sql =
  181. "INSERT INTO Location
  182. (
  183.     locId,
  184.     country,
  185.     region,
  186.     city,
  187.     postalCode,
  188.     location,
  189.     metroCode,
  190.     areaCode
  191. ) VALUES (
  192.     :locId,
  193.     :country,
  194.     :region,
  195.     :city,
  196.     :postalCode,
  197.     Point(:latitude, :longitude),
  198.     :metroCode,
  199.     :areaCode
  200. );";
  201.             $this->insert_location_stmt = $this->conn->prepare( $insert_location_sql );
  202.             if( !$this->insert_location_stmt )
  203.             {
  204.                 $debugInfo = array(
  205.                     "statement" => $insert_location_sql,
  206.                     "errorInfo" => $this->conn->errorInfo()
  207.                 );
  208.                 throw new GeoLiteCityDaoException( "Insert location statement prepare failed", $debugInfo );
  209.             }
  210.         }
  211.  
  212.         $parameters = array(
  213.             ":locId" => $location->getLocId(),
  214.             ":country" => $location->getCountry(),
  215.             ":region" => $location->getRegion(),
  216.             ":city" => $location->getCity(),
  217.             ":postalCode" => $location->getPostalCode(),
  218.             ":longitude" => $location->getLongitude(),
  219.             ":latitude" => $location->getLatitude(),
  220.             ":metroCode" => $location->getMetroCode(),
  221.             ":areaCode" => $location->getAreaCode()
  222.         );
  223.         $ret = $this->insert_location_stmt->execute( $parameters );
  224.         if( $ret !== true )
  225.         {
  226.             $debugInfo = array(
  227.                 "statement" => $insert_location_sql,
  228.                 "parameters" => $parameters,
  229.                 "errorInfo" => $this->insert_location_stmt->errorInfo()
  230.             );
  231.             throw new GeoLiteCityDaoException( "Insert location statement execution failed", $debugInfo );
  232.         }
  233.     }
  234.  
  235.     public function insertBlock( Block &$block )
  236.     {
  237.         if( $this->insert_block_stmt === null )
  238.         {
  239.             $insert_block_sql =
  240. "INSERT INTO Blocks
  241. (
  242.     startIpNum,
  243.     endIpNum,
  244.     locId
  245. ) VALUES (
  246.     :startIpNum,
  247.     :endIpNum,
  248.     :locId
  249. );";
  250.             $this->insert_block_stmt = $this->conn->prepare( $insert_block_sql );
  251.             if( !$this->insert_block_stmt )
  252.             {
  253.                 $debugInfo = array(
  254.                     "statement" => $insert_block_sql,
  255.                     "errorInfo" => $this->conn->errorInfo()
  256.                 );
  257.                 throw new GeoLiteCityDaoException( "Insert block statement prepare failed", $debugInfo );
  258.             }
  259.         }
  260.  
  261.         $parameters = array(
  262.             ":startIpNum" => $block->getStartIpNum(),
  263.             ":endIpNum" => $block->getEndIpNum(),
  264.             ":locId" => $block->getLocId()
  265.         );
  266.         $ret = $this->insert_block_stmt->execute( $parameters );
  267.         if( $ret !== true )
  268.         {
  269.             $debugInfo = array(
  270.                 "statement" => $insert_block_sql,
  271.                 "parameters" => $parameters,
  272.                 "errorInfo" => $this->insert_block_stmt->errorInfo()
  273.             );
  274.             throw new GeoLiteCityDaoException( "Insert block statement execution failed", $debugInfo );
  275.         }
  276.     }
  277. }
  278.  
  279. class ProgressIndicator
  280. {
  281.     private $count_str = "";
  282.  
  283.     public function begin()
  284.     {
  285.         echo "Progress: {$this->count_str}";
  286.         flush();
  287.     }
  288.     protected function clearProgressDisplay()
  289.     {
  290.         for( $i = 0; $i < strlen($this->count_str); $i++ )
  291.         {
  292.             echo "\x08";
  293.         }
  294.     }
  295.  
  296.     public function show( $count )
  297.     {
  298.         $this->clearProgressDisplay();
  299.         $this->count_str = (string)$count;
  300.         echo $this->count_str;
  301.         flush();
  302.     }
  303.     public function end()
  304.     {
  305.         echo "\n";
  306.     }
  307. }
  308.  
  309. class GeoLiteCityImporter
  310. {
  311.     protected $dao;
  312.     protected $location_reader;
  313.     protected $block_reader;
  314.  
  315.     public function GeoLiteCityImporter( GeoLiteCityDao &$dao, LocationReader &$location_reader, BlockReader &$block_reader )
  316.     {
  317.         $this->dao = $dao;
  318.         $this->location_reader = $location_reader;
  319.         $this->block_reader = $block_reader;
  320.     }
  321.  
  322.     public function run()
  323.     {
  324.         echo "Inserting locations.\n";
  325.         $count = 0;
  326.         $progress_indicator = new ProgressIndicator();
  327.         $progress_indicator->begin();
  328.         while( $location = $this->location_reader->readEntry() )
  329.         {
  330.             $this->dao->insertLocation( $location );
  331.  
  332.             $count++;
  333.             if( $count % 1000 == 0 )
  334.             {
  335.                 $progress_indicator->show( $count );
  336.             }
  337.         }
  338.         $progress_indicator->show( $count );
  339.         $progress_indicator->end();
  340.  
  341.         echo "Inserting blocks.\n";
  342.         $count = 0;
  343.         $progress_indicator = new ProgressIndicator();
  344.         $progress_indicator->begin();
  345.         while( $block = $this->block_reader->readEntry() )
  346.         {
  347.             $this->dao->insertBlock( $block );
  348.  
  349.             $count++;
  350.             if( $count % 1000 == 0 )
  351.             {
  352.                 $progress_indicator->show( $count );
  353.             }
  354.         }
  355.         $progress_indicator->show( $count );
  356.         $progress_indicator->end();
  357.     }
  358. }
  359.  
  360. $dsn = "mysql:host=localhost;dbname=GeoLiteCity";
  361. $user = "root";
  362. $pass = "";
  363. $conn = new PDO( $dsn, $user, $pass );
  364.  
  365. $dao = new SqlGeoLiteCityDao( $conn );
  366.  
  367. try
  368. {
  369.     $location_reader = new CsvLocationReader( "GeoLiteCity-Location.csv" );
  370.     $block_reader = new CsvBlockReader( "GeoLiteCity-Blocks.csv" );
  371.  
  372.     $importer = new GeoLiteCityImporter( $dao, $location_reader, $block_reader );
  373.     $importer->run();
  374. } catch( GeoLiteCityDaoException $e )
  375. {
  376.     echo "Dao exception: " . $e->getMessage() . "\n";
  377.     var_dump( $e->getDebugInfo() );
  378.     exit(1);
  379. } catch( Exception $e )
  380. {
  381.     echo "Exception: $e\n";
  382.     exit(1);
  383. }
  384.  
  385. exit(0);
  386.  
  387. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement