Browse Source

dry schild

hmt 9 năm trước cách đây
mục cha
commit
1d8583a9e4
2 tập tin đã thay đổi với 138 bổ sung168 xóa
  1. 137 167
      lib/schild.rb
  2. 1 1
      lib/schild/version.rb

+ 137 - 167
lib/schild.rb

@@ -1,120 +1,6 @@
 require 'schild/version'
 require 'sequel'
 
-# erst Ruby 2.1.0 macht include zu einer public-Methode
-if Module.private_method_defined? :include
-  class Module
-    public :include
-  end
-end
-
-# String und Symbol werden um snake_case ergänzt, das die Schild-Tabellen umbenennt
-module CoreExtensions
-  module String
-    def snake_case
-      return downcase if match(/\A[A-Z]+\z/)
-      gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
-        gsub(/([a-z])([A-Z])/, '\1_\2').
-        downcase
-    end
-  end
-
-  module Symbol
-    def snake_case
-      to_s.snake_case
-    end
-  end
-end
-
-# Halten wir Protokoll zu den erstellten Methoden
-# Ist brauchbar, wenn man z.B. noch extremer als der SchildTypeSaver arbeiten möchte
-module MethodLogger
-  class Methods
-    @@accessor_methods = {}
-
-    def self.add(klass, meth)
-      @@accessor_methods[klass] ||= []
-      @@accessor_methods[klass] << meth
-    end
-
-    def self.list(klass)
-      @@accessor_methods[klass]
-    end
-  end
-end
-
-# Schild hat teilweise nil in DB-Feldern. SchildTypeSaver gibt entweder einen
-# Leer-String zurück ("") oder bei strftime das 1899 Datum zurück.
-module SchildTypeSaver
-  Symbol.include CoreExtensions::Symbol
-  String.include CoreExtensions::String
-
-  # bei include wird für jede Spalte in der Schild-Tabelle eine Ersatzmethode
-  # erstellt, die bei nil ein Null-Objekt erstellt.
-  def self.included(klass)
-    klass.columns.each do |column|
-      name = column.snake_case
-      MethodLogger::Methods.add(klass, name)
-      # allow_nil ist als Argument optional und lässt bei +true+ alle Ergebnisse durch
-      define_method(("_"+name.to_s).to_sym) {public_send(column)}
-      define_method(name) do |allow_nil=false|
-        ret = public_send(column)
-        if allow_nil || ret
-          ret = ret.strip if ret.class == String
-          ret
-        else
-         create_null_object(klass, column)
-        end
-      end
-    end
-  end
-
-  def create_null_object(klass, column)
-    k = DB.schema_type_class(klass.db_schema[column][:type])
-    if k.class == Array
-      # Sequel stellt :datetime als [Time, DateTime] dar, deswegen die Abfrage nach Array
-      # Schild verwendet Time Objekte, wir machen das auch
-      Time.new(1899)
-    elsif k == Integer
-      0
-    elsif k == Float
-      0.0
-    else
-      # alle anderen types werden als Klasse zurückgegeben
-      k.new
-    end
-  end
-end
-
-# Mixin für Notenbezeichnungen
-module NotenHelfer
-  # Notenbezeichnung als String
-  def note_s(ziffer)
-    case ziffer
-    when "1", "1+", "1-"
-      "sehr gut"
-    when "2", "2+", "2-"
-      "gut"
-    when "3", "3+", "3-"
-      "befriedigend"
-    when "4", "4+", "4-"
-      "ausreichend"
-    when "5", "5+", "5-"
-      "mangelhaft"
-    when "6"
-      "ungenügend"
-    when 'NB'
-      "––––––"
-    when "E1"
-      "mit besonderem Erfolg teilgenommen"
-    when "E2"
-      "mit Erfolg teilgenommen"
-    when 'E3'
-      "teilgenommen"
-    end
-  end
-end
-
 # Das Schild Modul, das alle Klassen für die Datenbankanbindung bereitstellt
 module Schild
   # ist die Datenbank-Verbindung. Alle Daten können über diese Konstante abgerufen werden
@@ -209,11 +95,137 @@ module Schild
 end
 
 module SchildErweitert
