Encore du refactoring, cette fois ci dans la classe Base. Regardons le code suivant:

  class Base
    def self.sql(raw_query)
      Database.connection.execute(raw_query)
    end

Le Database.connection.execute me dérange. Il viole la loi de Demeter.

À bien y réfléchir, je n’ai tout simplement pas envie d’exposer la méthode connection, qu’on trouve aussi un peu plus loin dans la class Base:

    def self.save(parameters)
      Recorder.new(Database.connection, self.to_s.downcase, parameters).save
      self.new(parameters)
    end

La classe Database est actuellement comme ça:

  class Database
    @@connection = false

    def self.connect(database_filename)
      @@connection = SQLite3::Database.open(database_filename)
    end

    def self.connected?
      !!@@connection
    end

    def self.connection
      @@connection
    end
  end

Je supprime purement et simplement la méthode connection:

  class Database
    @@connection = false

    def self.connect(database_filename)
      @@connection = SQLite3::Database.open(database_filename)
    end

    def self.connected?
      !!@@connection
    end
  end

Maintenant, on rejoue les tests, qui vont nous indiquer ce qui doit être réécrit:

$ rspec sorm_spec.rb 
[...]
     NoMethodError:
       undefined method `connection' for SORM::Database:Class
     # ./sorm.rb:19:in `sql'
[...]
     NoMethodError:
       undefined method `connection' for SORM::Database:Class
     # ./sorm.rb:23:in `save'
[...]
7 examples, 5 failures

On va simplement créer une méthode Database.execute, qui elle, pourra utiliser l’objet connection:

  class Database
    @@connection = false

    def self.connect(database_filename)
      @@connection = SQLite3::Database.open(database_filename)
    end

    def self.connected?
      !!@@connection
    end

    def self.execute(sql)
      @@connection.execute(sql)
    end
  end

  class Base
    def self.sql(raw_query)
      Database.execute(raw_query)
    end
  # ...

À y regarder de près, je ne suis plus certain de trouver un intérêt à Base.sql. Il faudrait la supprimer puisqu’elle peut être remplacée par Database.execute. Mais il faudra attendre car il y a encore des tests qui ne passent plus, à cause de ce code:

    def self.save(parameters)
      Recorder.new(Database.connection, self.to_s.downcase, parameters).save
      self.new(parameters)
    end

On s’en occupera la prochaine fois.

To be continued

À demain.