mongous 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +6 -3
- data/README.ja.adoc +6 -3
- data/lib/mongous/base.rb +12 -2
- data/lib/mongous/extention.rb +4 -0
- data/lib/mongous/filter.rb +57 -14
- data/lib/mongous/version.rb +1 -1
- data/sample/connect_auto_0.rb +1 -1
- data/sample/declare_compact_1.rb +0 -2
- data/sample/declare_compact_2.rb +38 -0
- data/sample/declare_label_1.rb +0 -2
- data/sample/declare_ndex_1.rb +0 -2
- data/sample/declare_ndex_2.rb +0 -2
- data/sample/declare_strict_1.rb +0 -2
- data/sample/declare_strict_2.rb +0 -2
- data/sample/multi_collection_1.rb +0 -2
- data/sample/multi_collection_2.rb +0 -2
- data/sample/multi_collection_3.rb +6 -8
- data/sample/query_basic_1.rb +8 -2
- data/sample/query_basic_2.rb +8 -2
- data/sample/query_basic_3.rb +0 -2
- data/sample/query_basic_4.rb +0 -2
- data/sample/query_basic_5.rb +0 -2
- data/sample/query_basic_6.rb +56 -0
- data/sample/query_detail_1.rb +0 -2
- data/sample/query_detail_2.rb +0 -2
- data/sample/query_detail_3.rb +0 -2
- data/sample/query_filter_1.rb +0 -2
- data/sample/query_filter_2.rb +0 -2
- data/sample/query_find_1.rb +6 -5
- data/sample/query_select_1.rb +8 -5
- data/sample/query_skip_limit_1.rb +17 -16
- data/sample/query_skip_limit_2.rb +19 -10
- data/sample/query_sort_1.rb +43 -0
- data/sample/save_basic_1.rb +1 -5
- data/sample/save_basic_2.rb +1 -5
- data/sample/save_basic_3.rb +1 -5
- data/sample/save_detail_1.rb +0 -2
- data/sample/save_detail_2.rb +0 -2
- data/sample/save_detail_3.rb +0 -2
- data/sample/save_verify_1.rb +0 -2
- data/sample/save_verify_2.rb +0 -2
- data/sample/save_verify_3.rb +0 -2
- data/sample/save_verify_4.rb +0 -2
- data/sample/save_verify_5.rb +0 -2
- data/sample/save_verify_6.rb +0 -2
- data/sample/save_verify_7.rb +0 -2
- data/sample/update_basic_1.rb +1 -5
- data/sample/zap_basic_1.rb +1 -5
- data/sample/zap_basic_2.rb +2 -6
- data/sample/zap_basic_3.rb +1 -5
- data/sample/zbenchmark_search_1.rb +19 -15
- data/sample/zbenchmark_search_2.rb +19 -15
- data/sample/zbenchmark_search_3.rb +25 -27
- metadata +5 -3
- data/sample/query_sort_order_1.rb +0 -46
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 8b0a73aa23287619bdae717f683f04e266d582dca4a6d055b798cf32243c6566
         | 
| 4 | 
            +
              data.tar.gz: 14e22dcbf25b3a0fa200023c9f770c549607060ddb03057b32c8c1ccee3b58c2
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b37766d78679cc2a6bee8bfe256da0a363344b6e349552f0491d5a0892fa1dfeb7cca90d4b2e326ac7687cdd2c3a0561fdfe9fca4ce71382029077d8c289e6de
         | 
| 7 | 
            +
              data.tar.gz: b5e9fee3f8f9d4f34d5203b9b260559d8ee1ca86e659d85629ef9c1b700bcfcb450b7ffc0447b7f3fa8c4245634f2e968619f9ba451c9591016e13c07d23060f
         | 
    
        data/README.adoc
    CHANGED
    
    | @@ -38,7 +38,7 @@ Or install it yourself as: | |
| 38 38 | 
             
            ----
         | 
