<commit_before>require 'mysql_c'
require 'do'

module DataObject
  module Mysql
    TYPES = Hash[*Mysql_c.constants.select {|x| x.include?("MYSQL_TYPE")}.map {|x| [Mysql_c.const_get(x), x.gsub(/^MYSQL_TYPE_/, "")]}.flatten]    
    
    QUOTE_STRING = "\""
    QUOTE_COLUMN = "`"
    
    class Connection < DataObject::Connection
      attr_reader :db
      
      def initialize(connection_string)
        @state = STATE_CLOSED
        @connection_string = connection_string
        opts = connection_string.split(" ")
        opts.each do |opt|
          k, v = opt.split("=")
          raise ArgumentError, "you specified an invalid connection component: #{opt}" unless k && v
          instance_variable_set("@#{k}", v)
        end
      end
      
      def change_database(database_name)
        @dbname = database_name
        @connection_string.gsub(/db_name=[^ ]*/, "db_name=#{database_name}")
      end
      
      def open
        @db = Mysql_c.mysql_init(nil)
        raise ConnectionFailed, "could not allocate a MySQL connection" unless @db
        conn = Mysql_c.mysql_real_connect(@db, @host, @user, @password, @dbname, @port || 0, @socket, @flags || 0)
        raise ConnectionFailed, "The connection with connection string #{@connection_string} failed\n#{Mysql_c.mysql_error(@db)}" unless conn
        @state = STATE_OPEN
        true
      end
      
      def close
        if @state == STATE_OPEN
          Mysql_c.mysql_close(@db)
          @state = STATE_CLOSED        
          true
        else
          false
        end
      end
      
      def create_command(text)
        Command.new(self, text)
      end
      
    end
    
    class Reader < DataObject::Reader

      def initialize(db, reader)
        @reader = reader
        unless @reader
          if Mysql_c.mysql_field_count(db) == 0
            @records_affected = Mysql_c.mysql_affected_rows(db)
            close
          else
            raise UnknownError, "An unknown error has occured while trying to process a MySQL query.\n#{Mysql_c.mysql_error(db)}"
          end
        else
          @field_count = @reader.field_count
          @state = STATE_OPEN
          self.next
          fields = Mysql_c.mysql_fetch_fields(@reader)
          @native_fields = fields
          raise UnknownError, "An unknown error has occured while trying to process a MySQL query. There were no fields in the resultset\n#{Mysql_c.mysql_error(db)}" if @reader.field_count == 0
          @native_fields, @fields = [], []
          0.upto(@reader.field_count - 1) do |pos|
            @native_fields << Mysql_c.mysql_fetch_field_direct(@reader, pos)
            @fields << Mysql_c.mysql_fetch_field_direct(@reader, pos).name
          end
          
          @rows = Mysql_c.mysql_num_rows(@reader)
          @has_rows = @rows > 0
        end
      end
      
      def close
        if @state != STATE_CLOSED
          Mysql_c.mysql_free_result(@reader)
          @state = STATE_CLOSED
          true
        else
          false
        end
      end
      
      def name(col)
        super
        @fields[col]
      end
      
      def get_index(name)
        super
        @fields.index(name)
      end
      
      def null?(idx)
        super
        @row[idx] == nil
      end
      
      def item(idx)
        super
        typecast(@row[idx], idx)
      end
      
      def next
        super
        @row = Mysql_c.mysql_fetch_row(@reader)
        close if @row.nil?
        @row ? true : nil
      end
      
      protected
      def native_type(col)
        super
        TYPES[@native_fields[col].type]
      end
      
      def typecast(val, idx)
        return nil if val.nil?
        field = @native_fields[idx]
        case TYPES[field.type]
          when "TINY"
            if field.max_length == 1
              val != "0"
            else
              val.to_i
            end
          when "BIT"
            val.to_i(2)<commit_msg>Using field types<commit_after>require 'mysql_c'
