text: # -*- coding: utf-8 -*-
  
  import random
  from ..exceptions import ArgumentError
  from ..exceptions.connectors import UnsupportedDriver
  from .mysql_connector import MySQLConnector
  from .postgres_connector import PostgresConnector
  from .sqlite_connector import SQLiteConnector
  from ..connections import (
      MySQLConnection,
      PostgresConnection,
      SQLiteConnection
  )
  
  
  class ConnectionFactory:
  
      CONNECTORS = {
          'sqlite': SQLiteConnector,
          'mysql': MySQLConnector,
          'postgres': PostgresConnector,
          'pgsql': PostgresConnector
      }
  
      CONNECTIONS = {
          'sqlite': SQLiteConnection,
          'mysql': MySQLConnection,
          'postgres': PostgresConnection,
          'pgsql': PostgresConnection
      }
  
      def make(self, config, name=None):
          if 'read' in config:
              return self._create_read_write_connection(config)
  
          return self._create_single_connection(config)
  
      def _create_single_connection(self, config):
          conn = self.create_connector(config).connect(config)
  
          return self._create_connection(
              config['driver'],
              conn,
              config['database'],
              config.get('prefix', ''),
              config
          )
  
      def _create_read_write_connection(self, config):
          connection = self._create_single_connection(
              self._get_write_config(config))
  
          connection.set_read_connection(self._create_read_connection(config))
  
          return connection
  
      def _create_read_connection(self, config):
          read_config = self._get_read_config(config)
  
          return self.create_connector(read_config).connect(read_config)
  
      def _get_read_config(self, config):
          read_config = self._get_read_write_config(config, 'read')
  
          return self._merge_read_write_config(config, read_config)
  
      def _get_write_config(self, config):
          write_config = self._get_read_write_config(config, 'write')
  
          return self._merge_read_write_config(config, write_config)
  
      def _get_read_write_config(self, config, type):
          if config.get(type, []):
              return random.choice(config[type])
  
          return config[type]
  
      def _merge_read_write_config(self, config, merge):
          config = config.copy()
          config.update(merge)
  
          del config['read']
          del config['write']
  
          return config
  
      def create_connector(self, config):
          if 'driver' not in config:
              raise ArgumentError('A driver must be specified')
  
          driver = config['driver']
  
          if driver not in self.CONNECTORS:
              raise UnsupportedDriver(driver)
  
          return self.CONNECTORS[driver](driver)
  
      @classmethod
      def register_connector(cls, name, connector):
          cls.CONNECTORS[connector] = connector
  
      @classmethod
      def register_connection(cls, name, connection):
          cls.CONNECTIONS[name] = connection
  
      def _create_connection(self, driver, connection,
                             database, prefix='', config=None):
          if config is None:
              config = {}
  
          if driver not in self.CONNECTIONS:
              raise UnsupportedDriver(driver)
  
          return self.CONNECTIONS[driver](connection, database, prefix, config)
  