| 39 39 | 
             
            require  "mongous"
         | 
| 40 40 |  | 
| 41 | 
            -
            Mongous. | 
| 41 | 
            +
            Mongous.document!  :Book
         | 
| 42 42 | 
             
            ----
         | 
| 43 43 |  | 
| 44 44 | 
             
            === Detail declaration
         | 
| @@ -102,7 +102,8 @@ Book.create( **doc ) | |
| 102 102 | 
             
            ----
         | 
| 103 103 | 
             
            pp books = Book.all
         | 
| 104 104 |  | 
| 105 | 
            -
            p book = Book.where( title:  | 
| 105 | 
            +
            p book = Book.where( title: /title/ ).first
         | 
| 106 | 
            +
            p book = Book.where( title: /title/ ).last
         | 
| 106 107 |  | 
| 107 108 | 
             
            books = Book.where( title: /title/ ).all
         | 
| 108 109 | 
             
            books.each do |book|
         | 
| @@ -198,7 +199,7 @@ Mongous.connect( hosts_or_uri = nil, **options ) | |
| 198 199 |  | 
| 199 200 | 
             
            [source,ruby]
         | 
| 200 201 | 
             
            ----
         | 
| 201 | 
            -
            Mongous. | 
| 202 | 
            +
            Mongous.document!( *names, **options )
         | 
| 202 203 | 
             
            ----
         | 
| 203 204 |  | 
| 204 205 | 
             
            * Result:
         | 
| @@ -206,6 +207,8 @@ Mongous.attach!( *names ) | |
| 206 207 |  | 
| 207 208 | 
             
            * Parameter:
         | 
| 208 209 | 
             
              ** names:           Collection names. (String or Symbol)
         | 
| 210 | 
            +
              ** options:         Options.
         | 
| 211 | 
            +
                *** timestamp:    If true then add fields :created_at, :updated_at.
         | 
| 209 212 |  | 
| 210 213 | 
             
            === Include document functions into collection operate class.
         | 
| 211 214 |  | 
    
        data/README.ja.adoc
    CHANGED
    
    | @@ -38,7 +38,7 @@ gem 'mongous' | |
| 38 38 | 
             
            ----
         | 
| 39 39 | 
             
            require  "mongous"
         | 
| 40 40 |  | 
| 41 | 
            -
            Mongous. | 
| 41 | 
            +
            Mongous.document!  :Book
         | 
| 42 42 | 
             
            ----
         | 
| 43 43 |  | 
| 44 44 | 
             
            === 詳細な定義
         | 
| @@ -102,7 +102,8 @@ Book.create( **doc ) | |
| 102 102 | 
             
            ----
         | 
| 103 103 | 
             
            pp books = Book.all
         | 
| 104 104 |  | 
| 105 | 
            -
            p book = Book.where( title:  | 
| 105 | 
            +
            p book = Book.where( title: /title/ ).first
         | 
| 106 | 
            +
            p book = Book.where( title: /title/ ).last
         | 
| 106 107 |  | 
| 107 108 | 
             
            books = Book.where( title: /title/ ).all
         | 
| 108 109 | 
             
            books.each do |book|
         | 
| @@ -198,7 +199,7 @@ Mongous.connect( hosts_or_uri = nil, **options ) | |
| 198 199 |  | 
| 199 200 | 
             
            [source,ruby]
         | 
| 200 201 | 
             
            ----
         | 
| 201 | 
            -
            Mongous. | 
| 202 | 
            +
            Mongous.document!( *names, **options )
         | 
| 202 203 | 
             
            ----
         | 
| 203 204 |  | 
| 204 205 | 
             
            * Result:
         | 
| @@ -206,6 +207,8 @@ Mongous.attach!( *names ) | |
| 206 207 |  | 
| 207 208 | 
             
            * Parameter:
         | 
| 208 209 | 
             
              ** names:           コレクション名. (String または Symbol)
         | 
| 210 | 
            +
              ** options:         オプション
         | 
| 211 | 
            +
                *** timestamp:    真のとき, フィールド :created_at, :updated_at を追加する.
         | 
| 209 212 |  | 
| 210 213 | 
             
            === コレクション操作クラスにドキュメントの機能を取り入れる.
         | 
| 211 214 |  | 
    
        data/lib/mongous/base.rb
    CHANGED
    
    | @@ -50,7 +50,7 @@ module Mongous | |
| 50 50 | 
             
                  self.class_variable_set( :@@client, _client )
         | 
| 51 51 | 
             
                end
         | 
| 52 52 |  | 
| 53 | 
            -
                def  | 
| 53 | 
            +
                def document!( *names, **opts )
         | 
| 54 54 | 
             
                  raise  Mongous::Error, "missing argument."   if names.empty?
         | 
| 55 55 |  | 
| 56 56 | 
             
                  names.each do |name|
         | 
| @@ -72,13 +72,23 @@ module Mongous | |
| 72 72 | 
             
                      end
         | 
| 73 73 | 
             
                    end
         | 
| 74 74 |  | 
| 75 | 
            -
                    Object.class_eval <<-CLASS
         | 
| 75 | 
            +
                    klass  =  Object.class_eval <<-CLASS
         | 
| 76 76 | 
             
                      class #{name}
         | 
| 77 77 | 
             
                        include Mongous::Document
         | 
| 78 78 | 
             
                      end
         | 
| 79 79 | 
             
                    CLASS
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                    if opts[:timestamp]
         | 
| 82 | 
            +
                      klass.class_eval do
         | 
| 83 | 
            +
                        field  :created_at, Time, create: proc{ Time.now }
         | 
| 84 | 
            +
                        field  :updated_at, Time, update: proc{ Time.now }
         | 
| 85 | 
            +
                        index  :created_at
         | 
| 86 | 
            +
                        index  :updated_at
         | 
| 87 | 
            +
                      end
         | 
| 88 | 
            +
                    end
         | 
| 80 89 | 
             
                  end
         | 
| 81 90 | 
             
                end
         | 
| 91 | 
            +
                alias  :attach!  :document!
         | 
| 82 92 |  | 
| 83 93 | 
             
                def client
         | 
| 84 94 | 
             
                  if not self.class_variable_defined?( :@@client )
         | 
    
        data/lib/mongous/extention.rb
    CHANGED
    
    
    
        data/lib/mongous/filter.rb
    CHANGED
    
    | @@ -5,11 +5,6 @@ module Mongous | |
| 5 5 | 
             
                  self.collection.estimated_document_count
         | 
| 6 6 | 
             
                end
         | 
| 7 7 |  | 
| 8 | 
            -
                def first
         | 
| 9 | 
            -
                  doc  =  self.collection.find.first
         | 
| 10 | 
            -
                  self.new( **doc )    if doc
         | 
| 11 | 
            -
                end
         | 
| 12 | 
            -
             | 
| 13 8 | 
             
                def all
         | 
| 14 9 | 
             
                  self.collection.find.map do |doc|
         | 
| 15 10 | 
             
                    self.new( **doc )
         | 
| @@ -32,6 +27,22 @@ module Mongous | |
| 32 27 | 
             
                  Filter.new( self ).attach( collection_name )
         | 
| 33 28 | 
             
                end
         | 
| 34 29 |  | 
| 30 | 
            +
                def []( nth_or_range, len = nil )
         | 
| 31 | 
            +
                  Filter.new( self )[ nth_or_range, len ]
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def first
         | 
| 35 | 
            +
                  Filter.new( self ).first
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def last
         | 
| 39 | 
            +
                  Filter.new( self ).last
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def sort( *keys, **hash )
         | 
| 43 | 
            +
                  Filter.new( self ).sort( *keys, **hash )
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 35 46 | 
             
                def select( *keys, **hash )
         | 
| 36 47 | 
             
                  Filter.new( self ).select( *keys, **hash )
         | 
| 37 48 | 
             
                end
         | 
| @@ -45,7 +56,7 @@ module Mongous | |
| 45 56 | 
             
                  raise  Mongous::Error, "Unset args for #{self}.not."    if filter.nil? && conditions.empty?
         | 
| 46 57 |  | 
| 47 58 | 
             
                  condition  =  normalize( filter, conditions )
         | 
| 48 | 
            -
                  Filter.new( self ). | 
| 59 | 
            +
                  Filter.new( self ).not( condition )
         | 
| 49 60 | 
             
                end
         | 
| 50 61 |  | 
| 51 62 | 
             
                def and( *filters )
         | 
| @@ -101,7 +112,7 @@ module Mongous | |
| 101 112 | 
             
                  w
         | 
| 102 113 | 
             
                end
         | 
| 103 114 |  | 
| 104 | 
            -
                def  | 
| 115 | 
            +
                def build_condition( conditions )
         | 
| 105 116 | 
             
                  hash  =  {}
         | 
| 106 117 | 
             
                  conditions.each do |key, item|
         | 
| 107 118 | 
             
                    case  key
         | 
| @@ -137,11 +148,23 @@ module Mongous | |
| 137 148 | 
             
                      end
         | 
| 138 149 | 
             
                    end
         | 
| 139 150 | 
             
                  end
         | 
| 151 | 
            +
                  hash
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                def where( conditions )
         | 
| 155 | 
            +
                  hash  =  build_condition( conditions )
         | 
| 140 156 | 
             
                  w  =  self.dup
         | 
| 141 157 | 
             
                  w.instance_variable_set( :@filter, @filter.merge( hash ) )
         | 
| 142 158 | 
             
                  w
         | 
| 143 159 | 
             
                end
         | 
| 144 160 |  | 
| 161 | 
            +
                def not( conditions )
         | 
| 162 | 
            +
                  hash  =  build_condition( conditions )
         | 
| 163 | 
            +
                  w  =  self.dup
         | 
| 164 | 
            +
                  w.instance_variable_set( :@filter, @filter.merge( {"$nor" => [hash]} ) )
         | 
| 165 | 
            +
                  w
         | 
| 166 | 
            +
                end
         | 
| 167 | 
            +
             | 
| 145 168 | 
             
                def to_condition
         | 
| 146 169 | 
             
                  @filter.dup
         | 
| 147 170 | 
             
                end
         | 
| @@ -152,7 +175,7 @@ module Mongous | |
| 152 175 | 
             
                  w
         | 
| 153 176 | 
             
                end
         | 
| 154 177 |  | 
| 155 | 
            -
                def  | 
| 178 | 
            +
                def select( *keys, **hash )
         | 
| 156 179 | 
             
                  if not keys.empty?
         | 
| 157 180 | 
             
                    _projection  =  Hash[ keys.zip( Array.new(keys.length, 1) ) ]
         | 
| 158 181 | 
             
                  elsif not hash.empty?
         | 
| @@ -164,7 +187,6 @@ module Mongous | |
| 164 187 | 
             
                  w.instance_variable_set( :@projection, _projection )
         | 
| 165 188 | 
             
                  w
         | 
| 166 189 | 
             
                end
         | 
| 167 | 
            -
                alias  :select  :projection
         | 
| 168 190 |  | 
| 169 191 | 
             
                def sort( *keys, **hash )
         | 
| 170 192 | 
             
                  if not keys.empty?
         | 
| @@ -178,17 +200,20 @@ module Mongous | |
| 178 200 | 
             
                  w.instance_variable_set( :@sort, _sort )
         | 
| 179 201 | 
             
                  w
         | 
| 180 202 | 
             
                end
         | 
| 181 | 
            -
                alias  :order  :sort
         | 
| 182 203 |  | 
| 183 204 | 
             
                def []( nth_or_range, len = nil )
         | 
| 184 205 | 
             
                  case  nth_or_range
         | 
| 185 206 | 
             
                  when  Integer
         | 
| 186 207 | 
             
                    _skip  =  nth_or_range
         | 
| 187 | 
            -
                    _limit  =  nil
         | 
| 188 208 |  | 
| 189 | 
            -
                    if  len
         | 
| 190 | 
            -
                       | 
| 209 | 
            +
                    if  len.is_a?(NilClass)
         | 
| 210 | 
            +
                      _limit  =  1
         | 
| 211 | 
            +
                    elsif  len.is_a?(Integer) && len == 0
         | 
| 212 | 
            +
                      _limit  =  nil
         | 
| 213 | 
            +
                    elsif  len.is_a?(Integer) && len > 0
         | 
| 191 214 | 
             
                      _limit  =  len
         | 
| 215 | 
            +
                    else
         | 
| 216 | 
            +
                      raise  Mongous::Error, "invalid len. :  #{ len }"
         | 
| 192 217 | 
             
                    end
         | 
| 193 218 |  | 
| 194 219 | 
             
                  when  Range
         | 
| @@ -247,7 +272,25 @@ module Mongous | |
| 247 272 | 
             
                end
         | 
| 248 273 |  | 
| 249 274 | 
             
                def first
         | 
| 250 | 
            -
                   | 
| 275 | 
            +
                  _filter  =  @filter
         | 
| 276 | 
            +
                  _option  =  @option.dup
         | 
| 277 | 
            +
                  _option[:projection]  =  @projection    if @projection
         | 
| 278 | 
            +
                  found  =  @klass.collection( @collection_name ).find( _filter, _option )
         | 
| 279 | 
            +
                  _order  =  @sort  ||  { _id: 1 }
         | 
| 280 | 
            +
                  doc  =  found.sort( _order ).first
         | 
| 281 | 
            +
                  @klass.new( **doc )    if doc
         | 
| 282 | 
            +
                end
         | 
| 283 | 
            +
             | 
| 284 | 
            +
                def last
         | 
| 285 | 
            +
                  _filter  =  @filter
         | 
| 286 | 
            +
                  _option  =  @option.dup
         | 
| 287 | 
            +
                  _option[:projection]  =  @projection    if @projection
         | 
| 288 | 
            +
                  found  =  @klass.collection( @collection_name ).find( _filter, _option )
         | 
| 289 | 
            +
                  _order  =  {}
         | 
| 290 | 
            +
                  ( @sort  ||  {_id: 1} ).each do |k,v|
         | 
| 291 | 
            +
                    _order[k]  =  - v
         | 
| 292 | 
            +
                  end
         | 
| 293 | 
            +
                  doc  =  found.sort( _order ).first
         | 
| 251 294 | 
             
                  @klass.new( **doc )    if doc
         | 
| 252 295 | 
             
                end
         | 
| 253 296 |  | 
    
        data/lib/mongous/version.rb
    CHANGED
    
    
    
        data/sample/connect_auto_0.rb
    CHANGED
    
    
    
        data/sample/declare_compact_1.rb
    CHANGED
    
    
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            require "mongous"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            Mongous.document!  :Book1
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            book  =  Book1.new
         | 
| 7 | 
            +
            book.title       =  "book1"
         | 
| 8 | 
            +
            book.save
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            book  =  Book1.where( title: "book1" ).first
         | 
| 11 | 
            +
            book.author      =  "alice"
         | 
| 12 | 
            +
            book.save
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Book1.each do |book|
         | 
| 15 | 
            +
              pp book
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
            puts
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            Book1.drop
         | 
| 20 | 
            +
             | 
| 21 | 
            +
             | 
| 22 | 
            +
            Mongous.document!  :Book2, timestamp: true
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            book  =  Book2.new
         | 
| 25 | 
            +
            book.title       =  "book2"
         | 
| 26 | 
            +
            book.save
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            book  =  Book2.where( title: "book2" ).first
         | 
| 29 | 
            +
            book.author      =  "bob"
         | 
| 30 | 
            +
            book.save
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            Book2.each do |book|
         | 
| 33 | 
            +
              pp book
         | 
| 34 | 
            +
            end
         | 
| 35 | 
            +
            puts
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            Book2.drop
         | 
| 38 | 
            +
             | 
    
        data/sample/declare_label_1.rb
    CHANGED
    
    
    
        data/sample/declare_ndex_1.rb
    CHANGED
    
    
    
        data/sample/declare_ndex_2.rb
    CHANGED
    
    
    
        data/sample/declare_strict_1.rb
    CHANGED
    
    
    
        data/sample/declare_strict_2.rb
    CHANGED
    
    
| @@ -1,24 +1,22 @@ | |
| 1 1 |  | 
| 2 2 | 
             
            require "mongous"
         | 
| 3 3 |  | 
| 4 | 
            -
            Mongous. | 
| 5 | 
            -
             | 
| 6 | 
            -
            Mongous. | 
| 7 | 
            -
            Mongous.attach!  :Book2
         | 
| 8 | 
            -
            Mongous.attach!  :Book3
         | 
| 4 | 
            +
            Mongous.document!  :Book1
         | 
| 5 | 
            +
            Mongous.document!  :Book2
         | 
| 6 | 
            +
            Mongous.document!  :Book3
         | 
| 9 7 |  | 
| 10 8 | 
             
            pp Book1.collection
         | 
| 11 9 | 
             
            pp Book2.collection
         | 
| 12 10 | 
             
            pp Book3.collection
         | 
| 13 11 |  | 
| 14 | 
            -
            Mongous. | 
| 15 | 
            -
            Mongous. | 
| 12 | 
            +
            Mongous.document!  :Book1
         | 
| 13 | 
            +
            Mongous.document!  :Book2, :Book3
         | 
| 16 14 |  | 
| 17 15 | 
             
            pp Book1.collection
         | 
| 18 16 | 
             
            pp Book2.collection
         | 
| 19 17 | 
             
            pp Book3.collection
         | 
| 20 18 |  | 
| 21 | 
            -
            Mongous. | 
| 19 | 
            +
            Mongous.document!  :Book1, :Book2, :Book3
         | 
| 22 20 |  | 
| 23 21 | 
             
            pp Book1.collection
         | 
| 24 22 | 
             
            pp Book2.collection
         | 
    
        data/sample/query_basic_1.rb
    CHANGED
    
    | @@ -1,21 +1,27 @@ | |
| 1 1 |  | 
| 2 2 | 
             
            require "mongous"
         | 
| 3 3 |  | 
| 4 | 
            -
            Mongous.connect!
         | 
| 5 | 
            -
             | 
| 6 4 | 
             
            class Book
         | 
| 7 5 | 
             
              include  Mongous::Document
         | 
| 8 6 | 
             
            end
         | 
| 9 7 |  | 
| 8 | 
            +
            p "book  =  Book.first"
         | 
| 10 9 | 
             
            p book  =  Book.first
         | 
| 11 10 | 
             
            puts
         | 
| 12 11 |  | 
| 12 | 
            +
            p "book  =  Book.last"
         | 
| 13 | 
            +
            p book  =  Book.last
         | 
| 14 | 
            +
            puts
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            p "count  =  Book.count"
         | 
| 13 17 | 
             
            p count  =  Book.count
         | 
| 14 18 | 
             
            puts
         | 
| 15 19 |  | 
| 20 | 
            +
            p "books  =  Book.all"
         | 
| 16 21 | 
             
            pp books  =  Book.all
         | 
| 17 22 | 
             
            puts
         | 
| 18 23 |  | 
| 24 | 
            +
            p "Book.each do |book|"
         | 
| 19 25 | 
             
            Book.each do |book|
         | 
| 20 26 | 
             
              p book
         | 
| 21 27 | 
             
            end
         |