-  include Schild
-  # Stellt die Schüler-Tabelle samt Assoziationen bereit.
-  class Schueler < Schild::Schueler
-    include SchildTypeSaver
+  # erst Ruby 2.1.0 macht include zu einer public-Methode
+  if Module.private_method_defined? :include
+    class Module
+      public :include
+    end
+  end
+
+  # String und Symbol werden um snake_case ergänzt, das die Schild-Tabellen umbenennt
+  module CoreExtensions
+    module String
+      def snake_case
+        return downcase if match(/\A[A-Z]+\z/)
+        gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
+          gsub(/([a-z])([A-Z])/, '\1_\2').
+          downcase
+      end
+    end
+
+    module Symbol
+      def snake_case
+        to_s.snake_case
+      end
+    end
+  end
 
+  # Schild hat teilweise nil in DB-Feldern. SchildTypeSaver gibt entweder einen
+  # Leer-String zurück ("") oder bei strftime das 1899 Datum zurück.
+  module SchildTypeSaver
+    Symbol.include SchildErweitert::CoreExtensions::Symbol
+    String.include CoreExtensions::String
+
+    # bei include wird für jede Spalte in der Schild-Tabelle eine Ersatzmethode
+    # erstellt, die bei nil ein Null-Objekt erstellt.
+    def self.included(klass)
+      klass.columns.each do |column|
+        name = column.snake_case
+        MethodLogger::Methods.add(klass, name)
+        # allow_nil ist als Argument optional und lässt bei +true+ alle Ergebnisse durch
+        define_method(("_"+name.to_s).to_sym) {public_send(column)}
+        define_method(name) do |allow_nil=false|
+        ret = public_send(column)
+        if allow_nil || ret
+          ret = ret.strip if ret.class == String
+          ret
+        else
+          create_null_object(klass, column)
+        end
+        end
+      end
+    end
+
+    def create_null_object(klass, column)
+      k = Schild::DB.schema_type_class(klass.db_schema[column][:type])
+      if k.class == Array
+        # Sequel stellt :datetime als [Time, DateTime] dar, deswegen die Abfrage nach Array
+        # Schild verwendet Time Objekte, wir machen das auch
+        Time.new(1899)
+      elsif k == Integer
+        0
+      elsif k == Float
+        0.0
+      else
+        # alle anderen types werden als Klasse zurückgegeben
+        k.new
+      end
+    end
+  end
+
+  # Halten wir Protokoll zu den erstellten Methoden
+  # Ist brauchbar, wenn man z.B. noch extremer als der SchildTypeSaver arbeiten möchte
+  module MethodLogger
+    class Methods
+      @@accessor_methods = {}
+
+      def self.add(klass, meth)
+        @@accessor_methods[klass] ||= []
+        @@accessor_methods[klass] << meth
+      end
+
+      def self.list(klass)
+        @@accessor_methods[klass]
+      end
+    end
+  end
+
+  # Mixin für Notenbezeichnungen
+  module NotenHelfer
+    # Notenbezeichnung als String
+    def note_s(ziffer)
+      case ziffer
+      when "1", "1+", "1-"
+        "sehr gut"
+      when "2", "2+", "2-"
+        "gut"
+      when "3", "3+", "3-"
+        "befriedigend"
+      when "4", "4+", "4-"
+        "ausreichend"
+      when "5", "5+", "5-"
+        "mangelhaft"
+      when "6"
+        "ungenügend"
+      when 'NB'
+        "––––––"
+      when "E1"
+        "mit besonderem Erfolg teilgenommen"
+      when "E2"
+        "mit Erfolg teilgenommen"
+      when 'E3'
+        "teilgenommen"
+      end
+    end
+  end
+
+  # Klassen sind Konstanten. Deswegen alle auslesen, die Klassen behalten und
+  # dynamisch neue Klassen mit gleichem Namen erstellen.
+  # Automatisch SchildTypeSaver einbinden.
+  #
+  # Sollen zusätzliche Methoden eingebunden werden, muss - wie unten Schueler
+  # und andere Klassen - die neu erstelle Klasse gepatcht werden.
+  # Die alten Methoden bleiben erhalten, d.h. auch die TypeSaver-Methoden.
+  Schild.constants.map {|name| Schild.const_get(name)}.select {|o| o.is_a?(Class)}.each do |klass|
+    name = Schild.const_get(klass.to_s).name.split("::").last
+    klass = Class.new(klass) do
+      include SchildTypeSaver
+    end
+    name = const_set(name, klass)
+  end
+
+  # Stellt die Schüler-Tabelle samt Assoziationen bereit.
+  class Schueler
     # gibt das z.Zt. aktuelle Halbjahr zurück.
     def akt_halbjahr
       abschnitte.last
