diff options
Diffstat (limited to 'org/db.org')
| -rw-r--r-- | org/db.org | 4808 | 
1 files changed, 4808 insertions, 0 deletions
| diff --git a/org/db.org b/org/db.org new file mode 100644 index 00000000..4a2f216b --- /dev/null +++ b/org/db.org @@ -0,0 +1,4808 @@ +-*- mode: org -*- +#+TITLE:       sisu db sql +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:db:sql: +#+AUTHOR:      Ralph Amissah +#+EMAIL:       [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]] +#+COPYRIGHT:   Copyright (C) 2015 - 2021 Ralph Amissah +#+LANGUAGE:    en +#+STARTUP:     content hideblocks hidestars noindent entitiespretty +#+OPTIONS:     H:3 num:nil toc:t \n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t +#+PROPERTY:    header-args  :exports code +#+PROPERTY:    header-args+ :noweb yes +#+PROPERTY:    header-args+ :eval no +#+PROPERTY:    header-args+ :results no +#+PROPERTY:    header-args+ :cache no +#+PROPERTY:    header-args+ :padline no + +* dbi.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/dbi.rb" +# <<sisu_document_header>> +module  SiSU_DBI                                                                 #% database building +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Screen +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'db_dbi'                             # db_dbi.rb +    include SiSU_DbDBI +  require_relative 'html_lite_shared'                   # html_lite_shared.rb +    include SiSU_FormatShared +  class SQL +    def initialize(opt) +      @opt=opt +      @db=SiSU_Env::InfoDb.new +      if @opt.act[:psql][:set]==:on \ +      or @opt.act[:sqlite][:set]==:on +        @sql_type=if @opt.act[:psql][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :pg +        elsif @opt.act[:psql][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :pg +        elsif @opt.act[:sqlite][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :sqlite +        elsif @opt.act[:sqlite][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :sqlite +        else +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :sqlite +        end +        if    @sql_type==:pg    then SiSU_Env::Load.new('pg',true).prog +        elsif @sql_type==:sqlite then SiSU_Env::Load.new('sqlite3',true).prog +        end +      end +    end +    def maintenance_check(opt,file,line) +      p opt.selections.str +      p "at #{file} #{line}" +    end +    def read_psql +      begin +        begin +          require 'pg' +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('pg NOT FOUND (LoadError)') +        end +        @conn=@db.psql.conn_pg +      rescue +        if @opt.act[:psql_create][:set]==:on +          cX=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]).cX +          puts <<-WOK +manually create the database: "#{cX.green}#{@db.db}#{cX.off}" if it does not yet exist +  #{cX.yellow}createdb #{@db.db}#{cX.off} +          WOK +          #sudo su -p postgres;  createdb #{@db.db}; #[createuser?] +        end +      ensure +      end +    end +    def read_sqlite +      begin +        begin +          begin +            require 'sqlite3' +          rescue LoadError +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +              error('sqlite3 NOT FOUND (LoadError)') +          end +          @conn=@db.sqlite.conn_sqlite3 +        rescue LoadError +          errmsg='sqlite3 NOT FOUND (LoadError)' +          if @opt.act[:no_stop][:set]==:on +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +              error(errmsg + ', ' + 'attempt to proceed without sqlite output (as requested)') +          else +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +              error(errmsg + ', ' + 'STOPPING') +            exit +          end +        end +      end +    end +    def connect +      case @sql_type +      when :pg     then read_psql #read_pg +      when :sqlite then read_sqlite +      end +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        "SQL DB #{@sql_type.upcase}", +        @opt.fno +      ).dbi_title unless @opt.act[:quiet][:set]==:on +      begin +        SiSU_DbDBI::Case.new(@opt,@conn,@sql_type).cases +      rescue +        SiSU_Errors::Rescued.new($!,$@,@cf,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +      begin +      rescue +        connect +      end +    end +  end +end +__END__ +#+END_SRC + +* dbi_discrete.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/dbi_discrete.rb" +# <<sisu_document_header>> +module  SiSU_DBI_Discrete                               #% database building +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Screen +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'db_dbi'                             # db_dbi.rb +    include SiSU_DbDBI +  require_relative 'html_lite_shared'                   # html_lite_shared.rb +    include SiSU_FormatShared +  begin +    require 'fileutils' +      include FileUtils::Verbose +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('fileutils NOT FOUND (LoadError)') +  end +  class SQL +    def initialize(opt) +      SiSU_Env::Load.new('sqlite3',true).prog +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +      @md=@particulars.md +      if @opt.act[:sqlite][:set]==:on +        @sql_type=:sqlite +        if @opt.act[:maintenance][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) +        end +      end +      @output_path=@md.file.output_path.sqlite_discrete.dir +      @filename=@md.file.base_filename.sqlite_discrete +      @file_maint=sql_maintenance_file +      @file="#{@output_path}/#{@filename}" +    end +    def build +      prepare +      create_and_populate +    end +    def maintenance_check(opt,file,line) +      #p opt.selections.str +      p "at #{file} #{line}" +    end +    def prepare +      if not FileTest.directory?(@output_path) +        FileUtils::mkdir_p(@output_path) +      elsif @file +        FileUtils::rm_rf(@file) +      end +    end +    def db_exist?(db,conn) +      msg=%{no connection with sqlite database established, createdb "#{db.sqlite.db}"?} +      if (not (FileTest.file?(db.sqlite.db)) \ +      or FileTest.zero?(db.sqlite.db)) +        puts msg +        exit +      end +      if conn.is_a?(NilClass) +        puts msg +        exit +      end +    end +    def create_and_populate +      db=SiSU_Env::DbOp.new(@md) +      conn=db.sqlite_discrete.conn_sqlite3 +      sdb=SiSU_DbDBI::Create.new(@opt,conn,@file,:sqlite) +      sdb_index=SiSU_DbDBI::Index.new(@opt,conn,@file,:sqlite) +      sdb.output_dir? +      begin +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'SQLite (discrete)', +          "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +        ).green_title_hi unless @opt.act[:quiet][:set]==:on +        sdb.create_db +        sdb.create_table.metadata_and_text +        sdb.create_table.doc_objects +        sdb.create_table.endnotes +        sdb.create_table.endnotes_asterisk +        sdb.create_table.endnotes_plus +        sdb.create_table.urls +        sdb_index.create_indexes +        db_exist?(db,conn) +        sdb_import=SiSU_DbDBI::Import.new(@opt,conn,@file_maint,:sqlite) +        sdb_import.marshal_load +        tell=SiSU_Screen::Ansi.new( +               @opt.act[:color_state][:set], +               "sqlite3 #{db.sqlite.db} database?" +             ) +        tell.puts_grey if @opt.act[:verbose][:set]==:on +      rescue +        SiSU_Errors::Rescued.new($!,$@,'-d').location do +          __LINE__.to_s + ':' + __FILE__ +        end +        sdb.output_dir? +      end +    end +    def read_sqlite +      begin +        begin +          require 'sqlite3' +          @conn=@db.sqlite.conn_sqlite3 +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error('sqlite3 not available') +        ensure +          Dir.chdir(@opt.f_pth[:pth]) +        end +      end +    end +    def connect +      begin +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "DBI (#{@sql_type}) #{@opt.selections.str}", +          @opt.fns +        ).dbi_title unless @opt.act[:quiet][:set]==:on +        @db.sqlite_discrete.conn_sqlite3 +      rescue +        SiSU_Errors::Rescued.new($!,$@,@cf,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def populate +    end +    def sql_maintenance_file +      file=if @opt.act[:maintenance][:set]==:on +        if @opt.fns and not @opt.fns.empty? +          @env=SiSU_Env::InfoEnv.new(@opt.fns) if @opt.fns +          if @sql_type ==:sqlite +            puts "\n#{@env.processing_path.sqlite}/#{@opt.fns}.sql" +          end +          @db=SiSU_Env::InfoDb.new +          @job="sqlite3 #{@db.sqlite.db} < #{@env.processing_path.sqlite}/#{@opt.fns}.sql" +          if @sql_type ==:sqlite +            File.new("#{@env.processing_path.sqlite}/#{@opt.fns}.sql",'w+') +          else +            File.new("#{@env.processing_path.postgresql}/#{@opt.fns}.sql",'w+') +          end +        elsif @opt.fns \ +        and @opt.fns.inspect =~/create/ +          nil #sort variations later +        else nil +        end +      else nil +      end +      file +    end +  end +end +__END__ +#+END_SRC + +* db_dbi.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_dbi.rb" +# <<sisu_document_header>> +module  SiSU_DbDBI +  require_relative 'db_columns'                                             # db_columns.rb +  require_relative 'db_tests'                                               # db_tests.rb +  require_relative 'db_create'                                              # db_create.rb +  require_relative 'db_select'                                              # db_select.rb +  require_relative 'db_indexes'                                             # db_indexes.rb +  require_relative 'db_drop'                                                # db_drop.rb +  require_relative 'db_remove'                                              # db_remove.rb +  require_relative 'db_load_tuple'                                          # db_load_tuple.rb +  require_relative 'db_import'                                              # db_import.rb +  class ColumnSize < SiSU_DbColumns::ColumnSize                             # db_columns.rb +  end +  class Test < SiSU_DbTests::Test                                           # db_tests.rb +  end +  class Create <SiSU_DbCreate::Create                                       # db_create.rb +  end +  class Case <SiSU_DbSelect::Case                                           # db_select.rb +  end +  class Index <SiSU_DbIndex::Index                                          # db_indexes.rb +  end +  class Drop <SiSU_DbDrop::Drop                                             # db_drop.rb +  end +  class Remove <SiSU_DbRemove::Remove                                       # db_remove.rb +  end +  class LoadDocuments <SiSU_DbTuple::LoadDocuments                          # db_load_tuple.rb +  end +  class LoadMetadata <SiSU_DbTuple::LoadMetadata                            # db_load_tuple.rb +  end +  class LoadUrls <SiSU_DbTuple::LoadUrls                                    # db_update urls +  end +  class Import <SiSU_DbImport::Import #<SiSU_DB::ColumnSize                 # db_import.rb +  end +end +__END__ +#+END_SRC + +* db_sqltxt.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_sqltxt.rb" +# <<sisu_document_header>> +module SiSU_DbText +  class Prepare +    def special_character_escape(str) +      str=str.to_s.gsub(/'/m,"''"). #string.gsub!(/'/,"\047") #string.gsub!(/'/,"\\'") +        gsub(/(\\)/m,'\1\1'). #ok but with warnings, double backslash on sqlite #str.gsub!(/[\\]/m,'\\x5C') #ok but with warnings, but not for sqlite #str.gsub!(/(\\)/m,'\1') #ok for sqlite not for pgsql +        gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/m,"<br>\n"). +        gsub(/#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}/m,''). #check +        gsub(/#{Mx[:lnk_o]}\s*(\S+?\.(?:png|jpg))(?:\s+\d+x\d+)?(.+?)#{Mx[:lnk_c]}\S+/m,'[image: \1] \2'). +        gsub(/#{Mx[:lnk_o]}\s*(.+?)\s*#{Mx[:lnk_c]}(?:file|ftp):\/\/\S+?([.,!?]?(?:\s|$))/m,'\1\2'). +        gsub(/#{Mx[:lnk_o]}\s*(.+?)\s*#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m,'\1') +    end +    def clean_searchable_text_from_document_objects(arr) +      en=[] +      arr=(arr.is_a?(String)) ? [ arr ] : arr +      txt_arr=arr.each.map do |s| +        s=s.gsub(/#{Mx[:fa_o]}[a-z]{1,4}#{Mx[:fa_o_c]}/m,''). +            gsub(/#{Mx[:fa_c_o]}[a-z]{1,4}#{Mx[:fa_c]}/m,''). +            gsub(/<br>/m,' ') +        en << s.scan(/#{Mx[:en_a_o]}\s*(.+?)\s*#{Mx[:en_a_c]}/m) +        s=s.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/m,''). +          gsub(/#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/m,''). +          gsub(/ \s+/m,' ') +        #p s if s =~/[^ \nA-Za-z0-9'"`?!#@$%^&*=+,.;:\[\]()<>{}‹›|\\\/~_-]/ +        s +      end +      txt_arr=txt_arr << en +      txt=txt_arr.flatten.join("\n") +      special_character_escape(txt) +    end +    def clean_document_objects_body(arr) +      en=[] +      arr=(arr.is_a?(String)) ? [ arr ] : arr +      txt_arr=arr.each.map do |s| +        en << s.scan(/#{Mx[:en_a_o]}\s*(.+?)\s*#{Mx[:en_a_c]}/m) +        s=s. +          gsub(/#{Mx[:en_a_o]}\s*(\d+).+?#{Mx[:en_a_c]}/m, +            '<sup>\1</sup>'). +          gsub(/#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/m,''). +          gsub(/ \s+/m,' ') +        s +      end +      en_arr=en.flatten.each.map do |e| +        e.sub(/^(\d+)\s*/,'<sup>\1</sup> ') +      end +      txt_arr=txt_arr << en_arr +      txt=txt_arr.flatten.join("\n<br>") +      special_character_escape(txt) +    end +    def clean_searchable_text_from_document_source(arr) +      txt_arr,en=[],[] +      arr=(arr.is_a?(String)) ? arr.split(/\n+/m) : arr +      arr.each do |s| +        s=s.gsub(/([*\/_-])\{(.+?)\}\1/m,'\2'). +          gsub(/^(?:block|group|poem|code)\{/m,''). +          gsub(/^\}(?:block|group|poem|code)/m,''). +          gsub(/\A(?:@\S+:\s+.+)\Z/m,'') +        if s =~/^:A~/ +          if defined? @md.creator \ +          and defined? @md.creator.author \ +          and not @md.creator.author.empty? +            s=s.gsub(/@author/,@md.creator.author) +          else +            SiSU_Screen::Ansi.new( +              'v', +              'WARNING Document Author information missing; provide @creator: :author:', +              @md.fnb +            ).warn unless @md.opt.act[:quiet][:set]==:on +          end +          if defined? @md.title \ +          and defined? @md.title.full \ +          and not @md.title.full.empty? +            s=s.gsub(/@title/,@md.title.full) +          else +            SiSU_Screen::Ansi.new( +              'v', +              'WARNING Document Title missing; provide @title:', +              @md.fnb +            ).warn unless @md.opt.act[:quiet][:set]==:on +          end +        end +        s=s.gsub(/^(?:_[1-9]\*?|_\*)\s+/m,''). +          gsub(/^(?:[1-9]\~(\S+)?)\s+/m,''). +          gsub(/^(?::?[A-C]\~(\S+)?)\s+/m,''). +          gsub(/^%{1,3} .+/m,''). #removed even if contained in code block +          gsub(/<br>/m,' ') +        #en << s.scan(/~\{\s*(.+?)\s*\}~/m) +        s=s.gsub(/~\{.+?\}~/m,''). +          gsub(/ \s+/m,' ') +        ##special_character_escape(s) +        #p s if s =~/[^ \nA-Za-z0-9'"`?!#@$%^&*=+,.;:\[\]()<>{}‹›|\\\/~_-]/ +        s +      end +      txt_arr << arr << en +      txt=txt_arr.flatten.join("\n") +      txt=special_character_escape(txt) +      txt +    end +    def strip_markup(str) #define rules, make same as in dal clean +      str=str.gsub(/#{Mx[:fa_superscript_o]}(\d+)#{Mx[:fa_superscript_c]}/,'[\1]'). +        gsub(/(?: \\;|#{Mx[:nbsp]})+/,' '). +        gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}\d+(.+)#{Mx[:tc_c]}/u,'\1').         #tables +        gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}\d+#{Mx[:tc_p]}/u,' ').                          #tables +        gsub(/#{Mx[:tc_p]}/u,' ').                                                     #tables tidy later +        gsub(/<.+?>/,''). +        gsub(/#{Mx[:lnk_o]}.+?\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}(?:file|ftp)\/\/:\S+ /,' [image] '). # else image names found in search +        gsub(/#{Mx[:lnk_o]}.+?\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,' [image]'). # else image names found in search +        gsub(/\s\s+/,' '). +        strip +    end +    def unique_words(str) +      a=str.scan(/[a-zA-Z0-9\\\/_-]{2,}/) #a=str.scan(/\S+{2,}/) +      str=a.uniq.sort.join(' ') +      str +    end +  end +end +__END__ +#+END_SRC + +* create drop import remove +** db_create.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_create.rb" +# <<sisu_document_header>> +module SiSU_DbCreate +  require_relative 'db_columns'                         # db_columns.rb +  class Create < SiSU_DbColumns::Columns +    require_relative 'se'                               # se.rb +    @@dl=nil +    def initialize(opt,conn,file,sql_type=:pg) +      @opt,@conn,@file,@sql_type=opt,conn,file,sql_type +      @cX=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]).cX +      @comment=(@sql_type==:pg) \ +      ? (SiSU_DbCreate::Comment.new(@conn,@sql_type)) +      : nil +      @@dl ||=SiSU_Env::InfoEnv.new.digest.length +    end +    def available +      DBI.available_drivers.each do |driver| +        puts "Driver: #{driver}" +        DBI.data_sources(driver).each do |dsn| +          puts "\tDatasource: #{dsn}" +        end +      end +    end +    def create_db +      @env=SiSU_Env::InfoEnv.new(@opt.fns) +      tell=(@sql_type==:sqlite) \ +      ? SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'Create SQLite db tables in:', +          %{"#{@file}"} +        ) +      : SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'Create pgSQL db tables in:', +          %{"#{Db[:name_prefix]}#{@env.path.base_markup_dir_stub}"} +        ) +      if (@opt.act[:verbose][:set]==:on \ +      || @opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on) +        tell.dark_grey_title_hi +      end +      SiSU_Env::SystemCall.new.create_pg_db(@env.path.base_markup_dir_stub) if @sql_type==:pg #watch use of path.base_markup_dir_stub instead of stub +    end +    def output_dir? +      dir=SiSU_Env::InfoEnv.new('') +      if @opt.act[:sqlite][:set]==:on +        dir.path.webserv_stub_ensure +      end +    end +    def create_table +      def conn_exec(sql) +        if @sql_type==:pg +          conn_exec_pg(sql) +        elsif @sql_type==:sqlite +          conn_exec_sqlite(sql) +        end +      end +      def conn_exec_pg(sql) +        begin +          @conn.exec_params(sql) +        rescue +          if @conn.is_a?(NilClass) +            errmsg="No pg connection (check pg dependencies)" +            if @opt.act[:no_stop][:set]==:on +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, proceeding without pg output (as requested)") +            else +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, STOPPING") +              exit +            end +          end +        end +      end +      def conn_exec_sqlite(sql) +        begin +          @conn.execute(sql) +        rescue +          if @conn.is_a?(NilClass) +            errmsg="No sqlite3 connection (check sqlite3 dependencies)" +            if @opt.act[:no_stop][:set]==:on +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, proceeding without sqlite output (as requested)") +            else +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, STOPPING") +              exit +            end +          end +        end +      end +      def metadata_and_text +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          currently using sisu_dbi module +          to be populated from document files +          create tables metadata_and_text +          data import through ruby transfer +          } +        end +        create_metadata_and_text=%{ +          CREATE TABLE metadata_and_text ( +            tid                  BIGINT PRIMARY KEY, +            /* title */ +            #{column.title.create_column} +            #{column.title_main.create_column} +            #{column.title_sub.create_column} +            #{column.title_short.create_column} +            #{column.title_edition.create_column} +            #{column.title_note.create_column} +            #{column.title_language.create_column} +            #{column.title_language_char.create_column} +            /* creator */ +            #{column.creator_author.create_column} +            #{column.creator_author_honorific.create_column} +            #{column.creator_author_nationality.create_column} +            #{column.creator_editor.create_column} +            #{column.creator_contributor.create_column} +            #{column.creator_illustrator.create_column} +            #{column.creator_photographer.create_column} +            #{column.creator_translator.create_column} +            #{column.creator_prepared_by.create_column} +            #{column.creator_digitized_by.create_column} +            #{column.creator_audio.create_column} +            #{column.creator_video.create_column} +            /* language */ +            #{column.language_document.create_column} +            #{column.language_document_char.create_column} +            #{column.language_original.create_column} +            #{column.language_original_char.create_column} +            /* date */ +            #{column.date_added_to_site.create_column} +            #{column.date_available.create_column} +            #{column.date_created.create_column} +            #{column.date_issued.create_column} +            #{column.date_modified.create_column} +            #{column.date_published.create_column} +            #{column.date_valid.create_column} +            #{column.date_translated.create_column} +            #{column.date_original_publication.create_column} +            #{column.date_generated.create_column} +            /* publisher */ +            #{column.publisher.create_column} +            /* original */ +            #{column.original_publisher.create_column} +            #{column.original_language.create_column} +            #{column.original_language_char.create_column} +            #{column.original_source.create_column} +            #{column.original_institution.create_column} +            #{column.original_nationality.create_column} +            /* rights */ +            #{column.rights_all.create_column} +            #{column.rights_copyright_text.create_column} +            #{column.rights_copyright_translation.create_column} +            #{column.rights_copyright_illustrations.create_column} +            #{column.rights_copyright_photographs.create_column} +            #{column.rights_copyright_preparation.create_column} +            #{column.rights_copyright_digitization.create_column} +            #{column.rights_copyright_audio.create_column} +            #{column.rights_copyright_video.create_column} +            #{column.rights_license.create_column} +            /* classify */ +            #{column.classify_topic_register.create_column} +            #{column.classify_subject.create_column} +            #{column.classify_loc.create_column} +            #{column.classify_dewey.create_column} +            #{column.classify_keywords.create_column} +            /* identifier */ +            #{column.identifier_oclc.create_column} +            #{column.identifier_isbn.create_column} +            /* notes */ +            #{column.notes_abstract.create_column} +            #{column.notes_description.create_column} +            #{column.notes_comment.create_column} +            #{column.notes_history.create_column} +            #{column.notes_coverage.create_column} +            #{column.notes_relation.create_column} +            /* column.notes_source.create_column */ +            #{column.notes_type.create_column} +            #{column.notes_format.create_column} +            #{column.notes_prefix.create_column} +            #{column.notes_prefix_a.create_column} +            #{column.notes_prefix_b.create_column} +            #{column.notes_suffix.create_column} +            /* src */ +            #{column.src_filename.create_column} +            #{column.src_fingerprint.create_column} +            #{column.src_filesize.create_column} +            #{column.src_word_count.create_column} +            #{column.src_txt.create_column} +            /* misc */ +            #{column.fulltext.create_column} +            #{column.links.create_column.gsub(/,$/,'')} +/*          subj                 VARCHAR(64) NULL, */ +/*          contact              VARCHAR(100) NULL, */ +/*          information          VARCHAR(100) NULL, */ +/*          types                CHAR(1) NULL, */ +/*          writing_focus_nationality VARCHAR(100) NULL, */ +          ); +        } +        conn_exec(create_metadata_and_text) +        @comment.psql.metadata_and_text if @comment +      end +      def doc_objects                                                 # create doc_objects base +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          to be populated from documents files +          create tables doc_objects +          data import through ruby transfer +          } +        end +        create_doc_objects=%{ +          CREATE TABLE doc_objects ( +            lid             BIGINT PRIMARY KEY, +            metadata_tid    BIGINT REFERENCES metadata_and_text, +            ocn             SMALLINT, +            ocnd            VARCHAR(6), +            ocns            VARCHAR(6), +            clean           TEXT NULL, +            body            TEXT NULL, +            book_idx        TEXT NULL, +            seg             VARCHAR(256) NULL, +            lev_an          VARCHAR(1), +            lev             SMALLINT NULL, +            lev0            SMALLINT, +            lev1            SMALLINT, +            lev2            SMALLINT, +            lev3            SMALLINT, +            lev4            SMALLINT, +            lev5            SMALLINT, +            lev6            SMALLINT, +            lev7            SMALLINT, +            en_a            SMALLINT NULL, +            en_z            SMALLINT NULL, +            en_a_asterisk   SMALLINT NULL, +            en_z_asterisk   SMALLINT NULL, +            en_a_plus       SMALLINT NULL, +            en_z_plus       SMALLINT NULL, +            t_of            VARCHAR(16), +            t_is            VARCHAR(16), +            node            VARCHAR(16) NULL, +            parent          VARCHAR(16) NULL, +            digest_clean    CHAR(#{@@dl}), +            digest_all      CHAR(#{@@dl}), +            types           CHAR(1) NULL +          ); +        } +        conn_exec(create_doc_objects) +        @comment.psql.doc_objects if @comment +      end +      def endnotes +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          to be populated from document files +          create tables endnotes +          data import through ruby transfer +          } +        end +        create_endnotes=%{ +          CREATE TABLE endnotes ( +            nid             BIGINT PRIMARY KEY, +            document_lid    BIGINT REFERENCES doc_objects, +            nr              SMALLINT, +            clean           TEXT NULL, +            body            TEXT NULL, +            ocn             SMALLINT, +            ocnd            VARCHAR(6), +            ocns            VARCHAR(6), +            digest_clean    CHAR(#{@@dl}), +            metadata_tid    BIGINT REFERENCES metadata_and_text +          ); +        } +        conn_exec(create_endnotes) +        @comment.psql.endnotes if @comment +      end +      def endnotes_asterisk +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          to be populated from document files +          create tables endnotes_asterisk +          data import through ruby transfer +          } +        end +        create_endnotes_asterisk=%{ +          CREATE TABLE endnotes_asterisk ( +            nid             BIGINT PRIMARY KEY, +            document_lid    BIGINT REFERENCES doc_objects, +            nr              SMALLINT, +            clean           TEXT NULL, +            body            TEXT NULL, +            ocn             SMALLINT, +            ocnd            VARCHAR(6), +            ocns            VARCHAR(6), +            digest_clean    CHAR(#{@@dl}), +            metadata_tid    BIGINT REFERENCES metadata_and_text +          ); +        } +        conn_exec(create_endnotes_asterisk) +        @comment.psql.endnotes_asterisk if @comment +      end +      def endnotes_plus +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          to be populated from document files +          create tables endnotes_plus +          data import through ruby transfer +          } +        end +        create_endnotes_plus=%{ +          CREATE TABLE endnotes_plus ( +            nid             BIGINT PRIMARY KEY, +            document_lid    BIGINT REFERENCES doc_objects, +            nr              SMALLINT, +            clean           TEXT NULL, +            body            TEXT NULL, +            ocn             SMALLINT, +            ocnd            VARCHAR(6), +            ocns            VARCHAR(6), +            digest_clean    CHAR(#{@@dl}), +            metadata_tid    BIGINT REFERENCES metadata_and_text +          ); +        } +        conn_exec(create_endnotes_plus) +        @comment.psql.endnotes_plus if @comment +      end +      def urls                                                       # create doc_objects file links mapping +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          currently using sisu_dbi module +          to be populated from doc_objects files +          create tables urls +          data import through ruby transfer +          } +        end +        create_urls=%{ +          CREATE TABLE urls ( +            metadata_tid    BIGINT REFERENCES metadata_and_text, +            plaintext       varchar(512), +            html_toc        varchar(512), +            html_doc        varchar(512), +            xhtml           varchar(512), +            xml_sax         varchar(512), +            xml_dom         varchar(512), +            odf             varchar(512), +            pdf_p           varchar(512), +            pdf_l           varchar(512), +            concordance     varchar(512), +            latex_p         varchar(512), +            latex_l         varchar(512), +            digest          varchar(512), +            manifest        varchar(512), +            markup          varchar(512), +            sisupod         varchar(512) +          ); +        } +        conn_exec(create_urls) +        @comment.psql.urls if @comment +      end +      self +    end +  end +  class Comment < SiSU_DbColumns::Columns +    def initialize(conn,sql_type=:pg) +      @conn=conn +      if sql_type == :pg then psql +      end +    end +    def psql +      def conn_execute_array(sql_arr) +        @conn.transaction do |conn| +          sql_arr.each do |sql| +            conn.exec_params(sql) +          end +        end +      end +      def metadata_and_text +        sql_arr=[ +          %{COMMENT ON Table metadata_and_text +            IS 'contains SiSU metadata and fulltext for search (including source .sst if shared)';}, +          %{COMMENT ON COLUMN metadata_and_text.tid +            IS 'unique';}, +          %{#{column.title.column_comment}}, +          %{#{column.title_main.column_comment}}, +          %{#{column.title_sub.column_comment}}, +          %{#{column.title_short.column_comment}}, +          %{#{column.title_edition.column_comment}}, +          %{#{column.title_note.column_comment}}, +          %{#{column.title_language.column_comment}}, +          %{#{column.title_language_char.column_comment}}, +          %{#{column.creator_author.column_comment}}, +          %{#{column.creator_author_honorific.column_comment}}, +          %{#{column.creator_author_nationality.column_comment}}, +          %{#{column.creator_editor.column_comment}}, +          %{#{column.creator_contributor.column_comment}}, +          %{#{column.creator_illustrator.column_comment}}, +          %{#{column.creator_photographer.column_comment}}, +          %{#{column.creator_translator.column_comment}}, +          %{#{column.creator_prepared_by.column_comment}}, +          %{#{column.creator_digitized_by.column_comment}}, +          %{#{column.creator_audio.column_comment}}, +          %{#{column.creator_video.column_comment}}, +          %{#{column.language_document.column_comment}}, +          %{#{column.language_document_char.column_comment}}, +          %{#{column.language_original.column_comment}}, +          %{#{column.language_original_char.column_comment}}, +          %{#{column.date_added_to_site.column_comment}}, +          %{#{column.date_available.column_comment}}, +          %{#{column.date_created.column_comment}}, +          %{#{column.date_issued.column_comment}}, +          %{#{column.date_modified.column_comment}}, +          %{#{column.date_published.column_comment}}, +          %{#{column.date_valid.column_comment}}, +          %{#{column.date_translated.column_comment}}, +          %{#{column.date_original_publication.column_comment}}, +          %{#{column.date_generated.column_comment}}, +          %{#{column.publisher.column_comment}}, +          %{#{column.original_publisher.column_comment}}, +          %{#{column.original_language.column_comment}}, +          %{#{column.original_language_char.column_comment}}, +          %{#{column.original_source.column_comment}}, +          %{#{column.original_institution.column_comment}}, +          %{#{column.original_nationality.column_comment}}, +          %{#{column.rights_all.column_comment}}, +          %{#{column.rights_copyright_text.column_comment}}, +          %{#{column.rights_copyright_translation.column_comment}}, +          %{#{column.rights_copyright_illustrations.column_comment}}, +          %{#{column.rights_copyright_photographs.column_comment}}, +          %{#{column.rights_copyright_preparation.column_comment}}, +          %{#{column.rights_copyright_digitization.column_comment}}, +          %{#{column.rights_copyright_audio.column_comment}}, +          %{#{column.rights_copyright_video.column_comment}}, +          %{#{column.rights_license.column_comment}}, +          %{#{column.classify_topic_register.column_comment}}, +          %{#{column.classify_subject.column_comment}}, +          %{#{column.classify_loc.column_comment}}, +          %{#{column.classify_dewey.column_comment}}, +          %{#{column.classify_keywords.column_comment}}, +          %{#{column.identifier_oclc.column_comment}}, +          %{#{column.identifier_isbn.column_comment}}, +          %{#{column.notes_abstract.column_comment}}, +          %{#{column.notes_comment.column_comment}}, +          %{#{column.notes_description.column_comment}}, +          %{#{column.notes_history.column_comment}}, +          %{#{column.notes_coverage.column_comment}}, +          %{#{column.notes_relation.column_comment}}, +          %{#{column.notes_type.column_comment}}, +          %{#{column.notes_format.column_comment}}, +          %{#{column.notes_prefix.column_comment}}, +          %{#{column.notes_prefix_a.column_comment}}, +          %{#{column.notes_prefix_b.column_comment}}, +          %{#{column.notes_suffix.column_comment}}, +          %{#{column.src_filename.column_comment}}, +          %{#{column.src_fingerprint.column_comment}}, +          %{#{column.src_filesize.column_comment}}, +          %{#{column.src_word_count.column_comment}}, +          %{#{column.src_txt.column_comment}}, +          %{#{column.fulltext.column_comment}}, +          %{#{column.links.column_comment}}, +        ] +        conn_execute_array(sql_arr) +      end +      def doc_objects +        sql_arr=[ +          %{COMMENT ON Table doc_objects +            IS 'contains searchable text of SiSU document objects';}, +          %{COMMENT ON COLUMN doc_objects.lid +            IS 'unique';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text';}, +          %{COMMENT ON COLUMN doc_objects.lev_an +            IS 'doc level A-D 1-4';}, +          %{COMMENT ON COLUMN doc_objects.lev +            IS 'doc level 0-7 \d\~';}, +          %{COMMENT ON COLUMN doc_objects.seg +            IS 'segment name from level number 4 (lv 1)';}, +          %{COMMENT ON COLUMN doc_objects.ocn +            IS 'object citation number';}, +          %{COMMENT ON COLUMN doc_objects.en_a +            IS 'first endnote number in text object (eg. NULL or 34) (used with en_z to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_z +            IS 'last endnote number within text object (eg. NULL, 34 or say 47) (used with en_a to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_a_asterisk +            IS 'first endnote number in text object (eg. NULL or 34) (used with en_z_asterisk to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_z_asterisk +            IS 'last endnote number within text object (eg. NULL, 34 or say 47) (used with en_a_asterisk to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_a_plus +            IS 'first endnote number in text object (eg. NULL or 34) (used with en_z_plus to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_z_plus +            IS 'last endnote number within text object (eg. NULL, 34 or say 47) (used with en_a_plus to create range)';}, +          %{COMMENT ON COLUMN doc_objects.types +            IS 'document types seg scroll';}, +          %{COMMENT ON COLUMN doc_objects.clean +            IS 'text object - substantive text: clean, stripped of markup';}, +          %{COMMENT ON COLUMN doc_objects.body +            IS 'text object - substantive text: light html markup';}, +          %{COMMENT ON COLUMN doc_objects.book_idx +            IS 'book index creation information for paragraph, if provided';}, +          %{COMMENT ON COLUMN doc_objects.lev0 +            IS 'document structure, level number 0';}, +          %{COMMENT ON COLUMN doc_objects.lev1 +            IS 'document structure, level number 1';}, +          %{COMMENT ON COLUMN doc_objects.lev2 +            IS 'document structure, level number 2';}, +          %{COMMENT ON COLUMN doc_objects.lev3 +            IS 'document structure, level number 3';}, +          %{COMMENT ON COLUMN doc_objects.lev4 +            IS 'document structure, level number 4';}, +          %{COMMENT ON COLUMN doc_objects.lev5 +            IS 'document structure, level number 5';}, +          %{COMMENT ON COLUMN doc_objects.lev6 +            IS 'document structure, level number 6';}, +          %{COMMENT ON COLUMN doc_objects.lev7 +            IS 'document structure, level number 7';}, +          %{COMMENT ON COLUMN doc_objects.t_of +            IS 'document structure, type of object (object is of)';}, +          %{COMMENT ON COLUMN doc_objects.t_is +            IS 'document structure, object is';}, +          %{COMMENT ON COLUMN doc_objects.node +            IS 'document structure, object node if heading';}, +          %{COMMENT ON COLUMN doc_objects.parent +            IS 'document structure, object parent (is a heading)';} +        ] +        conn_execute_array(sql_arr) +      end +      def endnotes +        sql_arr=[ +          %{COMMENT ON Table endnotes +            IS 'contains searchable text of SiSU documents endnotes';}, +          %{COMMENT ON COLUMN endnotes.nid +            IS 'unique';}, +          %{COMMENT ON COLUMN endnotes.document_lid +            IS 'ties to text block from which referenced';}, +          %{COMMENT ON COLUMN endnotes.nr +            IS 'endnote number <!e_(\d+)!>';}, +          %{COMMENT ON COLUMN endnotes.clean +            IS 'endnote substantive content, stripped of markup';}, +          %{COMMENT ON COLUMN endnotes.body +            IS 'endnote substantive content';}, +          %{COMMENT ON COLUMN endnotes.ocn +            IS 'object citation no# <\~(\d+)> from which endnote is referenced';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text - unique for each document';} +        ] +        conn_execute_array(sql_arr) +      end +      def endnotes_asterisk +        sql_arr=[ +          %{COMMENT ON Table endnotes_asterisk +            IS 'contains searchable text of SiSU documents endnotes marked with asterisk';}, +          %{COMMENT ON COLUMN endnotes_asterisk.nid +            IS 'unique';}, +          %{COMMENT ON COLUMN endnotes_asterisk.document_lid +            IS 'ties to text block from which referenced';}, +          %{COMMENT ON COLUMN endnotes_asterisk.nr +            IS 'endnote number <!e_(\d+)!>';}, +          %{COMMENT ON COLUMN endnotes_asterisk.clean +            IS 'endnote substantive content, stripped of markup';}, +          %{COMMENT ON COLUMN endnotes_asterisk.body +            IS 'endnote substantive content';}, +          %{COMMENT ON COLUMN endnotes_asterisk.ocn +            IS 'object citation no# <\~(\d+)> from which endnote is referenced';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text - unique for each document';} +        ] +        conn_execute_array(sql_arr) +      end +      def endnotes_plus +        sql_arr=[ +          %{COMMENT ON Table endnotes_plus +            IS 'contains searchable text of SiSU documents endnotes marked with plus';}, +          %{COMMENT ON COLUMN endnotes_plus.nid +            IS 'unique';}, +          %{COMMENT ON COLUMN endnotes_plus.document_lid +            IS 'ties to text block from which referenced';}, +          %{COMMENT ON COLUMN endnotes_plus.nr +            IS 'endnote number <!e_(\d+)!>';}, +          %{COMMENT ON COLUMN endnotes_plus.clean +            IS 'endnote substantive content, stripped of markup';}, +          %{COMMENT ON COLUMN endnotes_plus.body +            IS 'endnote substantive content';}, +          %{COMMENT ON COLUMN endnotes_plus.ocn +            IS 'object citation no# <\~(\d+)> from which endnote is referenced';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text - unique for each document';}, +        ] +        conn_execute_array(sql_arr) +      end +      def urls +        sql_arr=[ +          %{COMMENT ON Table urls +            IS 'contains base url links to different SiSU output';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text - unique for each document, the mapping of rows is one to one';}, +          %{COMMENT ON COLUMN urls.plaintext +            IS 'plaintext utf-8';}, +          %{COMMENT ON COLUMN urls.html_toc +            IS 'table of contents for segmented html document';}, +          %{COMMENT ON COLUMN urls.html_doc +            IS 'html document (scroll)';}, +          %{COMMENT ON COLUMN urls.xhtml +            IS 'xhtml document (scroll)';}, +          %{COMMENT ON COLUMN urls.xml_sax +            IS 'xml sax oriented document (scroll)';}, +          %{COMMENT ON COLUMN urls.xml_dom +            IS 'xml dom oriented document (scroll)';}, +          %{COMMENT ON COLUMN urls.odf +            IS 'opendocument format text';}, +          %{COMMENT ON COLUMN urls.pdf_p +            IS 'pdf portrait';}, +          %{COMMENT ON COLUMN urls.pdf_l +            IS 'pdf landscape';}, +          %{COMMENT ON COLUMN urls.concordance +            IS 'rudimentary document index linked to html';}, +          %{COMMENT ON COLUMN urls.latex_p +            IS 'latex portrait';}, +          %{COMMENT ON COLUMN urls.latex_l +            IS 'latex_landscape';}, +          %{COMMENT ON COLUMN urls.markup +            IS 'markup';}, +          %{COMMENT ON COLUMN urls.sisupod +            IS 'SiSU document format .tgz (all SiSU information on document)';}, +        ] +        conn_execute_array(sql_arr) +      end +      self +    end +  end +end +__END__ +#+END_SRC + +** db_drop.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_drop.rb" +# <<sisu_document_header>> +module SiSU_DbDrop +  require_relative 'utils_response'                   # utils_response.rb +  class Drop +    include SiSU_Response +    def initialize(opt,conn,db_info,sql_type) +      @opt,@conn,@db_info,@sql_type=opt,conn,db_info,sql_type +      case @sql_type +      when :sqlite +        cascade='' +      else +        cascade='CASCADE' +      end +      @drop_table=[ +        "DROP TABLE metadata_and_text #{cascade};", +        "DROP TABLE doc_objects #{cascade};", +        "DROP TABLE urls #{cascade};", +        "DROP TABLE endnotes #{cascade};", +        "DROP TABLE endnotes_asterisk #{cascade};", +        "DROP TABLE endnotes_plus #{cascade};", +      ] +    end +    def drop +      def tables                                                              #% drop all tables +        begin +          msg_sqlite="as not all disk space is recovered after dropping the database << #{@db_info.sqlite.db} >>, you may be better off deleting the file, and recreating it as necessary" +          case @sql_type +          when :sqlite +            puts msg_sqlite +            ans=response?('remove sql database?') +            if ans \ +            and File.exist?(@db_info.sqlite.db) +              @conn.close +              File.unlink(@db_info.sqlite.db) +              db=SiSU_Env::InfoDb.new +              conn=db.sqlite.conn_sqlite3 +              sdb=SiSU_DbDBI::Create.new(@opt,conn,@db_info,@sql_type) +              sdb_index=SiSU_DbDBI::Index.new(@opt,conn,@db_info,@sql_type) +              sdb.output_dir? +              begin +                sdb.create_db +                sdb.create_table.metadata_and_text +                sdb.create_table.doc_objects +                sdb.create_table.endnotes +                sdb.create_table.endnotes_asterisk +                sdb.create_table.endnotes_plus +                sdb.create_table.urls +                sdb_index.create_indexes +              rescue +                SiSU_Errors::Rescued.new($!,$@,'-D').location do +                  __LINE__.to_s + ':' + __FILE__ +                end +                sdb.output_dir? +              end +              exit +            else +              @conn.transaction +              @drop_table.each do |d| +                begin +                  @conn.exec_params(d) +                rescue +                  next +                end +                end +              @conn.commit +            end +          when :pg +            @conn.transaction +            @drop_table.each do |d| +              begin +                @conn.exec_params(d) +              rescue +                next +              end +            end +            @conn.commit +          end +        rescue +          case @sql_type +          when :sqlite +            ans=response?('remove sql database?') +            if ans and File.exist?(@db_info.sqlite.db); File.unlink(@db_info.sqlite.db) +            end +          else +            @drop_table.each do |d| +              begin +                @conn.exec_params(d) +              rescue +                next +              end +            end +          end +        ensure +        end +      end +      def indexes +        def conn_execute_array(sql_arr) +          @conn.transaction do |conn| +            sql_arr.each do |sql| +              begin +                conn.exec_params(sql) +              rescue +                next +              end +            end +          end +        end +        def base                                                             #% drop base indexes +          print "\n          drop documents common indexes\n" unless @opt.act[:quiet][:set]==:on +          sql_arr=[ +            %{DROP INDEX idx_title;}, +            %{DROP INDEX idx_author;}, +            %{DROP INDEX idx_filename;}, +            %{DROP INDEX idx_topics;}, +            %{DROP INDEX idx_ocn;}, +            %{DROP INDEX idx_digest_clean;}, +            %{DROP INDEX idx_digest_all;}, +            %{DROP INDEX idx_lev0;}, +            %{DROP INDEX idx_lev1;}, +            %{DROP INDEX idx_lev2;}, +            %{DROP INDEX idx_lev3;}, +            %{DROP INDEX idx_lev4;}, +            %{DROP INDEX idx_lev5;}, +            %{DROP INDEX idx_lev6;}, +            %{DROP INDEX idx_endnote_nr;}, +            %{DROP INDEX idx_digest_en;}, +            %{DROP INDEX idx_endnote_nr_asterisk;}, +            %{DROP INDEX idx_endnote_asterisk;}, +            %{DROP INDEX idx_digest_en_asterisk;}, +            %{DROP INDEX idx_endnote_nr_plus;}, +            %{DROP INDEX idx_endnote_plus;}, +            %{DROP INDEX idx_digest_en_plus}, +          ] +          conn_execute_array(sql_arr) +        end +        def text                                                             #% drop TEXT indexes, sqlite +          print "\n          drop documents TEXT indexes\n" unless @opt.act[:quiet][:set]==:on +          sql_arr=[ +            %{DROP INDEX idx_clean;}, +            %{DROP INDEX idx_endnote}, +          ] +          conn_execute_array(sql_arr) +        end +        self +      end +      indexes.base +      @opt.act[:psql][:set]==:on ? '' : indexes.text +      self +    end +  end +end +__END__ +#+END_SRC + +** db_import.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_import.rb" +# <<sisu_document_header>> +module SiSU_DbImport +  require_relative 'db_columns'                         # db_columns.rb +  require_relative 'db_load_tuple'                      # db_load_tuple.rb +  require_relative 'db_sqltxt'                          # db_sqltxt.rb +  require_relative 'html_lite_shared'                   # html_lite_shared.rb +  class Import < SiSU_DbText::Prepare +    include SiSU_Param +    include SiSU_Screen +    include SiSU_DbAction +    @@dl=nil +    @@hname=nil +    attr_accessor :tp +    def initialize(opt,conn,file_maint,sql_type=:pg) +      @opt,@conn,@file_maint,@sql_type=opt,conn,file_maint,sql_type +      @cX=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]).cX +      @env=SiSU_Env::InfoEnv.new(@opt.fns) +      @dal="#{@env.processing_path.ao}" +      @fnb=if @opt.fns.empty? \ +      or @opt.selections.str.empty? +        '' +      else +        @md=SiSU_Param::Parameters.new(@opt).get +        @md.fnb +      end +      @fnc="#{@dal}/#{@opt.fns}.content.rbm" +      @@seg,@@seg_full='',''                                  #create? consider placing field just before clean text as opposed to seg which contains seg(.html) name info seg_full would contain seg info for levels 5 & 6 where available eg seg_full may be 7.3 (level 5) and 7.3.1 (level 6) where seg  is 7 +      @col=Hash.new('') +      @col[:ocn]='' +      @counter={} +      @db=SiSU_Env::InfoDb.new +      if @sql_type==:sqlite +        @driver_sqlite3= +        (@conn.inspect.match(/^(.{10})/)[1] \ +        == @db.sqlite.conn_sqlite3.inspect.match(/^(.{10})/)[1]) \ +        ? true +        : false +      end +      sql='SELECT MAX(lid) FROM doc_objects' +      begin +        @col[:lid] ||=0 +        @col[:lid]=@driver_sqlite3 \ +        ? @conn.execute( sql ).join.to_i +        : @conn.exec( sql ).getvalue(0,0).to_i +      rescue +        if @opt.act[:maintenance][:set]==:on +          puts "#{__FILE__}:#{__LINE__}" +        end +      end +      @col[:lid]=0 if @col[:lid].nil? or @col[:lid].to_s.empty? +      sql='SELECT MAX(nid) FROM endnotes' +      begin +        @id_n=@driver_sqlite3 \ +        ? @conn.execute( sql ).join.to_i +        : @conn.exec( sql ).getvalue(0,0).to_i +        @id_n ||=0 +      rescue +        if @opt.act[:maintenance][:set]==:on +          puts "#{__FILE__}:#{__LINE__}" +        end +      end +      @id_n =0 if @col[:lid].nil? or @col[:lid].to_s.empty? +      @col[:lv0]=@col[:lv1]=@col[:lv2]=@col[:lv3]=@col[:lv4]=@col[:lv5]=@col[:lv6]=@col[:lv7]=0 +      @db=SiSU_Env::InfoDb.new +      @pdf_fn=SiSU_Env::FileOp.new(@md).base_filename +      @@dl ||=SiSU_Env::InfoEnv.new.digest.length +    end +    def marshal_load +      require_relative 'ao'                               # ao.rb +      @ao_array=SiSU_AO::Source.new(@opt).get             # ao file drawn here +      if (@opt.act[:verbose][:set]==:on \ +      || @opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on) +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "#{@db.psql.db}::#{@opt.fns}" +        ).puts_blue +      end +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Marshal Load', +        @fnc +      ).puts_grey if @opt.act[:verbose][:set]==:on +      select_first_match=%{ +        SELECT metadata_and_text.tid +        FROM metadata_and_text +        WHERE metadata_and_text.src_filename = '#{@md.fns}' +        AND metadata_and_text.language_document_char = '#{@opt.lng}' +      ;} # note, for .ssm: @md.fns (is set during runtime & is) != @opt.fns @md.opt.fns +      file_exist=if @sql_type==:sqlite +        begin +          @conn.get_first_value(select_first_match) +        rescue SQLite3::Exception => e +          # not tested +          puts "Exception occurred" +          puts e +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +            "\n" \ +            + 'Attempting to initialize db' + "\n" \ +            + 'Creating db tables' +          ) +          sdb={ +            create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +            index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +          } +          db_action(sdb).create +        end +      else +        begin +          @conn.exec(select_first_match).field_values("tid")[0] +        rescue PG::Error => e +          err=[ +            e.result.error_field( PG::Result::PG_DIAG_SEVERITY ), +            e.result.error_field( PG::Result::PG_DIAG_SQLSTATE ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_PRIMARY ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_DETAIL ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_HINT ), +            e.result.error_field( PG::Result::PG_DIAG_STATEMENT_POSITION ), +            e.result.error_field( PG::Result::PG_DIAG_INTERNAL_POSITION ), +            e.result.error_field( PG::Result::PG_DIAG_INTERNAL_QUERY ), +            e.result.error_field( PG::Result::PG_DIAG_CONTEXT ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_FILE ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_LINE ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_FUNCTION ), +          ] +          p err +          if err[2] =~/relation "\S+?" does not exist/ \ +          or err.inspect =~/relation "\S+?" does not exist/ +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +              "\n" \ +              + err[2] + "\n" \ +              + 'Attempting to initialize db' + "\n" \ +              + 'Creating db tables' +            ) +            sdb={ +              create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +              index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +            } +            db_action(sdb).create +            retry +          end +        end +      end +      if not file_exist +        t_d=[]                                                              # transaction_data +        t_d << db_import_metadata +        t_d << db_import_documents(@ao_array) +        t_d << db_import_urls(@ao_array,@fnc)                              #import OID on/off +        t_d=t_d.flatten +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          puts @conn.class if defined? @conn.class +          puts @conn.driver_name if defined? @conn.driver_name +          puts @conn.driver if defined? @conn.driver +        end +        begin                                                               #% sql +          if @sql_type==:sqlite +            @conn.transaction do |conn| +              t_d.each do |sql| +                conn.execute(sql) +              end +            end +            #also 'execute' works for sqlite +            #@conn.execute("BEGIN") +            #  t_d.each do |sql| +            #    @conn.execute(sql) +            #  end +            #@conn.execute("COMMIT") +          else +            #'do' works for postgresql +            @conn.exec("BEGIN") +              t_d.each do |sql| +                @conn.exec(sql) +              end +            @conn.exec("COMMIT") +          end +        rescue +          SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +          sqlfn="#{@env.processing_path.sql}/#{@md.fnb}.sql" +          sql=File.new(sqlfn,'w') +          t_d.each {|i| sql.puts i} +          p sqlfn +          if @opt.act[:maintenance][:set]==:on +            puts sql +            p @conn.methods.sort +            puts "#{__FILE__}:#{__LINE__}" +          end +        ensure +        end +      else +        if file_exist +          @db=SiSU_Env::InfoDb.new +          puts "\nfile #{@opt.fns} in language code #{@opt.lng} already exists in database #{@db.psql.db}, use --update instead?" +        end +      end +    end +    def pf_db_import_transaction_open +    end +    def pf_db_import_transaction_close +    end +    def book_idx_hash_to_str(book_idx) +      book_idx=book_idx ? book_idx : '' +      book_idx_str,book_subidx_part='','' +      if not book_idx.empty? +        book_idx_str='' +        book_idx.each_pair do |k0,v0| +          book_idx_str << %{#{k0}+#{v0[:plus]}} +          book_subidx_part='' +          if v0[:sub].length > 0 +            v0[:sub].each do |subterms| +               subterms.each_pair do |k1,v1| +                 book_subidx_part << %{\n  #{k1}+#{v1[:plus]} | } +               end +            end +            book_idx_str=book_idx_str + ':' + book_subidx_part +          end +        end +      end +      book_idx_str +    end +    def db_import_metadata                                                       #% import documents - populate database +      if (@opt.act[:verbose][:set]==:on \ +      || @opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on) +        print %{ #{@cX.grey}import documents dbi_unit #{@cX.off} } +      end +      @tp={} +      @md=SiSU_Param::Parameters.new(@opt).get +#% sisutxt & fulltxt +      if FileTest.exist?(@md.fns) +        txt_arr=IO.readlines(@md.fns,'') +        src=txt_arr.join("\n") +        src=special_character_escape(src) +        @tp[:sisutxt_f],@tp[:sisutxt_i]='sisutxt, ',"'#{src}', " +        txt=clean_searchable_text_from_document_source(txt_arr) +        #txt=special_character_escape(txt) +        @tp[:fulltxt_f],@tp[:fulltxt_i]='fulltxt, ',"'#{txt}', " +      end +#% title +      if defined? @md.title.full \ +      and @md.title.full=~/\S+/                                              # DublinCore 1 - title +        #@tp[:title]=@md.title.full +        #special_character_escape(@tp[:title]) +        #@tp[:title_f],@tp[:title_i]='title, ',"'#{@tp[:title]}', " +        sql='SELECT MAX(tid) FROM metadata_and_text;' +        begin +          @@id_t ||=0 +          id_t=@driver_sqlite3 \ +          ? @conn.execute( sql ).join.to_i # { |x| id_t=x.join.to_i } +          : @conn.exec( sql ).getvalue(0,0).to_i +          @@id_t=id_t if id_t +        rescue +          if @opt.act[:maintenance][:set]==:on +            puts "#{__FILE__} #{__LINE__}" +          end +        end +        @@id_t+=1 #bug related, needs to be performed once at start of file, but consider moving, as, placed here it means program will fail if document header lacks @title: +        if (@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          puts %{\n#{@cX.grey}Processing file number#{@cX.off}: #{@cX.green}#{@@id_t}#{@@cX.off}} +        end +      end +      ################ CLEAR ############## +      SiSU_DbDBI::Test.new(self,@opt).verify                          #% import title names, filenames (tuple) +      t=SiSU_DbTuple::LoadMetadata.new(@conn,@@id_t,@md,@file_maint) +      tuple=t.tuple +      tuple +    end +    def db_import_documents(ao_array)                                     #% import documents - populate main database table, import into substantive database tables (tuple) +      begin +        @col[:tid]=@@id_t +        @en,@en_ast,@en_pls,@tuple_array=[],[],[],[] +        @col[:en_a],@col[:en_z]=nil,nil +        ao_array.each do |data| +          data.obj=data.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'\1'). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'\1'). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'\1'). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'\1'). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'\1'). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'\1'). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'\1'). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'\1'). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'\1'). +            gsub(/#{Mx[:gl_o]}(●)#{Mx[:gl_c]}\s*/,'\1 '). +            gsub(/#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}/,'') #check +          @col[:seg]=@@seg +          if data.of ==:para \ +          || data.of ==:heading \ +          || data.of ==:heading_insert \ +          || data.of ==:block \ +          || data.of ==:group      # regular text what of code-blocks grouped text etc. +            notedata=data.obj.dup +                                                                               #% :headings +            if data.is==:heading \ +            && (data.ln.inspect=~/[0-3]/) +              ( +                @col[:lev], +                txt,@col[:ocn], +                @col[:lev_an], +                @col[:ocnd],@col[:ocns], +                @col[:t_of],@col[:t_is], +                @col[:node],@col[:parent], +                @col[:digest_clean],@col[:digest_all]= +                data.ln, +                data.obj,data.ocn, +                data.lv, +                data.odv,data.osp, +                data.of,data.is, +                data.node,data.parent, +                '','' +              ) +              @col[:lid]+=1 +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_minus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              if @en[0] then @en_a,@en_z=@en[0].first,@en[0].last +              end +              if @en_ast[0] then @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last +              end +              if @en_pls[0] then @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last +              end +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              case @col[:lev] +              when /0/ then @col[:lv0]+=1 +              when /1/ then @col[:lv1]+=1 +              when /2/ then @col[:lv2]+=1 +              when /3/ then @col[:lv3]+=1 +              when /4/ then @col[:lv4]+=1 +              end +              @col[:lev]=@col[:plaintext]=@col[:body]='' +            elsif data.is==:heading \ +            && data.ln==4 +              ( +                @@seg,txt, +                @col[:ocn],@col[:lev_an], +                @col[:ocnd],@col[:ocns], +                @col[:t_of],@col[:t_is], +                @col[:node],@col[:parent], +                @col[:digest_clean],@col[:digest_all]= +                data.name,data.obj, +                data.ocn,data.lv, +                data.odv,data.osp, +                data.of,data.is, +                data.node,data.parent, +                '','' +              ) +              @col[:seg]=@@seg +              @col[:lv4]+=1 +              @col[:lid]+=1 +              @col[:lev]=4 +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_plus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @col[:lev]=@col[:plaintext]=@col[:body]='' +            elsif data.is==:heading \ +            && data.ln==5 +              ( +                txt, +                @col[:ocn],@col[:lev_an], +                @col[:ocnd],@col[:ocns], +                @col[:t_of],@col[:t_is], +                @col[:node],@col[:parent], +                @col[:digest_clean],@col[:digest_all]= +                data.obj, +                data.ocn,data.lv, +                data.odv,data.osp, +                data.of,data.is, +                data.node,data.parent, +                '','' +              ) +              @@seg_full=data.name if data.is==:heading \ +              && data.ln==5 \ +              && data.name #check data.name +              @@seg ||='' #nil # watch +              @col[:seg]=@@seg +              @col[:lv5]+=1 +              @col[:lid]+=1 +              @col[:lev]=5 +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_plus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @col[:lev]=@col[:plaintext]=@col[:body]='' +            elsif data.is==:heading \ +            && data.ln==6 +              txt,       @col[:ocn],@col[:lev_an],@col[:ocnd],@col[:ocns],@col[:t_of],@col[:t_is],@col[:node],@col[:parent],@col[:digest_clean],@col[:digest_all]= +                data.obj,data.ocn,  data.lv,      data.odv,   data.osp,   data.of,    data.is,    data.node,  data.parent,  '',                 '' +              @@seg_full=data.name if data.is==:heading && data.ln==6 && data.name #check data.name +              @@seg ||='' #nil # watch +              @col[:seg]=@@seg +              @col[:lv6]+=1 +              @col[:lid]+=1 +              @col[:lev]=6 +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_plus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @col[:lev]=@col[:plaintext]=@col[:body]='' +            elsif data.is==:heading \ +            && data.ln==7 +              txt,       @col[:ocn],@col[:lev_an],@col[:ocnd],@col[:ocns],@col[:t_of],@col[:t_is],@col[:node],@col[:parent],@col[:digest_clean],@col[:digest_all]= +                data.obj,data.ocn,  data.lv,      data.odv,   data.osp,   data.of,    data.is,    data.node,  data.parent,  '',                 '' +              @@seg_full=data.name if data.is==:heading && data.ln==7 && data.name #check data.name +              @@seg ||='' #nil # watch +              @col[:seg]=@@seg +              @col[:lv7]+=1 +              @col[:lid]+=1 +              @col[:lev]=7 +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_plus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @col[:lev]=@col[:plaintext]=@col[:body]='' +                                                                               #% :structure :layout :comment +            elsif data.of==:structure \ +            || data.of==:layout \ +            || data.of==:comment +              #added watch +                                                                               #% : +            else                                                               #% regular text +              @col[:lid]+=1 +              ( +                txt='' +                txt,@col[:ocn], +                @col[:ocnd],@col[:ocns], +                @col[:t_of],@col[:t_is], +                @col[:node],@col[:parent], +                @col[:digest_clean],@col[:digest_all], +                @col[:lev]= +                data.obj,data.ocn, +                data.odv,data.osp, +                data.of,data.is, +                '',data.parent, +                '','', +                9 +              ) +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              if @sql_type==:pg \ +              and txt.size > (SiSU_DbColumns::ColumnSize.new.document_clean - 1)             # examine pg build & remove limitation +                puts "\n\nTOO LARGE (TXT - see error log)\n\n" +                open("#{Dir.pwd}/pg_documents_error_log",'a') do |error| +                  error.puts("\n#{@opt.fns}\nTEXT BODY\n#{@col[:body].size} object #{@col[:ocn]} -> #{@col[:body].slice(0..500)}") +                end +                txt=%{\n\nLARGE TEXT BLOCK OMITTED\n\n} +              end +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              body=if data.is==:table +                SiSU_FormatShared::CSS_Format.new(@md,data).html_table +              elsif data.is==:code +                SiSU_FormatShared::CSS_Format.new(@md,data).code +              elsif defined? data.indent \ +              and defined? data.hang \ +              and data.indent =~/[1-9]/ \ +              and data.indent == data.hang +                SiSU_FormatShared::CSS_Format.new(@md,data).indent(data.indent) +              elsif defined? data.indent \ +              and defined? data.hang \ +              and data.hang =~/[0-9]/ \ +              and data.indent != data.hang +                SiSU_FormatShared::CSS_Format.new(@md,data).hang_indent(data.hang,data.indent) +              else +                SiSU_FormatShared::CSS_Format.new(@md,data).norm +              end +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @en,@en_ast,@en_pls=[],[],[] +              @col[:en_a]=@col[:en_z]=nil +              @col[:lev]=@col[:plaintext]=@col[:body]=@col[:words]='' +            end +            if notedata =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/                                         #% import into database endnotes tables +              endnote_array=notedata.scan(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/) +              endnote_array.each do |inf| +                if inf[/#{Mx[:en_a_o]}\d+.+?#{Mx[:en_a_c]}/] +                  if inf[/#{Mx[:en_a_o]}(\d+)(.+?)#{Mx[:en_a_c]}/] +                    nr,txt,digest_clean=$1,$2.strip,0 +                  end +                  @id_n ||=0 +                  @id_n+=1 +                  txt=special_character_escape(txt) +                  body=SiSU_FormatShared::CSS_Format.new(@md,data).endnote(nr,txt) +                  txt=strip_markup(txt) +                  if txt.size > (SiSU_DbColumns::ColumnSize.new.endnote_clean - 1) +                    puts "\n\nTOO LARGE (ENDNOTE - see error log)\n\n" +                    open("#{Dir.pwd}/pg_documents_error_log",'a') do |error| +                      error.puts("\n#{@opt.fns}\nENDNOTE\n#{txt.size} object #{@col[:ocn]},#{@col[:ocnd]},#{@col[:ocns]} -> #{txt.slice(0..500)}") +                    end +                    txt=%{\n\nLARGE TEXT BLOCK OMITTED\n\n} +                  end +                  if txt +                    en={ +                      type: 'endnotes', +                      id:      @id_n, +                      lid:     @col[:lid], +                      nr:      nr, +                      txt:     txt, +                      body:    body, +                      ocn:     @col[:ocn], +                      ocnd:    @col[:ocnd], +                      ocns:    @col[:ocns], +                      id_t:    @@id_t, +                      hash:    digest_clean +                    } +                    t=SiSU_DbTuple::LoadEndnotes.new(@conn,en,@opt,@file_maint) +                    @tuple_array << t.tuple +                  end +                end +              end +              word_mode=notedata.scan(/\S+/) +            end +            if notedata =~/#{Mx[:en_b_o]}\*.+?#{Mx[:en_b_c]}/                                      #% import into database endnotes tables +              endnote_array=notedata.scan(/#{Mx[:en_b_o]}\*.+?#{Mx[:en_b_c]}/) +              endnote_array.each do |inf| +                if inf[/#{Mx[:en_b_o]}\*\d+.+?#{Mx[:en_b_c]}/]                    # dal new endnotes 2003w31/1 +                  if inf[/#{Mx[:en_b_o]}[*](\d+)(.+?)#{Mx[:en_b_c]}/]           # dal new endnotes 2003w31/1 +                    nr,txt,digest_clean=$1,$2.strip,0 +                  end +                  @id_n+=1 +                  txt=special_character_escape(txt) +                  body=SiSU_FormatShared::CSS_Format.new(@md,data).endnote(nr,txt) +                  txt=strip_markup(txt) +                  if txt.size > (SiSU_DbColumns::ColumnSize.new.endnote_clean - 1) +                    puts "\n\nTOO LARGE (ENDNOTE - see error log)\n\n" +                    open("#{Dir.pwd}/pg_documents_error_log",'a') do |error| +                      error.puts("\n#{@opt.fns}\nENDNOTE\n#{txt.size} object #{@col[:ocn]},#{@col[:ocnd]},#{@col[:ocns]} -> #{txt.slice(0..500)}") +                    end +                    txt=%{\n\nLARGE TEXT BLOCK OMITTED\n\n} +                  end +                  if txt +                    en={ +                      type: 'endnotes_asterisk', +                      id:      @id_n, +                      lid:     @col[:lid], +                      nr:      nr, +                      txt:     txt, +                      body:    body, +                      ocn:     @col[:ocn], +                      ocnd:    @col[:ocnd], +                      ocns:    @col[:ocns], +                      id_t:    @@id_t, +                      hash:    digest_clean +                    } +                    t=SiSU_DbTuple::LoadEndnotes.new(@conn,en,@opt,@file_maint) +                    @tuple_array << t.tuple +                  end +                end +              end +              word_mode=notedata.scan(/\S+/) +            end +            if notedata =~/#{Mx[:en_b_o]}\+.+?#{Mx[:en_b_c]}/                                           #% import into database endnotes tables +              endnote_array=notedata.scan(/#{Mx[:en_b_o]}\+.+?#{Mx[:en_b_c]}/) +              endnote_array.each do |inf| +                if inf[/#{Mx[:en_b_o]}\+\d+.+?#{Mx[:en_b_c]}/]                        # dal new endnotes 2003w31/1 +                  if inf[/#{Mx[:en_b_o]}[+](\d+)(.+?)#{Mx[:en_b_c]}/]               # dal new endnotes 2003w31/1 +                    nr,txt,digest_clean=$1,$2.strip,0 +                  end +                  @id_n+=1 +                  txt=special_character_escape(txt) +                  body=SiSU_FormatShared::CSS_Format.new(@md,data).endnote(nr,txt) +                  txt=strip_markup(txt) +                  if txt.size > (SiSU_DbColumns::ColumnSize.new.endnote_clean - 1) +                    puts "\n\nTOO LARGE (ENDNOTE - see error log)\n\n" +                    open("#{Dir.pwd}/pg_documents_error_log",'a') do |error| +                      error.puts("\n#{@opt.fns}\nENDNOTE\n#{txt.size} object #{@col[:ocn]},#{@col[:ocnd]},#{@col[:ocns]} -> #{txt.slice(0..500)}") +                    end +                    txt=%{\n\nLARGE TEXT BLOCK OMITTED\n\n} +                  end +                  if txt +                    en={ +                      type: 'endnotes_plus', +                      id:      @id_n, +                      lid:     @col[:lid], +                      nr:      nr, +                      txt:     txt, +                      body:    body, +                      ocn:     @col[:ocn], +                      ocnd:    @col[:ocnd], +                      ocns:    @col[:ocns], +                      id_t:    @@id_t, +                      hash:    digest_clean +                    } +                    t=SiSU_DbTuple::LoadEndnotes.new(@conn,en,@opt,@file_maint) +                    @tuple_array << t.tuple +                  end +                end +              end +              word_mode=notedata.scan(/\S+/) +            end +          end +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +      @tuple_array +    end +    def endnotes(txt) +      @txt=txt +      def extract_any +        if @txt =~/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})[*+]?(\d+)\s+.+?(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/ +          endnotes(@txt).range +          @en << endnotes(@txt).standard if @txt =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/ +          @en_ast << endnotes(@txt).asterisk if @txt =~/#{Mx[:en_b_o]}\*.+?#{Mx[:en_b_c]}/ +          @en_pls << endnotes(@txt).plus if @txt =~/#{Mx[:en_b_o]}\+.+?#{Mx[:en_b_c]}/ +          @txt=endnotes(@txt).clean_text +        end +        @txt +      end +      def standard +        (@txt =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/) \ +        ? @txt.scan(/#{Mx[:en_a_o]}(\d+).+?#{Mx[:en_a_c]}/) +        : nil +      end +      def asterisk +        (@txt =~/#{Mx[:en_b_o]}\*.+?#{Mx[:en_b_c]}/) \ +        ? @txt.scan(/#{Mx[:en_b_o]}[*](\d+).+?#{Mx[:en_b_c]}/) +        : nil +      end +      def plus +        (@txt =~/#{Mx[:en_b_o]}\+.+?#{Mx[:en_b_c]}/) \ +        ? @txt.scan(/#{Mx[:en_b_o]}[+](\d+).+?#{Mx[:en_b_c]}/) +        : nil +      end +      def clean_text(base_url=nil) +        @txt=if base_url +          @txt.gsub(/#{Mx[:en_a_o]}(\d+).+?#{Mx[:en_a_c]}/,%{<sup><a href="#{base_url}#_\\1" name="-\\1">\\1</a></sup>}). +            gsub(/#{Mx[:en_b_o]}([*]\d+).+?#{Mx[:en_b_c]}/,%{<sup><a href="#{base_url}#_\\1" name="-\\1">\\1</a></sup>}). +            gsub(/#{Mx[:en_b_o]}([+]\d+).+?#{Mx[:en_b_c]}/,%{<sup><a href="#{base_url}#_\\1" name="-\\1">\\1</a></sup>}) +        else +          @txt.gsub(/#{Mx[:en_a_o]}(\d+).+?#{Mx[:en_a_c]}/,'<sup>\1</sup>'). +            gsub(/#{Mx[:en_b_o]}([*]\d+).+?#{Mx[:en_b_c]}/,'<sup>\1</sup>'). +            gsub(/#{Mx[:en_b_o]}([+]\d+).+?#{Mx[:en_b_c]}/,'<sup>\1</sup>') +        end +        @txt +      end +      def range +        @col[:en_a]=@col[:en_z]=nil +        if @txt =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}([*]\d+).+?#{Mx[:en_b_c]}|#{Mx[:en_b_o]}([+]\d+).+?#{Mx[:en_b_c]}/ +          word_array=@txt.scan(/\S+/) +          word_array.each do |w| +            if w[/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})[*+]?(\d+)\s+.+?(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/]                                                # not tested since change 2003w31 +              @col[:en_a]=$1 unless @col[:en_a] +              @col[:en_z]=@col[:en_a].dup unless @col[:en_a] +              @col[:en_z]=$1 if @col[:en_a] +            end +          end +        end +        @col +      end +      self +    end +    def db_import_urls(dbi_unit,content)                                           #% import documents OID - populate database +      begin +        @fnc=content +        @env=SiSU_Env::InfoEnv.new(@opt.fns) +        f,u={},{} +        if @fnb.empty? \ +        or @fnb.nil? +          p 'file output path error' #remove +        end +        if FileTest.file?("#{@md.file.output_path.txt.dir}/#{@md.file.base_filename.txt}")==true +          f[:txt],u[:txt]='plaintext,', "'#{@md.file.output_path.txt.url}/#{@md.file.base_filename.txt}'," +        end +        if FileTest.file?("#{@md.file.output_path.html_seg.dir}/#{@md.file.base_filename.html_segtoc}")==true +          f[:html_toc],u[:html_toc]='html_toc,', "'#{@md.file.output_path.html_seg.url}/#{@md.file.base_filename.html_segtoc}'," +        end +        if FileTest.file?("#{@md.file.output_path.html_scroll.dir}/#{@md.file.base_filename.html_scroll}")==true +          f[:html_doc],u[:html_doc]='html_doc,', "'#{@md.file.output_path.html_scroll.url}/#{@md.file.base_filename.html_scroll}'," +        end +        if FileTest.file?("#{@md.file.output_path.xhtml.dir}/#{@md.file.base_filename.xhtml}")==true +          f[:xhtml],u[:xhtml]='xhtml,', "'#{@md.file.output_path.xhtml.url}/#{@md.file.base_filename.xhtml}'," +        end +        if FileTest.file?("#{@md.file.output_path.xml_sax.dir}/#{@md.file.base_filename.xml_sax}")==true +          f[:xml_sax],u[:xml_sax]='xml_sax,', "'#{@md.file.output_path.xml_sax.url}/#{@md.file.base_filename.xml_sax}'," +        end +        if FileTest.file?("#{@md.file.output_path.xml_dom.dir}/#{@md.file.base_filename.xml_dom}")==true +          f[:xml_dom],u[:xml_dom]='xml_dom,', "'#{@md.file.output_path.xml_dom.url}/#{@md.file.base_filename.xml_dom}'," +        end +        if FileTest.file?("#{@md.file.output_path.epub.dir}/#{@md.file.base_filename.epub}")==true +          f[:epub],u[:epub]='epub,', "'#{@md.file.output_path.epub.url}/#{@md.file.base_filename.epub}'," +        end +        if FileTest.file?("#{@md.file.output_path.odt.dir}/#{@md.file.base_filename.odt}")==true +          f[:odf],u[:odf]='odf,', "'#{@md.file.output_path.odt.url}/#{@md.file.base_filename.odt}'," +        end +        if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_p_a4}")==true #\ +        #or FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_p_letter}")==true +          f[:pdf_p],u[:pdf_p]='pdf_p,', "'#{@md.file.output_path.pdf.url}/#{@pdf_fn.pdf_p_a4}'," +        end +        if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_l_a4}")==true #\ +        #or FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_l_letter}")==true +          f[:pdf_l],u[:pdf_l]='pdf_l,', "'#{@md.file.output_path.pdf.url}/#{@pdf_fn.pdf_l_a4}'," +        end +        if FileTest.file?("#{@md.file.output_path.html_concordance.dir}/#{@md.file.base_filename.html_concordance}")==true +          f[:concordance],u[:concordance]='concordance,', "'#{@md.file.output_path.html_concordance.url}/#{@md.file.base_filename.html_concordance}'," +        end +        #if FileTest.file?("#{@md.file.output_path.x.dir}/#{@md.file.base_filename.x}")==true +        #  f[:latex_p],u[:latex_p]='latex_p,', "'#{@md.file.output_path.x.url}/#{@md.file.base_filename.x}'," +        #end +        ##if FileTest.file?("#{out}/#{@fnb}/#{@opt.fns}.tex")==true +        ##  f[:latex_p],u[:latex_p]='latex_p,', "'#{base}/#{@fnb}/#{@opt.fns}.tex'," +        ##end +        #if FileTest.file?("#{@md.file.output_path.x.dir}/#{@md.file.base_filename.x}")==true +        #  f[:latex_l],u[:latex_l]='latex_l,', "'#{@md.file.output_path.x.url}/#{@md.file.base_filename.x}'," +        #end +        ##if FileTest.file?("#{out}/#{@fnb}/#{@opt.fns}.landscape.tex")==true +        ##  f[:latex_l],u[:latex_l]='latex_l,', "'#{base}/#{@fnb}/#{@opt}.fns}.landscape.tex'," +        ##end +        if FileTest.file?("#{@md.file.output_path.digest.dir}/#{@md.file.base_filename.digest}")==true +          f[:digest],u[:digest]='digest,', "'#{@md.file.output_path.digest.url}/#{@md.file.base_filename.digest}'," +        end +        if FileTest.file?("#{@md.file.output_path.manifest.dir}/#{@md.file.base_filename.manifest}")==true #revisit, was to be text, this is html +          f[:manifest],u[:manifest]='manifest,', "'#{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}'," +        end +        if FileTest.file?("#{@md.file.output_path.src.dir}/#{@md.file.base_filename.src}")==true +          f[:markup],u[:markup]='markup,', "'#{@md.file.output_path.src.url}/#{@md.file.base_filename.src}'," +        end +        if FileTest.file?("#{@md.file.output_path.sisupod.dir}/#{@md.file.base_filename.sisupod}")==true +          f[:sisupod],u[:sisupod]='sisupod,', "'#{@md.file.output_path.sisupod.url}/#{@md.file.base_filename.sisupod}'," +        end +        t=SiSU_DbTuple::LoadUrls.new(@conn,f,u,@@id_t,@opt,@file_maint) +        tuple=t.tuple +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +      tuple +    end +  end +end +__END__ +#+END_SRC + +** db_remove.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_remove.rb" +# <<sisu_document_header>> +module SiSU_DbRemove +  class Remove +    include SiSU_DbAction +    def initialize(opt,conn,file,sql_type) +      @opt,@conn,@file,@sql_type=opt,conn,file,sql_type +      @md=SiSU_Param::Parameters.new(@opt).get +      @fnb=@md.fnb +      @db=SiSU_Env::InfoDb.new +    end +    def remove +      driver_sqlite3=if @sql_type==:sqlite +        (@conn.inspect.match(/^(.{10})/)[1]==@db.sqlite.conn_sqlite3.inspect.match(/^(.{10})/)[1]) \ +        ? true +        : false +      end +      del_id=if driver_sqlite3 +        begin +          remove_selected=%{ +            SELECT tid +            FROM metadata_and_text +            WHERE src_filename = '#{@md.fns}' +            AND metadata_and_text.language_document_char = '#{@opt.lng}' +          ;} # note, for .ssm: @md.fns (is set during runtime & is) != @opt.fns @md.opt.fns +          @conn.get_first_value(remove_selected).to_i +        rescue SQLite3::Exception => e +          #not tested +          puts "Exception occurred" +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark(e.inspect) +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +            "\n" \ +            + 'Attempting to initialize db' + "\n" \ +            + 'Creating db tables' +          ) +          sdb={ +            create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +            index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +          } +          db_action(sdb).create +        end +      else +        begin +          remove_selected=%{ +            SELECT metadata_and_text.tid +            FROM metadata_and_text +            WHERE metadata_and_text.src_filename = '#{@md.fns}' +            AND metadata_and_text.language_document_char = '#{@opt.lng}' +          ;} # note, for .ssm: @md.fns (is set during runtime & is) != @opt.fns @md.opt.fns +          x=@conn.exec(remove_selected) +          x.field_values("tid")[0] +        rescue PG::Error => e +          err=[ +            e.result.error_field( PG::Result::PG_DIAG_SEVERITY ), +            e.result.error_field( PG::Result::PG_DIAG_SQLSTATE ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_PRIMARY ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_DETAIL ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_HINT ), +            e.result.error_field( PG::Result::PG_DIAG_STATEMENT_POSITION ), +            e.result.error_field( PG::Result::PG_DIAG_INTERNAL_POSITION ), +            e.result.error_field( PG::Result::PG_DIAG_INTERNAL_QUERY ), +            e.result.error_field( PG::Result::PG_DIAG_CONTEXT ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_FILE ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_LINE ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_FUNCTION ), +          ] +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark("\n" + err.inspect) +          if err[2] =~/relation "\S+?" does not exist/ \ +          or err.inspect =~/relation "\S+?" does not exist/ +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +              "\n" \ +              + err[2] + "\n" \ +              + 'Attempting to initialize db' + "\n" \ +              + 'Creating db tables' +            ) +            sdb={ +              create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +              index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +            } +            db_action(sdb).create +          end +        end +      end +      if del_id +        sql_entry=[ +          "DELETE FROM endnotes WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM endnotes_asterisk WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM endnotes_plus WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM doc_objects WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM urls WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM metadata_and_text WHERE metadata_and_text.tid = '#{del_id}';", +        ] +        if driver_sqlite3 +          @conn.transaction +          sql_entry.each do |s| +            begin +              @conn.execute(s) +            rescue +              next +            end +          end +          @conn.commit if driver_sqlite3 +        else +          sql_entry.each do |s| +            begin +              @conn.exec_params(s) +            rescue +              next +            end +          end +        end +        if @opt.act[:maintenance][:set]==:on +          @file.puts sql_entry +        end +      else +        if (@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @opt.selections.str, +            "no such file in database #{@db.psql.db}::#{@opt.fns}" +          ).puts_grey +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* db_load_tuple.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_load_tuple.rb" +# <<sisu_document_header>> +module SiSU_DbTuple +  require_relative 'db_columns'                         # db_columns.rb +  class LoadDocuments +    require_relative 'dp'                               # dp.rb +      include SiSU_Param +    def initialize(conn,col,opt,file_maint) +      @conn,@col,@opt,@file_maint=conn,col,opt,file_maint +      @col[:lev]=@col[:lev].to_i +      unless @col[:lev].inspect=~/^[0-7]/ \ +      or @col[:lev]==0..7 +        @col[:lev]=9 +      end +      @col[:ocn]=0 unless @col[:ocn].inspect=~/\d+/ +      @cX=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]).cX +    end +    def tuple                                                                    #% import line +      sql_entry=if @col[:en_a] +        "INSERT INTO doc_objects (lid, metadata_tid, lev, lev_an, clean, body, book_idx, ocn, ocnd, ocns, seg, lev0, lev1, lev2, lev3, lev4, lev5, lev6, lev7, en_a, en_z, t_of, t_is, node, parent, digest_clean, digest_all) " + +        "VALUES (#{@col[:lid]}, #{@col[:tid]}, #{@col[:lev]}, '#{@col[:lev_an]}', '#{@col[:plaintext]}', '#{@col[:body]}', '#{@col[:book_idx]}', '#{@col[:ocn]}', '#{@col[:ocnd]}', '#{@col[:ocns]}', '#{@col[:seg]}', '#{@col[:lv0]}', '#{@col[:lv1]}', '#{@col[:lv2]}', '#{@col[:lv3]}', '#{@col[:lv4]}', '#{@col[:lv5]}', '#{@col[:lv6]}', '#{@col[:lv7]}', '#{@col[:en_a]}', '#{@col[:en_z]}', '#{@col[:t_of]}', '#{@col[:t_is]}', '#{@col[:node]}', '#{@col[:parent]}', '#{@col[:digest_clean]}', '#{@col[:digest_all]}');" +      else +        "INSERT INTO doc_objects (lid, metadata_tid, lev, lev_an, clean, body, book_idx, ocn, ocnd, ocns, seg, lev0, lev1, lev2, lev3, lev4, lev5, lev6, lev7, t_of, t_is, node, parent, digest_clean, digest_all) " + +        "VALUES (#{@col[:lid]}, #{@col[:tid]}, #{@col[:lev]}, '#{@col[:lev_an]}', '#{@col[:plaintext]}', '#{@col[:body]}', '#{@col[:book_idx]}', '#{@col[:ocn]}', '#{@col[:ocnd]}', '#{@col[:ocns]}', '#{@col[:seg]}', '#{@col[:lv0]}', '#{@col[:lv1]}', '#{@col[:lv2]}', '#{@col[:lv3]}', '#{@col[:lv4]}', '#{@col[:lv5]}', '#{@col[:lv6]}', '#{@col[:lv7]}', '#{@col[:t_of]}', '#{@col[:t_is]}', '#{@col[:node]}', '#{@col[:parent]}', '#{@col[:digest_clean]}', '#{@col[:digest_all]}');" +      end +      if @opt.act[:maintenance][:set]==:on +          puts @file_maint.inspect +          puts sql_entry +          @file_maint.puts sql_entry +      elsif @opt.act[:verbose_plus][:set]==:on +          puts sql_entry +      end +      if @opt.act[:verbose][:set]==:on +        if @col[:lev].inspect =~/[0-35-7]/ +          lev=case @col[:lev].inspect +          when /0/ then ':A' +          when /1/ then ':B' +          when /2/ then ':C' +          when /3/ then ':D' +          when /5/ then ' 2' +          when /6/ then ' 3' +          when /7/ then ' 4' +          end +          puts %{#{lev}>\t#{@col[:lv0]}\t#{@col[:lv1]}\t#{@col[:lv2]}\t#{@col[:lv3]}\t#{@col[:lv4]}\t#{@col[:lv5]}\t#{@col[:lv6]}\t#{@col[:lv7]}\t#{@col[:ocn]}\t#{@col[:node]}\t#{@col[:ocns]}} +        elsif @col[:lev].inspect =~/[4]/ +          puts %{ #{@cX.green}1>#{@cX.off}\t#{@col[:lv0]}\t#{@col[:lv1]}\t#{@col[:lv2]}\t#{@col[:lv3]}\t#{@col[:lv4]}\t#{@col[:lv5]}\t#{@col[:lv6]}\t#{@col[:lv7]}\t#{@col[:ocn]}\t#{@col[:node]}\t#{@col[:ocns]}\t#{@col[:seg]}} +        end +      end +      sql_entry +    end +  end +  class LoadMetadata #< SiSU_DbColumns::Columns +    def initialize(conn,id,md,file_maint) +      @conn,@id,@md,@file_maint=conn,id,md,file_maint +      @tp=SiSU_DbColumns::Columns.new(md) +    end +    def tuple +      sql_entry="INSERT INTO metadata_and_text ( +#{@tp.column.title.tuple[0]} +#{@tp.column.title_main.tuple[0]} +#{@tp.column.title_sub.tuple[0]} +#{@tp.column.title_short.tuple[0]} +#{@tp.column.title_edition.tuple[0]} +#{@tp.column.title_note.tuple[0]} +#{@tp.column.title_language.tuple[0]} +#{@tp.column.title_language_char.tuple[0]} +#{@tp.column.creator_author.tuple[0]} +#{@tp.column.creator_author_honorific.tuple[0]} +#{@tp.column.creator_author_nationality.tuple[0]} +#{@tp.column.creator_editor.tuple[0]} +#{@tp.column.creator_contributor.tuple[0]} +#{@tp.column.creator_illustrator.tuple[0]} +#{@tp.column.creator_photographer.tuple[0]} +#{@tp.column.creator_translator.tuple[0]} +#{@tp.column.creator_prepared_by.tuple[0]} +#{@tp.column.creator_digitized_by.tuple[0]} +#{@tp.column.creator_audio.tuple[0]} +#{@tp.column.creator_video.tuple[0]} +#{@tp.column.language_document.tuple[0]} +#{@tp.column.language_document_char.tuple[0]} +#{@tp.column.language_original.tuple[0]} +#{@tp.column.language_original_char.tuple[0]} +#{@tp.column.date_added_to_site.tuple[0]} +#{@tp.column.date_available.tuple[0]} +#{@tp.column.date_created.tuple[0]} +#{@tp.column.date_issued.tuple[0]} +#{@tp.column.date_modified.tuple[0]} +#{@tp.column.date_published.tuple[0]} +#{@tp.column.date_valid.tuple[0]} +#{@tp.column.date_translated.tuple[0]} +#{@tp.column.date_original_publication.tuple[0]} +#{@tp.column.date_generated.tuple[0]} +#{@tp.column.publisher.tuple[0]} +#{@tp.column.original_publisher.tuple[0]} +#{@tp.column.original_language.tuple[0]} +#{@tp.column.original_language_char.tuple[0]} +#{@tp.column.original_source.tuple[0]} +#{@tp.column.original_institution.tuple[0]} +#{@tp.column.original_nationality.tuple[0]} +#{@tp.column.rights_all.tuple[0]} +#{@tp.column.rights_copyright_text.tuple[0]} +#{@tp.column.rights_copyright_translation.tuple[0]} +#{@tp.column.rights_copyright_illustrations.tuple[0]} +#{@tp.column.rights_copyright_photographs.tuple[0]} +#{@tp.column.rights_copyright_preparation.tuple[0]} +#{@tp.column.rights_copyright_digitization.tuple[0]} +#{@tp.column.rights_copyright_audio.tuple[0]} +#{@tp.column.rights_copyright_video.tuple[0]} +#{@tp.column.rights_license.tuple[0]} +#{@tp.column.classify_topic_register.tuple[0]} +#{@tp.column.classify_subject.tuple[0]} +#{@tp.column.classify_loc.tuple[0]} +#{@tp.column.classify_dewey.tuple[0]} +#{@tp.column.classify_keywords.tuple[0]} +#{@tp.column.identifier_oclc.tuple[0]} +#{@tp.column.identifier_isbn.tuple[0]} +#{@tp.column.notes_abstract.tuple[0]} +#{@tp.column.notes_description.tuple[0]} +#{@tp.column.notes_comment.tuple[0]} +#{@tp.column.notes_history.tuple[0]} +#{@tp.column.notes_format.tuple[0]} +#{@tp.column.notes_relation.tuple[0]} +#{@tp.column.notes_coverage.tuple[0]} +#{@tp.column.notes_type.tuple[0]} +#{@tp.column.notes_prefix.tuple[0]} +#{@tp.column.notes_prefix_a.tuple[0]} +#{@tp.column.notes_prefix_b.tuple[0]} +#{@tp.column.notes_suffix.tuple[0]} +#{@tp.column.src_filename.tuple[0]} +#{@tp.column.src_fingerprint.tuple[0]} +#{@tp.column.src_filesize.tuple[0]} +#{@tp.column.src_word_count.tuple[0]} +#{@tp.column.src_txt.tuple[0]} +#{@tp.column.fulltext.tuple[0]} +tid) +" + +       "VALUES ( +#{@tp.column.title.tuple[1]} +#{@tp.column.title_main.tuple[1]} +#{@tp.column.title_sub.tuple[1]} +#{@tp.column.title_short.tuple[1]} +#{@tp.column.title_edition.tuple[1]} +#{@tp.column.title_note.tuple[1]} +#{@tp.column.title_language.tuple[1]} +#{@tp.column.title_language_char.tuple[1]} +#{@tp.column.creator_author.tuple[1]} +#{@tp.column.creator_author_honorific.tuple[1]} +#{@tp.column.creator_author_nationality.tuple[1]} +#{@tp.column.creator_editor.tuple[1]} +#{@tp.column.creator_contributor.tuple[1]} +#{@tp.column.creator_illustrator.tuple[1]} +#{@tp.column.creator_photographer.tuple[1]} +#{@tp.column.creator_translator.tuple[1]} +#{@tp.column.creator_prepared_by.tuple[1]} +#{@tp.column.creator_digitized_by.tuple[1]} +#{@tp.column.creator_audio.tuple[1]} +#{@tp.column.creator_video.tuple[1]} +#{@tp.column.language_document.tuple[1]} +#{@tp.column.language_document_char.tuple[1]} +#{@tp.column.language_original.tuple[1]} +#{@tp.column.language_original_char.tuple[1]} +#{@tp.column.date_added_to_site.tuple[1]} +#{@tp.column.date_available.tuple[1]} +#{@tp.column.date_created.tuple[1]} +#{@tp.column.date_issued.tuple[1]} +#{@tp.column.date_modified.tuple[1]} +#{@tp.column.date_published.tuple[1]} +#{@tp.column.date_valid.tuple[1]} +#{@tp.column.date_translated.tuple[1]} +#{@tp.column.date_original_publication.tuple[1]} +#{@tp.column.date_generated.tuple[1]} +#{@tp.column.publisher.tuple[1]} +#{@tp.column.original_publisher.tuple[1]} +#{@tp.column.original_language.tuple[1]} +#{@tp.column.original_language_char.tuple[1]} +#{@tp.column.original_source.tuple[1]} +#{@tp.column.original_institution.tuple[1]} +#{@tp.column.original_nationality.tuple[1]} +#{@tp.column.rights_all.tuple[1]} +#{@tp.column.rights_copyright_text.tuple[1]} +#{@tp.column.rights_copyright_translation.tuple[1]} +#{@tp.column.rights_copyright_illustrations.tuple[1]} +#{@tp.column.rights_copyright_photographs.tuple[1]} +#{@tp.column.rights_copyright_preparation.tuple[1]} +#{@tp.column.rights_copyright_digitization.tuple[1]} +#{@tp.column.rights_copyright_audio.tuple[1]} +#{@tp.column.rights_copyright_video.tuple[1]} +#{@tp.column.rights_license.tuple[1]} +#{@tp.column.classify_topic_register.tuple[1]} +#{@tp.column.classify_subject.tuple[1]} +#{@tp.column.classify_loc.tuple[1]} +#{@tp.column.classify_dewey.tuple[1]} +#{@tp.column.classify_keywords.tuple[1]} +#{@tp.column.identifier_oclc.tuple[1]} +#{@tp.column.identifier_isbn.tuple[1]} +#{@tp.column.notes_abstract.tuple[1]} +#{@tp.column.notes_comment.tuple[1]} +#{@tp.column.notes_description.tuple[1]} +#{@tp.column.notes_history.tuple[1]} +#{@tp.column.notes_format.tuple[1]} +#{@tp.column.notes_relation.tuple[1]} +#{@tp.column.notes_coverage.tuple[1]} +#{@tp.column.notes_type.tuple[1]} +#{@tp.column.notes_prefix.tuple[1]} +#{@tp.column.notes_prefix_a.tuple[1]} +#{@tp.column.notes_prefix_b.tuple[1]} +#{@tp.column.notes_suffix.tuple[1]} +#{@tp.column.src_filename.tuple[1]} +#{@tp.column.src_fingerprint.tuple[1]} +#{@tp.column.src_filesize.tuple[1]} +#{@tp.column.src_word_count.tuple[1]} +#{@tp.column.src_txt.tuple[1]} +#{@tp.column.fulltext.tuple[1]} +#{@id} +);" +      if @md.opt.act[:maintenance][:set]==:on +        puts "maintenance mode on: creating sql transaction file (for last transaction set (document) only):\n\t#{@file_maint.inspect}" +        @file_maint.puts sql_entry +      end +      sql_entry +    end +  end +  class LoadUrls +    def initialize(conn,f,u,id,opt,file_maint) +      @conn,@f,@u,@id,@opt,@file_maint=conn,f,u,id,opt,file_maint +    end +    def tuple +      sql_entry="INSERT INTO urls (#{@f[:txt]} #{@f[:html_toc]} #{@f[:html_doc]} #{@f[:xhtml]} #{@f[:xml_sax]} #{@f[:xml_dom]} #{@f[:odf]} #{@f[:pdf_p]} #{@f[:pdf_l]} #{@f[:concordance]} #{@f[:latex_p]} #{@f[:latex_l]} #{@f[:manifest]} #{@f[:digest]} #{@f[:markup]} #{@f[:sisupod]} metadata_tid) " + +      "VALUES (#{@u[:txt]} #{@u[:html_toc]} #{@u[:html_doc]} #{@u[:xhtml]} #{@u[:xml_sax]} #{@u[:xml_dom]} #{@u[:odf]} #{@u[:pdf_p]} #{@u[:pdf_l]} #{@u[:concordance]} #{@u[:latex_p]} #{@u[:latex_l]} #{@u[:manifest]} #{@u[:digest]} #{@u[:markup]} #{@u[:sisupod]} #{@id});" +      if @opt.act[:maintenance][:set]==:on +        @file_maint.puts sql_entry +      end +      sql_entry +    end +  end +  class LoadEndnotes +    def initialize(conn,en,opt,file_maint) +      @conn,@en,@opt,@file_maint=conn,en,opt,file_maint +    end +    def tuple +      sql_entry="INSERT INTO #{@en[:type]} (nid, document_lid, nr, clean, body, ocn, ocnd, ocns, metadata_tid, digest_clean) " + +      "VALUES ('#{@en[:id]}', '#{@en[:lid]}', '#{@en[:nr]}', '#{@en[:txt]}', '#{@en[:body]}', '#{@en[:ocn]}', '#{@en[:ocnd]}', '#{@en[:ocns]}', '#{@en[:id_t]}', '#{@en[:hash]}');" +      if @opt.act[:maintenance][:set]==:on +        @file_maint.puts sql_entry +      end +      sql_entry +    end +  end +end +__END__ +#+END_SRC + +* db_select.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_select.rb" +# <<sisu_document_header>> +module SiSU_DbAction +  def db_action(sdb) +    @sdb=sdb +    def createdb +      @sdb[:create].output_dir? +      begin +        @sdb[:create].create_db +      rescue +        @sdb[:create].output_dir? +      end +    end +    def drop +      @sdb[:drop].drop.tables +    end +    def create +      @sdb[:create].output_dir? +      begin +        @sdb[:create].create_table.metadata_and_text +        @sdb[:create].create_table.doc_objects +        @sdb[:create].create_table.endnotes +        @sdb[:create].create_table.endnotes_asterisk +        @sdb[:create].create_table.endnotes_plus +        @sdb[:create].create_table.urls +        @sdb[:index].create_indexes +      rescue +        SiSU_Errors::Rescued.new($!,$@,'--sqlite').location +        @sdb[:create].output_dir? do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    def import +      db_exist? +      @sdb[:import].marshal_load +      tell=case @sql_type +      when :sqlite +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "sqlite3 #{@db.sqlite.db} database?" +        ) +      when :pg +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "pgaccess or psql #{@db.psql.db} database?" +        ) +      else '???' +      end +      tell.puts_grey if @opt.act[:verbose][:set]==:on +    end +    def remove +      db_exist? +      @sdb[:remove_doc].remove +    end +    def update +      remove +      import +    end +    self +  end +end +module SiSU_DbSelect +  class Case +    include SiSU_DbAction +    def initialize(opt,conn='',sql_type=:pg) +      @opt,@conn,@sql_type=opt,conn,sql_type +      @db=SiSU_Env::InfoDb.new +      @file_maint=sql_maintenance_file +      @sdb={ +        create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +        index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +        drop: SiSU_DbDBI::Drop.new(@opt,@conn,@db,@sql_type), +      } +      if (@opt.act[:psql_import][:set]==:on \ +      || @opt.act[:psql_update][:set]==:on) \ +      or (@opt.act[:sqlite_import][:set]==:on \ +      || @opt.act[:sqlite_update][:set]==:on) +        @sdb[:import]=SiSU_DbDBI::Import.new(@opt,@conn,@file_maint,@sql_type) +        @sdb[:remove_doc]=SiSU_DbDBI::Remove.new(@opt,@conn,@file_maint,@sql_type) +      elsif (@opt.act[:psql_remove][:set]==:on \ +      or @opt.act[:sqlite_remove][:set]==:on) +        @sdb[:remove_doc]=SiSU_DbDBI::Remove.new(@opt,@conn,@file_maint,@sql_type) +      end +    end +    def db_exist? +      if @sql_type==:sqlite \ +      and (not (FileTest.file?(@db.sqlite.db)) \ +      or FileTest.zero?(@db.sqlite.db)) +        puts %{no connection with sqlite database established, you may need to run:\n} \ +        + %{    sisu --sqlite --createall\n} \ +        + %{  before attempting to populate the database} +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +          "\n" \ +          + 'Attempting to initialize db' + "\n" \ +          + 'Creating db tables' +        ) +        db_action(@sdb).create +      end +      if @conn.is_a?(NilClass) +        if @sql_type==:sqlite +          puts %{no connection with sqlite database established, you may need to run:\n} \ +          + %{    sisu --sqlite --createall\n} \ +          + %{  before attempting to populate the database} +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +            "\n" \ +            + 'Attempting to initialize db' + "\n" \ +            + 'Creating db tables' +          ) +          db_action(@sdb).create +          @db.sqlite.db +        else +          puts %{no connection with pg database established, you may need to run:\n} \ +          + %{    createdb "#{@db.psql.db}"\n} \ +          + %{  after that don't forget to run:\n} \ +          + %{    sisu --pg --createall\n} \ +          + %{  before attempting to populate the database} +          @db.psql.db +        end +        exit +      end +    end +    def sql_maintenance_file +      file=if @opt.act[:maintenance][:set]==:on +        if @opt.fns and not @opt.fns.empty? +          @env=SiSU_Env::InfoEnv.new(@opt.fns) if @opt.fns +          if @sql_type ==:sqlite +            puts "\n#{@env.processing_path.sqlite}/#{@opt.fns}.sql" +          end +          @db=SiSU_Env::InfoDb.new +          @job="sqlite3 #{@db.sqlite.db} < #{@env.processing_path.sqlite}/#{@opt.fns}.sql" +          if @sql_type ==:sqlite +            File.new("#{@env.processing_path.sqlite}/#{@opt.fns}.sql",'w+') +          else +            File.new("#{@env.processing_path.postgresql}/#{@opt.fns}.sql",'w+') +          end +        elsif @opt.fns \ +        and (@opt.act[:sqlite_create][:set] ==:on \ +        || @opt.act[:psql_create][:set] ==:on) +          nil #sort variations later +        else nil +        end +      else nil +      end +      file +    end +    def cases +      if @opt.act[:psql_drop][:set] ==:on \ +      or @opt.act[:sqlite_drop][:set] ==:on +        db_action(@sdb).drop +      end +      if @opt.act[:psql_createdb][:set] ==:on \ +      or @opt.act[:sqlite_createdb][:set] ==:on +        db_action(@sdb).createdb +      end +      if @opt.act[:psql_create][:set] ==:on \ +      or @opt.act[:sqlite_create][:set] ==:on +        db_action(@sdb).create +      end +      if @opt.act[:psql_update][:set] ==:on \ +      or @opt.act[:sqlite_update][:set] ==:on +        db_action(@sdb).update +      else +        if @opt.act[:psql_remove][:set] ==:on \ +        or @opt.act[:sqlite_remove][:set] ==:on +          db_action(@sdb).remove +        end +        if @opt.act[:psql_import][:set] ==:on \ +        or @opt.act[:sqlite_import][:set] ==:on +          db_action(@sdb).import +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* structure +** db_columns.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_columns.rb" +# <<sisu_document_header>> +module SiSU_DbColumns +  require_relative 'se'                                # se.rb +  require_relative 'db_sqltxt'                         # db_sqltxt.rb +  class Columns < SiSU_DbText::Prepare +    def initialize(md=nil) +      @md=md +      @db=SiSU_Env::InfoDb.new #watch +      @lang ||=SiSU_i18n::Languages.new +      if defined? md.opt.act \ +      and ((md.opt.act[:psql_import][:set]==:on \ +      || md.opt.act[:psql_update][:set]==:on) \ +      or (md.opt.act[:sqlite_import][:set]==:on \ +      || md.opt.act[:sqlite_update][:set]==:on)) \ +      and FileTest.exist?(md.fns) +        txt_arr=IO.readlines(md.fns,'') +        src=txt_arr.join("\n") +        if @db.share_source? +          @sisutxt=special_character_escape(src) +        else @sisutxt='' +        end +        @fulltext=clean_searchable_text_from_document_objects(txt_arr) +       else @sisutxt,@fulltext='','' +      end +    end +#% structures +    #def column_define +    #  def varchar(name,size) +    #    "#{name}                VARCHAR(#{size}) NULL," +    #  end +    #end +=begin +#% title +@title: + :subtitle: + :short: + :edition: + :language: + :note: +=end +    def column +      def title                          # DublinCore 1 - title +        def name +          'title' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title]}) NOT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata full document title [DC1]';} +        end +        def tuple +          if defined? @md.title.full \ +          and @md.title.full=~/\S+/ +            txt=@md.title.full +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_main +        def name +          'title_main' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title_part]}) NOT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata main document title';} +        end +        def tuple +          if defined? @md.title.main \ +          and @md.title.main=~/\S+/ +            txt=@md.title.main +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_sub +        def name +          'title_sub' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title_part]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document subtitle';} +        end +        def tuple +          if defined? @md.title.sub \ +          and @md.title.sub=~/\S+/ +            txt=@md.title.sub +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_short +        def name +          'title_short' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title_part]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document short title if any';} +        end +        def tuple +          if defined? @md.title.short \ +          and @md.title.short=~/\S+/ +            txt=@md.title.short +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_edition +        def name +          'title_edition' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title_edition]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document edition (version)';} +        end +        def tuple +          if defined? @md.title.edition \ +          and @md.title.edition=~/\S+/ +            txt=@md.title.edition +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_note +        def name +          'title_note' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document notes associated with title';} +        end +        def tuple +          if defined? @md.title.note \ +          and @md.title.note=~/\S+/ +            txt=@md.title.note +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_language +        def name +          'title_language' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document language [DC12]';} +        end +        def tuple +          if @lang.list[@md.opt.lng][:n] +            txt=@lang.list[@md.opt.lng][:n] +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_language_char            # consider +        def name +          'title_language_char' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language_char]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document language iso code';} +        end +        def tuple +          if defined? @md.opt.lng \ +          and @md.opt.lng=~/\S+/ +            txt=@md.opt.lng +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% creator +@creator: + :author: + :editor: + :contributor: + :illustrator: + :photographer: + :translator: + :prepared_by: + :digitized_by: + :audio: + :video: +=end +      def creator_author                 # DublinCore 2 - creator/author (author) +        def name +          'creator_author' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document author (creator) [DC2]';} +        end +        def tuple +          if defined? @md.creator.author_detail \ +          and @md.creator.author_detail.is_a?(Array) \ +          and @md.creator.author_detail.length > 0 +            txt='' +            @md.creator.author_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_author_honorific       # consider +        def name +          'creator_author_hon' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_creator_misc_short]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document author honorific (title e.g, Ms. Dr. Prof.)';} +        end +        def tuple +          if defined? @md.creator.author_hon \ +          and @md.creator.author_hon=~/\S+/ +            txt=@md.creator.author_hon +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_author_nationality     # consider +        def name +          'creator_author_nationality' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_creator_misc_short]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata nationality of document author (creator)';} +        end +        def tuple +          if defined? @md.creator.author_nationality_detail \ +          and @md.creator.author_nationality=~/\S+/ +            txt=@md.creator.author_nationality_detail +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_editor +        def name +          'creator_editor' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document editor name(s)';} +        end +        def tuple +          if defined? @md.creator.editor_detail \ +          and @md.creator.editor_detail.is_a?(Array) \ +          and @md.creator.editor_detail.length > 0 +            txt='' +            @md.creator.editor_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_contributor            # DublinCore 6 - contributor +        def name +          'creator_contributor' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document contributor name(s) [DC6]';} +        end +        def tuple +          if defined? @md.creator.contributor_detail \ +          and @md.creator.contributor_detail.is_a?(Array) \ +          and @md.creator.contributor_detail.length > 0 +            txt='' +            @md.creator.contributor_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_illustrator +        def name +          'creator_illustrator' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document illustrator name(s)';} +        end +        def tuple +          if defined? @md.creator.illustrator_detail \ +          and @md.creator.illustrator_detail.is_a?(Array) \ +          and @md.creator.illustrator_detail.length > 0 +            txt='' +            @md.creator.illustrator_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_photographer +        def name +          'creator_photographer' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document photographer name(s)';} +        end +        def tuple +          if defined? @md.creator.photographer_detail \ +          and @md.creator.photographer_detail.is_a?(Array) \ +          and @md.creator.photographer_detail.length > 0 +            txt='' +            @md.creator.photographer_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_translator +        def name +          'creator_translator' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document translator name(s)';} +        end +        def tuple +          if defined? @md.creator.translator_detail \ +          and @md.creator.translator_detail.is_a?(Array) \ +          and @md.creator.translator_detail.length > 0 +            txt='' +            @md.creator.translator_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_prepared_by +        def name +          'creator_prepared_by' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document prepared by name(s)';} +        end +        def tuple +          if defined? @md.creator.prepared_by_detail \ +          and @md.creator.prepared_by_detail.is_a?(Array) \ +          and @md.creator.prepared_by_detail.length > 0 +            txt='' +            @md.creator.prepared_by_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_digitized_by +        def name +          'creator_digitized_by' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document digitized by name(s)';} +        end +        def tuple +          if defined? @md.creator.digitized_by_detail \ +          and @md.creator.digitized_by_detail.is_a?(Array) \ +          and @md.creator.digitized_by_detail.length > 0 +            txt='' +            @md.creator.digitized_by_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_audio +        def name +          'creator_audio' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document audio by name(s)';} +        end +        def tuple +          if defined? @md.creator.audio_detail \ +          and @md.creator.audio_detail.is_a?(Array) \ +          and @md.creator.audio_detail.length > 0 +            txt='' +            @md.creator.audio_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_video +        def name +          'creator_video' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document video by name(s)';} +        end +        def tuple +          if defined? @md.creator.video_detail \ +          and @md.creator.video_detail.is_a?(Array) \ +          and @md.creator.video_detail.length > 0 +            txt='' +            @md.creator.video_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% language +#taken from other fields +@title: + :language: +@original: + :language: +#not available --> +#@language: +# :document: +# :original: +=end +      def language_document +        def name +          'language_document' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document language';} +        end +        def tuple +          if @lang.list[@md.opt.lng][:n] +            txt=@lang.list[@md.opt.lng][:n] +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def language_document_char +        def name +          'language_document_char' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language_char]}) NOT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document language';} +        end +        def tuple +          #modify check, is now required, SiSUv3d_ +          if defined? @md.opt.lng \ +          and @md.opt.lng=~/\S+/ +            txt=@md.opt.lng +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def language_original +        def name +          'language_original' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata original document/text language';} +        end +        def tuple +          if defined? @md.language.original \ +          and @md.language.original=~/\S+/ +            txt=@md.language.original +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def language_original_char +        def name +          'language_original_char' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language_char]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document language';} +        end +        def tuple +          if defined? @md.language.original_char \ +          and @md.language.original_char=~/\S+/ +            txt=@md.language.original_char +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% date +@date: + :added_to_site: + :available: + :created: + :issued: + :modified: + :published: + :valid: + :translated: + :original_publication: +=end +      def date_added_to_site +        def name +          'date_added_to_site' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +          #"#{name}                DATE," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date added to site';} +        end +        def tuple +          if defined? @md.date.added_to_site \ +          and @md.date.added_to_site=~/\S+/ +            txt=@md.date.added_to_site +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_available +        def name +          'date_available' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date added to site [DC]';} +        end +        def tuple +          if defined? @md.date.available \ +          and @md.date.available=~/\S+/ +            txt=@md.date.available +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_created +        def name +          'date_created' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date created [DC]';} +        end +        def tuple +          if defined? @md.date.created \ +          and @md.date.created=~/\S+/ +            txt=@md.date.created +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_issued +        def name +          'date_issued' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date issued [DC]';} +        end +        def tuple +          if defined? @md.date.issued \ +          and @md.date.issued=~/\S+/ +            txt=@md.date.issued +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_modified +        def name +          'date_modified' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date modified [DC]';} +        end +        def tuple +          if defined? @md.date.modified \ +          and @md.date.modified=~/\S+/ +            txt=@md.date.modified +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_published +        def name +          'date_published' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date published [DC7]';} +        end +        def tuple +          if defined? @md.date.published \ +          and @md.date.published=~/\S+/ +            txt=@md.date.published +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_valid +        def name +          'date_valid' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date valid [DC]';} +        end +        def tuple +          if defined? @md.date.valid \ +          and @md.date.valid=~/\S+/ +            txt=@md.date.valid +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_translated +        def name +          'date_translated' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date translated';} +        end +        def tuple +          if defined? @md.date.translated \ +          and @md.date.translated=~/\S+/ +            txt=@md.date.translated +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_original_publication +        def name +          'date_original_publication' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date of original publication';} +        end +        def tuple +          if defined? @md.date.original_publication \ +          and @md.date.original_publication=~/\S+/ +            txt=@md.date.original_publication +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_generated +        def name +          'date_generated' +        end +        def create_column              #choose other representation of time +          "#{name}                VARCHAR(30) NULL," +          #"#{name}                VARCHAR(10) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date of sisu generation of document, automatically populated';} +        end +        def tuple                      #choose other representation of time +          if defined? @md.generated \ +          and @md.generated.to_s=~/\S+/ +            txt=@md.generated.to_s +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% publisher +@publisher: +=end +      def publisher +        def name +          'publisher' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document publisher [DC5]';} +        end +        def tuple +          if defined? @md.publisher \ +          and @md.publisher=~/\S+/ +            txt=@md.publisher +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +##% current +#    def current_publisher +#      def name +#        'current_publisher' +#      end +#      def size +#        10 +#      end +#      def create_column +#        "#{name}                VARCHAR(#{current_publisher.size}) NULL," +#      end +#      def tuple +#        t=if defined? @md.current.publisher \ +#        and @md.current.publisher=~/\S+/ +#          txt=@md.current.publisher +#          txt=special_character_escape(txt) +#          "'#{txt}', " +#        end +#      end +#      self +#    end +=begin +#% original +@original: + :publisher: + #:date:                                #repeated under date + :language: + :institution: + :nationality: + :source: +=end +      def original_publisher +        def name +          'original_publisher' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original publisher [DC5]';} +        end +        def tuple +          if defined? @md.original.publisher \ +          and @md.original.publisher=~/\S+/ +            txt=@md.original.publisher +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_language +        def name +          'original_language' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original language';} +        end +        def tuple +          if defined? @md.original.language \ +          and @md.original.language=~/\S+/ +            txt=@md.original.language +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_language_char         # consider +        def name +          'original_language_char' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language_char]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original language iso character';} +        end +        def tuple +          if defined? @md.original.language_char \ +          and @md.original.language_char=~/\S+/ +            txt=@md.original.language_char +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_source +        def name +          'original_source' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original source [DC11]';} +        end +        def tuple +          if defined? @md.original.source \ +          and @md.original.source=~/\S+/ +            txt=@md.original.source +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_institution +        def name +          'original_institution' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original institution';} +        end +        def tuple +          if defined? @md.original.institution \ +          and @md.original.institution=~/\S+/ +            txt=@md.original.institution +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_nationality +        def name +          'original_nationality' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original nationality';} +        end +        def tuple +          if defined? @md.original.nationality \ +          and @md.original.nationality=~/\S+/ +            txt=@md.original.nationality +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% rights +@rights: + #:copyright:                          #mapped to :text: used where no other copyrights and included in :all: + :text: + :translation: + :illustrations: + :photographs: + :preparation: + :digitization: + :audio: + :video: + :license: + :all: +=end +      def rights_all +        def name +          'rights' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata rights associated with document (composite) [DC15]';} +        end +        def tuple +          if defined? @md.rights.all \ +          and @md.rights.all=~/\S+/ +            txt=@md.rights.all +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_text +        def name +          'rights_copyright_text' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text';} +        end +        def tuple +          if defined? @md.rights.copyright_text \ +          and @md.rights.copyright_text=~/\S+/ +            txt=@md.rights.copyright_text +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_translation +        def name +          'rights_copyright_translation' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text translation (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_translation \ +          and @md.rights.copyright_translation=~/\S+/ +            txt=@md.rights.copyright_translation +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_illustrations +        def name +          'rights_copyright_illustrations' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text illustrations (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_illustrations \ +          and @md.rights.copyright_illustrations=~/\S+/ +            txt=@md.rights.copyright_illustrations +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_photographs +        def name +          'rights_copyright_photographs' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text photographs (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_photographs \ +          and @md.rights.copyright_photographs=~/\S+/ +            txt=@md.rights.copyright_photographs +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_preparation +        def name +          'rights_copyright_preparation' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text preparation (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_preparation \ +          and @md.rights.copyright_preparation=~/\S+/ +            txt=@md.rights.copyright_preparation +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_digitization +        def name +          'rights_copyright_digitization' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text digitization (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_digitization \ +          and @md.rights.copyright_digitization=~/\S+/ +            txt=@md.rights.copyright_digitization +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_audio +        def name +          'rights_copyright_audio' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text audio (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_audio \ +          and @md.rights.copyright_audio=~/\S+/ +            txt=@md.rights.copyright_audio +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_video +        def name +          'rights_copyright_video' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text video (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_video \ +          and @md.rights.copyright_video=~/\S+/ +            txt=@md.rights.copyright_video +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_license +        def name +          'rights_license' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata license granted for use of document if any)';} +        end +        def tuple +          if defined? @md.rights.license \ +          and @md.rights.license=~/\S+/ +            txt=@md.rights.license +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% identifier +@identifier: + :oclc: + :isbn: +=end +      def identifier_oclc +        def name +          'identifier_oclc' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_library]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata identifier document Online Computer Library Center number';} +        end +        def tuple +          if defined? @md.identifier.oclc \ +          and @md.identifier.oclc=~/\S+/ +            txt=@md.identifier.oclc +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def identifier_isbn +        def name +          'identifier_isbn' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_small]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata identifier document isbn (if any)';} +        end +        def tuple +          if defined? @md.identifier.isbn \ +          and @md.identifier.isbn=~/\S+/ +            txt=@md.identifier.isbn +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% classify +@classify: + :topic_register: + :subject: + :keywords: + :type: + :loc: + :dewey: +=end +      def classify_topic_register +        def name +          'classify_topic_register' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document topic register (semi-structured document subject information)';} +        end +        def tuple +          if defined? @md.classify.topic_register \ +          and @md.classify.topic_register=~/\S+/ +            txt=@md.classify.topic_register +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def classify_subject +        def name +          'classify_subject' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document subject matter [DC3]';} +        end +        def tuple +          if defined? @md.classify.subject \ +          and @md.classify.subject=~/\S+/ +            txt=@md.classify.subject +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def classify_loc +        def name +          'classify_loc' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_library]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document Library of Congress';} +        end +        def tuple +          if defined? @md.classify.loc \ +          and @md.classify.loc=~/\S+/ +            txt=@md.classify.loc +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def classify_dewey +        def name +          'classify_dewey' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_library]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document Dewey';} +        end +        def tuple +          if defined? @md.classify.dewey \ +          and @md.classify.dewey=~/\S+/ +            txt=@md.classify.dewey +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def classify_keywords +        def name +          'classify_keywords' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document keywords';} +        end +        def tuple +          if defined? @md.classify.keywords \ +          and @md.classify.keywords=~/\S+/ +            txt=@md.classify.keywords +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% notes +@notes: + :abstract: + :description: + :comment: + :coverage: + :relation: + :format: + :history: + :prefix: + :prefix_a: + :prefix_b: + :suffix: +=end +      def notes_abstract +        def name +          'notes_abstract' +        end +        def create_column +          "#{name}                     TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes abstract';} +        end +        def tuple +          if defined? @md.notes.abstract \ +          and @md.notes.abstract=~/\S+/ +            txt=@md.notes.abstract +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_description +        def name +          'notes_description' +        end +        def create_column +          "#{name}                    TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes description [DC4]';} +        end +        def tuple +          if defined? @md.notes.description \ +          and @md.notes.description=~/\S+/ +            txt=@md.notes.description +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_comment +        def name +          'notes_comment' +        end +        def create_column +          "#{name}                       TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes comment';} +        end +        def tuple +          if defined? @md.notes.comment \ +          and @md.notes.comment=~/\S+/ +            txt=@md.notes.comment +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_coverage +        def name +          'notes_coverage' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_short]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document coverage [DC14]';} +        end +        def tuple +          if defined? @md.classify.coverage \ +          and @md.classify.coverage=~/\S+/ +            txt=@md.classify.coverage +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_relation +        def name +          'notes_relation' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_short]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document relation [DC13]';} +        end +        def tuple +          if defined? @md.classify.relation \ +          and @md.classify.relation=~/\S+/ +            txt=@md.classify.relation +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_history   #check, consider removal +        def name +          'notes_history' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes history';} +        end +        def tuple +          if defined? @md.notes.history \ +          and @md.notes.history=~/\S+/ +            txt=@md.notes.history +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_type #check +        def name +          'notes_type' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata notes document type [DC8]';} +        end +        def tuple +          if defined? @md.notes.type \ +          and @md.notes.type=~/\S+/ +            txt=@md.notes.type +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_format +        def name +          'notes_format' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document format [DC9]';} +        end +        def tuple +          if defined? @md.classify.format \ +          and @md.classify.format=~/\S+/ +            txt=@md.classify.format +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_prefix +        def name +          'notes_prefix' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes prefix';} +        end +        def tuple +          if defined? @md.notes.prefix \ +          and @md.notes.prefix=~/\S+/ +            txt=@md.notes.prefix +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_prefix_a +        def name +          'notes_prefix_a' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes prefix_a';} +        end +        def tuple +          if defined? @md.notes.prefix_a \ +          and @md.notes.prefix_a=~/\S+/ +            txt=@md.notes.prefix_a +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_prefix_b +        def name +          'notes_prefix_b' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes prefix_b';} +        end +        def tuple +          if defined? @md.notes.prefix_b \ +          and @md.notes.prefix_b=~/\S+/ +            txt=@md.notes.prefix_b +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_suffix +        def name +          'notes_suffix' +        end +        def create_column                # keep text +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes suffix';} +        end +        def tuple +          if defined? @md.notes.suffix \ +          and @md.notes.suffix=~/\S+/ +            txt=@md.notes.suffix +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% src +=end +      def src_filename +        def name +          'src_filename' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_filename]}) NOT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'sisu markup source text filename';} +        end +        def tuple +          if defined? @md.fns \ +          and @md.fns=~/\S+/ +            txt=@md.fns +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def src_fingerprint +        def name +          'src_fingerprint' #hash/digest, sha512, sha256 or md5 +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_digest]}) NULL," +          #"#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'sisu markup source text fingerprint, hash digest sha512, sha256 or md5';} +        end +        def tuple +          if defined? @md.dgst \ +          and @md.dgst.is_a?(Array) \ +          and @md.dgst[1]=~/\S+/ +            txt=@md.dgst[1] +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def src_filesize +        def name +          'src_filesize' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_filesize]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'sisu markup source text file size';} +        end +        def tuple +         if defined? @md.filesize \ +         and @md.filesize=~/\S+/ +           txt=@md.filesize +           txt=special_character_escape(txt) +           ["#{name}, ","'#{txt}', "] +         else ['',''] +         end +        end +        self +      end +      def src_word_count +        def name +          'src_word_count' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'sisu markup source text word count';} +        end +        def tuple +          if defined? @md.wc_words \ +          and @md.wc_words.to_s=~/\S+/ +            txt=@md.wc_words +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def src_txt                      # consider naming sisusrc +        def name +          'src_text' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'sisu markup source text (if shared)';} +        end +        def tuple +          if ((@md.opt.act[:psql_import][:set]==:on \ +          || @md.opt.act[:psql_update][:set]==:on) \ +          or (@md.opt.act[:sqlite_import][:set]==:on \ +          || @md.opt.act[:sqlite_update][:set]==:on)) \ +          and FileTest.exist?(@md.fns) +            ["#{name}, ","'#{@sisutxt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% misc +@links: +=end +      def fulltext +        def name +          'fulltext' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'document full text clean, searchable';} +        end +        def tuple +          if ((@md.opt.act[:psql_import][:set]==:on \ +          || @md.opt.act[:psql_update][:set]==:on) \ +          or (@md.opt.act[:sqlite_import][:set]==:on \ +          || @md.opt.act[:sqlite_update][:set]==:on)) \ +          and  FileTest.exist?(@md.fns) +            ["#{name}, ","'#{@fulltext}', "] +          else ['',''] +          end +        end +        self +      end +      def links +        def name +          'links' +        end +        def create_column +          "#{name}                TEXT NULL," +          #"#{name}                 VARCHAR(#{links.size}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document links';} +        end +        #def tuple +        #  #BUG HERE - links is an array of paired values :say :url +        #  if defined? @md.links \ +        #  and @md.links=~/\S+/ +        #    txt=@md.links +        #    txt=special_character_escape(txt) +        #    ["#{name}, ","'#{txt}', "] +        #  else ['',''] +        #  end +        #end +        self +      end +      self +    end +  end +  class ColumnSize +    def document_clean # restriction not necessary +      60000 +    end +    def document_body +      16000 +    end +    def document_seg +      120 +    end +    def document_seg_full +      120 +    end +    def endnote_clean # restriction not necessary +      60000 +    end +    def endnote_body +      16000 +    end +  end +end +__END__ +#+END_SRC + +** db_indexes.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_indexes.rb" +# <<sisu_document_header>> +module SiSU_DbIndex +  class Index                                           # create documents Indexes def initialize(opt,conn='',sql_type) +    def initialize(opt,conn,file,sql_type) +      @opt,@conn,@file,@sql_type=opt,conn,file,sql_type +    end +    def create_indexes                                                           # check added from pg not tested +      def conn_execute_sql_pg(conn,sql) +        conn.exec_params(sql) +      end +      def conn_execute_sql_sqlite(conn,sql) +        conn.execute(sql) +      end +      def conn_execute_sql(conn,sql) +        if @sql_type==:pg +          conn_execute_sql_pg(conn,sql) +        elsif @sql_type==:sqlite +          conn_execute_sql_sqlite(conn,sql) +        else +        end +      end +      def conn_execute_array(sql_arr) +        begin +          @conn.transaction do |conn| +            sql_arr.each do |sql| +              conn_execute_sql(conn,sql) +            end +          end +        rescue +          if @conn.is_a?(NilClass) +            errmsg="No sqlite3 connection (check sqlite3 dependencies)" +            if @opt.act[:no_stop][:set]==:on +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, proceeding without sqlite output (as requested)") +            else +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, STOPPING") +              exit +            end +          end +        end +      end +      def base +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          print "\n          create documents common indexes\n" +        end +        sql_arr=[ +          %{CREATE INDEX idx_ocn ON doc_objects(ocn);}, +          %{CREATE INDEX idx_digest_clean ON doc_objects(digest_clean);}, +          %{CREATE INDEX idx_digest_all ON doc_objects(digest_all);}, +          %{CREATE INDEX idx_lev0 ON doc_objects(lev0);}, +          %{CREATE INDEX idx_lev1 ON doc_objects(lev1);}, +          %{CREATE INDEX idx_lev2 ON doc_objects(lev2);}, +          %{CREATE INDEX idx_lev3 ON doc_objects(lev3);}, +          %{CREATE INDEX idx_lev4 ON doc_objects(lev4);}, +          %{CREATE INDEX idx_lev5 ON doc_objects(lev5);}, +          %{CREATE INDEX idx_lev6 ON doc_objects(lev6);}, +          %{CREATE INDEX idx_endnote_nr ON endnotes(nr);}, +          %{CREATE INDEX idx_digest_en ON endnotes(digest_clean);}, +          %{CREATE INDEX idx_endnote_nr_asterisk ON endnotes_asterisk(nr);}, +          %{CREATE INDEX idx_endnote_asterisk ON endnotes_asterisk(clean);}, +          %{CREATE INDEX idx_digest_en_asterisk ON endnotes_asterisk(digest_clean);}, +          %{CREATE INDEX idx_endnote_nr_plus ON endnotes_plus(nr);}, +          %{CREATE INDEX idx_endnote_plus ON endnotes_plus(clean);}, +          %{CREATE INDEX idx_digest_en_plus ON endnotes_plus(digest_clean);}, +          %{CREATE INDEX idx_title ON metadata_and_text(title);}, +          %{CREATE INDEX idx_author ON metadata_and_text(creator_author);}, +          %{CREATE INDEX idx_filename ON metadata_and_text(src_filename);}, +          %{CREATE INDEX idx_language ON metadata_and_text(language_document_char);}, +          %{CREATE INDEX idx_topics ON metadata_and_text(classify_topic_register)}, +        ] +        conn_execute_array(sql_arr) +      end +      def text +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          print "\n          create documents TEXT indexes\n" +        end +        sql_arr=[ +          %{CREATE INDEX idx_clean ON doc_objects(clean);}, +          %{CREATE INDEX idx_endnote ON endnotes(clean);} +        ] +        conn_execute_array(sql_arr) +      end +      base +      @opt.act[:psql][:set]==:on ? '' : text +    end +  end +end +__END__ +#+END_SRC + +* db_tests.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_tests.rb" +# <<sisu_document_header>> +module SiSU_DbTests +  class Test +    def initialize(info,opt) +      @ck,@opt=info,opt +      unless @opt.act[:quiet][:set]==:on +        puts @ck.tp[:fns]  if @ck.tp[:fns] and not @ck.tp[:fns].empty? +        puts @ck.tp[:title] if @ck.tp[:title] and not @ck.tp[:title].empty? +        puts @ck.tp[:creator] if @ck.tp[:creator] and not @ck.tp[:creator].empty? +      end +    end +    def verify +      unless @opt.act[:quiet][:set]==:on +        puts @ck.tp[:fns].length.to_s                + ' checklength ' + @ck.tp[:fns]                if @ck.tp[:fns]                and @ck.tp[:fns].length                >@ck.lt_filename +        puts @ck.tp[:title].length.to_s              + ' checklength ' + @ck.tp[:title]              if @ck.tp[:title]              and @ck.tp[:title].length              >@ck.lt_title +        puts @ck.tp[:subtitle].length.to_s           + ' checklength ' + @ck.tp[:subtitle]           if @ck.tp[:subtitle]           and @ck.tp[:subtitle].length           >@ck.lt_subtitle +        puts @ck.tp[:creator].length.to_s            + ' checklength ' + @ck.tp[:creator]            if @ck.tp[:creator]            and @ck.tp[:creator].length            >@ck.lt_creator +        puts @ck.tp[:author_title].length.to_s       + ' checklength ' + @ck.tp[:author_title]       if @ck.tp[:author_title]       and @ck.tp[:author_title].length       >@ck.lt_author_title +        puts @ck.tp[:illustrator].length.to_s        + ' checklength ' + @ck.tp[:illustrator]        if @ck.tp[:illustrator]        and @ck.tp[:illustrator].length        >@ck.lt_illustrator +        puts @ck.tp[:translator].length.to_s         + ' checklength ' + @ck.tp[:translator]         if @ck.tp[:translator]         and @ck.tp[:translator].length         >@ck.lt_translator +        puts @ck.tp[:prepared_by].length.to_s        + ' checklength ' + @ck.tp[:prepared_by]        if @ck.tp[:prepared_by]        and @ck.tp[:prepared_by].length        >@ck.lt_prepared_by +        puts @ck.tp[:digitized_by].length.to_s       + ' checklength ' + @ck.tp[:digitized_by]       if @ck.tp[:digitized_by]       and @ck.tp[:digitized_by].length       >@ck.lt_digitized_by +        puts @ck.tp[:subject].length.to_s            + ' checklength ' + @ck.tp[:subject]            if @ck.tp[:subject]            and @ck.tp[:subject].length            >@ck.lt_subject +        puts @ck.tp[:description].length.to_s        + ' checklength ' + @ck.tp[:description]        if @ck.tp[:description]        and @ck.tp[:description].length        >@ck.lt_description +        puts @ck.tp[:publisher].length.to_s          + ' checklength ' + @ck.tp[:publisher]          if @ck.tp[:publisher]          and @ck.tp[:publisher].length          >@ck.lt_publisher +        puts @ck.tp[:contributor].length.to_s        + ' checklength ' + @ck.tp[:contributor]        if @ck.tp[:contributor]        and @ck.tp[:contributor].length        >@ck.lt_contributor +        puts @ck.tp[:date].length.to_s               + ' checklength ' + @ck.tp[:date]               if @ck.tp[:date]               and @ck.tp[:date].length               >@ck.lt_date +        puts @ck.tp[:date_created].length.to_s       + ' checklength ' + @ck.tp[:date_created]       if @ck.tp[:date_created]       and @ck.tp[:date_created].length       >@ck.lt_date +        puts @ck.tp[:date_issued].length.to_s        + ' checklength ' + @ck.tp[:date_issued]        if @ck.tp[:date_issued]        and @ck.tp[:date_issued].length        >@ck.lt_date +        puts @ck.tp[:date_valid].length.to_s         + ' checklength ' + @ck.tp[:date_valid]         if @ck.tp[:date_valid]         and @ck.tp[:date_valid].length         >@ck.lt_date +        puts @ck.tp[:date_available].length.to_s     + ' checklength ' + @ck.tp[:date_available]     if @ck.tp[:date_available]     and @ck.tp[:date_available].length     >@ck.lt_date +        puts @ck.tp[:date_modified].length.to_s      + ' checklength ' + @ck.tp[:date_modified]      if @ck.tp[:date_modified]      and @ck.tp[:date_modified].length      >@ck.lt_date +        puts @ck.tp[:date_translated].length.to_s    + ' checklength ' + @ck.tp[:date_translated]    if @ck.tp[:date_translated]    and @ck.tp[:date_translated].length    >@ck.lt_date +        puts @ck.tp[:date_added_to_site].length.to_s + ' checklength ' + @ck.tp[:date_added_to_site] if @ck.tp[:date_added_to_site] and @ck.tp[:date_added_to_site].length >@ck.lt_date +        puts @ck.tp[:type].length.to_s               + ' checklength ' + @ck.tp[:type]               if @ck.tp[:type]               and @ck.tp[:type].length               >@ck.lt_type +        puts @ck.tp[:format].length.to_s             + ' checklength ' + @ck.tp[:format]             if @ck.tp[:format]             and @ck.tp[:format].length             >@ck.lt_format +        puts @ck.tp[:identifier].length.to_s         + ' checklength ' + @ck.tp[:identifier]         if @ck.tp[:identifier]         and @ck.tp[:identifier].length         >@ck.lt_identifier +        puts @ck.tp[:source].length.to_s             + ' checklength ' + @ck.tp[:source]             if @ck.tp[:source]             and @ck.tp[:source].length             >@ck.lt_source +        puts @ck.tp[:language].length.to_s           + ' checklength ' + @ck.tp[:language]           if @ck.tp[:language]           and @ck.tp[:language].length           >@ck.lt_language +        puts @ck.tp[:language_original].length.to_s  + ' checklength ' + @ck.tp[:language_original]  if @ck.tp[:language_original]  and @ck.tp[:language_original].length  >@ck.lt_language_original +        puts @ck.tp[:relation].length.to_s           + ' checklength ' + @ck.tp[:relation]           if @ck.tp[:relation]           and @ck.tp[:relation].length           >@ck.lt_relation +        puts @ck.tp[:coverage].length.to_s           + ' checklength ' + @ck.tp[:coverage]           if @ck.tp[:coverage]           and @ck.tp[:coverage].length           >@ck.lt_coverage +        puts @ck.tp[:rights].length.to_s             + ' checklength ' + @ck.tp[:rights]             if @ck.tp[:rights]             and @ck.tp[:rights].length             >@ck.lt_rights +        puts @ck.tp[:copyright].length.to_s          + ' checklength ' + @ck.tp[:copyright]          if @ck.tp[:copyright]          and @ck.tp[:copyright].length          >@ck.lt_copyright +        puts @ck.tp[:owner].length.to_s              + ' checklength ' + @ck.tp[:owner]              if @ck.tp[:owner]              and @ck.tp[:owner].length              >@ck.lt_owner +        puts @ck.tp[:keywords].length.to_s           + ' checklength ' + @ck.tp[:keywords]           if @ck.tp[:keywords]           and @ck.tp[:keywords].length           >@ck.lt_keywords +        puts @ck.tp[:abstract].length.to_s           + ' checklength ' + @ck.tp[:abstract]           if @ck.tp[:abstract]           and @ck.tp[:abstract].length           >@ck.lt_abstract +        puts @ck.tp[:comment].length.to_s            + ' checklength ' + @ck.tp[:comment]            if @ck.tp[:comment]            and @ck.tp[:comment].length            >@ck.lt_comment +        puts @ck.tp[:loc].length.to_s                + ' checklength ' + @ck.tp[:loc]                if @ck.tp[:loc]                and @ck.tp[:loc].length                >@ck.lt_loc +        puts @ck.tp[:dewey].length.to_s              + ' checklength ' + @ck.tp[:dewey]              if @ck.tp[:dewey]              and @ck.tp[:dewey].length              >@ck.lt_dewey +        puts @ck.tp[:isbn].length.to_s               + ' checklength ' + @ck.tp[:isbn]               if @ck.tp[:isbn]               and @ck.tp[:isbn].length               >@ck.lt_isbn +        puts @ck.tp[:pg].length.to_s                 + ' checklength ' + @ck.tp[:pg]                 if @ck.tp[:pg]                 and @ck.tp[:pg].length                 >@ck.lt_pg +        puts @ck.tp[:topic_register].length.to_s     + ' checklength ' + @ck.tp[:topic_register]     if @ck.tp[:topic_register]     and @ck.tp[:topci_register].length     >@ck.lt_topic_register +        puts @ck.tp[:date]                                                                           if @ck.tp[:date] and not @ck.tp[:date].empty? and @ck.tp[:date] !~/\d\d-\d\d-\d\d/ +      end +    end +  end +end +__END__ +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + +  - Description: documents, structuring, processing, publishing, search +    db sql + +  - Author: Ralph Amissah +    <ralph.amissah@gmail.com> + +  - Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +    2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, +    2020, 2021, Ralph Amissah, +    All Rights Reserved. + +  - License: GPL 3 or later: + +    SiSU, a framework for document structuring, publishing and search + +    Copyright (C) Ralph Amissah + +    This program is free software: you can redistribute it and/or modify it +    under the terms of the GNU General Public License as published by the Free +    Software Foundation, either version 3 of the License, or (at your option) +    any later version. + +    This program is distributed in the hope that it will be useful, but WITHOUT +    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +    more details. + +    You should have received a copy of the GNU General Public License along with +    this program. If not, see <http://www.gnu.org/licenses/>. + +    If you have Internet connection, the latest version of the GPL should be +    available at these locations: +    <http://www.fsf.org/licensing/licenses/gpl.html> +    <http://www.gnu.org/licenses/gpl.html> + +    <http://www.sisudoc.org/sisu/en/manifest/gpl.fsf.html> + +  - SiSU uses: +    - Standard SiSU markup syntax, +    - Standard SiSU meta-markup syntax, and the +    - Standard SiSU object citation numbering and system + +  - Homepages: +    <http://www.sisudoc.org> + +  - Git +    <https://git.sisudoc.org/projects/> +    <https://git.sisudoc.org/projects/?p=software/sisu.git;a=summary> +    <https://git.sisudoc.org/projects/?p=markup/sisu-markup-samples.git;a=summary> +#+END_SRC | 