require 'do'

module DataObject
  module Mysql
    TYPES = Hash[*Mysql_c.constants.select {|x| x.include?("MYSQL_TYPE")}.map {|x| [Mysql_c.const_get(x), x.gsub(/^MYSQL_TYPE_/, "")]}.flatten]    
    
    QUOTE_STRING = "\""
    QUOTE_COLUMN = "`"
    
    class Connection < DataObject::Connection
      attr_reader :db
      
      def initialize(connection_string)
        @state = STATE_CLOSED
        @connection_string = connection_string
        opts = connection_string.split(" ")
        opts.each do |opt|
          k, v = opt.split("=")
          raise ArgumentError, "you specified an invalid connection component: #{opt}" unless k && v
          instance_variable_set("@#{k}", v)
        end
      end
      
      def change_database(database_name)
        @dbname = database_name
        @connection_string.gsub(/db_name=[^ ]*/, "db_name=#{database_name}")
      end
      
      def open
        @db = Mysql_c.mysql_init(nil)
        raise ConnectionFailed, "could not allocate a MySQL connection" unless @db
        conn = Mysql_c.mysql_real_connect(@db, @host, @user, @password, @dbname, @port || 0, @socket, @flags || 0)
        raise ConnectionFailed, "The connection with connection string #{@connection_string} failed\n#{Mysql_c.mysql_error(@db)}" unless conn
        @state = STATE_OPEN
        true
      end
      
      def close
        if @state == STATE_OPEN
          Mysql_c.mysql_close(@db)
          @state = STATE_CLOSED        
          true
        else
          false
        end
      end
      
      def create_command(text)
        Command.new(self, text)
      end
      
    end
    
    class Reader < DataObject::Reader

      def initialize(db, reader)
        @reader = reader
        unless @reader
          if Mysql_c.mysql_field_count(db) == 0
            @records_affected = Mysql_c.mysql_affected_rows(db)
            close
          else
            raise UnknownError, "An unknown error has occured while trying to process a MySQL query.\n#{Mysql_c.mysql_error(db)}"
          end
        else
          @field_count = @reader.field_count
          @state = STATE_OPEN
          self.next
          raise UnknownError, "An unknown error has occured while trying to process a MySQL query. There were no fields in the resultset\n#{Mysql_c.mysql_error(db)}" if @reader.field_count == 0
          @native_fields, @fields = [], []
          0.upto(@reader.field_count - 1) do |pos|
            field = Mysql_c.mysql_fetch_field_direct(@reader, pos)
            @native_fields << field.type
            @fields << field.name
            field = nil
          end
          
          @rows = Mysql_c.mysql_num_rows(@reader)
          @has_rows = @rows > 0
        end
      end
      
      def close
        if @state != STATE_CLOSED
          Mysql_c.mysql_free_result(@reader)
          @state = STATE_CLOSED
          true
        else
          false
        end
      end
      
      def name(col)
        super
        @fields[col]
      end
      
      def get_index(name)
        super
        @fields.index(name)
      end
      
      def null?(idx)
        super
        @row[idx] == nil
      end
      
      def item(idx)
        super
        typecast(@row[idx], idx)
      end
      
      def next
        super
        @row = Mysql_c.mysql_fetch_row(@reader)
        close if @row.nil?
        @row ? true : nil
      end
      
      protected
      def native_type(col)
        super
        TYPES[@native_fields[col].type]
      end
      
      def typecast(val, idx)
        return nil if val.nil?
        field = @native_fields[idx]
        case TYPES[field]
          when "TINY"
            val != "0"
          when "BIT"
            val.to_i(2)
{'fraction_non_alphanumeric': 0.0940536338904003, 'fraction_numerical': 0.0024614587381785206, 'mean_word_length': 1.7116262732701089, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4111128', 'n_tokens_mistral': 2385, 'n_tokens_neox': 2338, 'n_words': 558}