@@ -268,20 +280,8 @@ module SchildErweitert
     end
   end
 
-  # Dient als Assoziation für Schüler und deren Klassenbezeichnung etc.
-  class Fachklasse < Schild::Fachklasse
-    include SchildTypeSaver
-  end
-
-  # Assoziation für Lehrer, hauptsächlich für Klassenlehrer
-  class Klassenlehrer < Schild::Klassenlehrer
-    include SchildTypeSaver
-  end
-
   # Ist die Assoziation, die Halbjahre, sog. Abschnitte zurückgibt.
-  class Abschnitt < Schild::Abschnitt
-    include SchildTypeSaver
-
+  class Abschnitt
     dataset_module do
       # filtert den Datensatz nach Jahr
       def jahr(i)
@@ -346,8 +346,7 @@ module SchildErweitert
   end
 
   # Assoziation für Noten
-  class Noten < Schild::Noten
-    include SchildTypeSaver
+  class Noten
     include NotenHelfer
 
     # note in String umwandeln
@@ -366,15 +365,9 @@ module SchildErweitert
     end
   end
 
-  # Assoziation für Fächer
-  class Faecher < Schild::Faecher
-    include SchildTypeSaver
-  end
 
   # Assoziation für BK-Abschlussdaten
-  class BKAbschluss < Schild::BKAbschluss
-    include SchildTypeSaver
-
+  class BKAbschluss
     # Ist der Schüler zugelassen?
     def zulassung?
       self.Zulassung == "+"
@@ -392,8 +385,7 @@ module SchildErweitert
   end
 
   # Assoziation für die jeweiligen BK-Prüfungsfächer
-  class BKAbschlussFaecher < Schild::BKAbschlussFaecher
-    include SchildTypeSaver
+  class BKAbschlussFaecher
     include NotenHelfer
 
     # Wurde das Fach schriftlich geprüft?
@@ -411,14 +403,9 @@ module SchildErweitert
     end
   end
 
-  # Assoziation für Abi-Abschlussdaten
-  class AbiAbschluss < Schild::AbiAbschluss
-    include SchildTypeSaver
-  end
 
   # Assoziation für die jeweiligen Abi-Prüfungsfächer
-  class AbiAbschlussFaecher < Schild::AbiAbschlussFaecher
-    include SchildTypeSaver
+  class AbiAbschlussFaecher
     include NotenHelfer
 
     def note(notenart)
@@ -426,22 +413,8 @@ module SchildErweitert
     end
   end
 
-  class Sprachenfolge < Schild::Sprachenfolge
-    include SchildTypeSaver
-  end
-
-  class Vermerke < Schild::Vermerke
-    include SchildTypeSaver
-  end
-
-  class Schuelerfotos < Schild::Schuelerfotos
-    include SchildTypeSaver
-  end
-
   # Schul-Tabelle mit vereinfachtem Zugriff auf Datenfelder.
-  class Schule < Schild::Schule
-    include SchildTypeSaver
-
+  class Schule
     # gibt die Schulnummer zurück
     def self.schulnummer
       self.first.schul_nr
@@ -461,9 +434,7 @@ module SchildErweitert
   end
 
   # Tabelle der Schuld-Benutzer zum Abgleichen der Daten
-  class Nutzer < Schild::Nutzer
-    include SchildTypeSaver
-
+  class Nutzer
     def name
       self.us_name
     end
@@ -487,4 +458,3 @@ module SchildErweitert
     end
   end
 end
-

+ 1 - 1
lib/schild/version.rb

@@ -1,3 +1,3 @@
 module Schild
-  VERSION = "0.6.4"
+  VERSION = "0.7.0"
 end