P4Record (Class)

In: p4table.rb
Parent: Object

Main record manipulation class. Handles the loading and saving of records as both jobs and files.

Methods

abandon   add_file   create   delete   each_file   exists=   exists?   exists?   file_list   get_file   load   metafile   method_missing   new   obliterate   query   rm_file   save  

Attributes

files  [R] 
id  [RW] 
meta  [RW] 
seq  [RW] 
spec  [RW] 
table  [RW] 

Public Class methods

Create a new record in the given table. Returns the skeletal record populated with the default values from the jobspec for editing.

[Source]

     # File p4table.rb, line 477
477:     def P4Record.create( table )
478:         id = P4RecId.next( table )
479:         rec = P4Record.new( id )
480:         rec.spec = P4Global.tagged.fetch_job( id.to_s )
481:         return rec
482:     end

Test for record existence

[Source]

     # File p4table.rb, line 487
487:     def P4Record.exists?( id )
488:         jobs = P4Global.tagged.run_jobs( "-e", "job=" + id.to_s )
489:         return jobs.length > 0 
490:     end

Load a record from its associated job. Use to load existing records rather than constructing new ones. Raises a RuntimeError if the record does not exist.

[Source]

     # File p4table.rb, line 427
427:     def P4Record.load( id )
428: 
429:         if ( ! P4Record.exists?( id ) )
430:             raise( RuntimeError, "Record #{id.to_s} does not exist", caller )
431:         end
432: 
433:         rec = P4Record.new( id )
434:         rec.spec = P4Global.tagged.fetch_job( id.to_s )
435:         if rec.spec.has_key?( "files" )
436:             rec.spec[ "files" ].each do
437:                 |file|
438:                 name = file.sub( ".*/", "" ).chomp
439:                 f = P4RecFile.new( name, id ) 
440:                 f.exists = true
441:                 f.depot_path = file.chomp
442:                 rec.files[ name ] =  f
443:             end
444:         end
445:         rec.exists = true
446:         return rec
447:     end

Constructor: DON‘T USE NEW DIRECTLY, CALL create/load.

[Source]

     # File p4table.rb, line 495
495:     def initialize( id )
496:         @id    = id
497:         @table = id.table
498:         @seq   = id.seq
499:         @spec  = nil
500:         @exists        = false
501:         @files = Hash.new
502: 
503:         @files[ "meta" ] = P4RecFile.new( "meta", @id )
504:     end

Load all records matching a query expression. Uses a dynamically built "p4 jobs -e" expression to identify the matching records and then loads each record. Returns an array of P4Record objects.

[Source]

     # File p4table.rb, line 454
454:     def P4Record.query( table, expr )
455:         expr = "job=#{table} & ( " + expr + " )"
456:         P4Global.tagged.run_jobs( "-e", expr ).collect do
457:             |job|
458:             rec = P4Record.new( P4RecId.new_from_job( job[ "job" ] ) )
459:             rec.spec = job
460:             rec.spec[ "files" ].each do
461:                 |file|
462:                 name = file.sub( ".*/", "" ).chomp
463:                 f = P4RecFile.new( name, id ) 
464:                 f.exists = true
465:                 f.depot_path = file
466:                 rec.files[ name ] =  f
467:             end
468:             rec.exists = true
469:             rec
470:         end
471:     end

Public Instance methods

Abandon all edits to this record. Use with care: it reverts the files that are open for add/edit/delete etc. but it doesn’t reload the record from the job - it may be a new record. You should either discard the record or reload it yourself after calling abandon().

[Source]

     # File p4table.rb, line 580
580:     def abandon
581:         p4 = P4Global.tagged
582:         each_file do
583:             |f|
584:             fs = p4.run_fstat( f.ws_path )
585:             if ( fs && fs[ "action" ] == "add" )
586:                 File.unlink( f.ws_path )
587:             end
588:             p4.run_revert( f.depot_path )
589:         end
590:     end

Add a new file attachment to this record

[Source]

     # File p4table.rb, line 550
550:     def add_file( name )
551:         if ( name == "meta" )
552:             raise( RuntimeError, "The meta file already exists.", caller )
553:         end
554: 
555:         nfile = P4RecFile.new( name, @id )
556:         nfile.add
557:         @files[ "name" ] =  nfile
558:     end

Delete a record. Deletes the files and the job.

[Source]

     # File p4table.rb, line 636
636:     def delete( desc )
637:         if ( ! exists? )
638:             raise( RuntimeError, "Can't delete. Record doesn't exist.", caller )
639:         end
640: 
641:         @files.values.each { |f| f.delete }
642:         change = P4Global.tagged.fetch_change
643:         change[ "Description" ] = desc
644:         P4Global.tagged.submit_spec( change )
645:         P4Global.tagged.run_job( "-d", @spec[ "job" ] )
646:         @files = Hash.new
647:         @spec[ "files" ] = Array.new
648:         @exists = false
649:     end

Iterate over the files in the record

[Source]

     # File p4table.rb, line 543
543:     def each_file
544:         @files.each_value { |f| yield( f ) }
545:     end

Explicitly set record existence (or otherwise)

[Source]

     # File p4table.rb, line 519
519:     def exists=( bool )
520:         @exists = bool
521:     end

Test for record existence

[Source]

     # File p4table.rb, line 512
512:     def exists?
513:         return @exists
514:     end

Get the list of files attached to this record in depot syntax

[Source]

     # File p4table.rb, line 595
595:     def file_list
596:         @files.values.collect do
597:             |f|
598:             f.depot_path
599:         end.compact.join( "\n" )
600:     end

Get a file handle by name (not the depot path). Returns a P4RecFile object.

[Source]

     # File p4table.rb, line 528
528:     def get_file( name )
529:         return @files[ name ] if @files.has_key?( name )
530:         raise( RuntimeError, "Record contains no file called #{name}", caller )
531:     end

Get the meta file specifically. Just shorthand.

[Source]

     # File p4table.rb, line 536
536:     def metafile
537:         get_file( "meta" )
538:     end

Allow direct access to the fields in the jobspec by making them virtual method names of the form _<field>()

[Source]

     # File p4table.rb, line 675
675:     def method_missing( meth, *args )
676:         meth = meth.to_s
677:         raise if ( meth[0..0] != "_" )
678:         meth = meth[ 1..-1 ]
679:         if ( meth =~ /^(.*)=$/ )
680:             meth = $1
681:             @spec[ meth ] = args.shift
682:         elsif ( args.length == 0 && @spec.has_key?( meth ) )
683:             @spec[ meth ]
684:         else
685:             ""
686:         end
687:     end

Obliterate a record. Does exactly what it says on the tin.

[Source]

     # File p4table.rb, line 655
655:     def obliterate
656:         if ( ! exists? )
657:             raise( RuntimeError, "Can't oblit. Record doesn't exist.", caller )
658:         end
659: 
660:         args = @files.values.collect { |f| f.depot_path } 
661:         P4Global.tagged.exception_level = 1
662:         P4Global.tagged.run_sync( args.collect { |a| a += "#none" } )
663:         P4Global.tagged.exception_level = 2
664:         P4Global.tagged.run_obliterate( "-y", args )
665:         P4Global.tagged.run_job( "-d", @spec[ "job" ] )
666:         @spec[ "files" ] = Array.new
667:         @files = Hash.new
668:         @exists = false
669:     end

Remove a file attachment

[Source]

     # File p4table.rb, line 563
563:     def rm_file( file )
564:         if ( file == "meta" )
565:             raise( RuntimeError, "You can't delete the meta file", caller )
566:         end
567: 
568:         f = get_file( file )
569:         f.delete
570:         @files.delete( file )
571:     end

Update the record. Updates the job and then archives the job into the meta file and saves any attached files. Provide the description you’d like to see attached to the change

[Source]

     # File p4table.rb, line 608
608:     def save( desc )
609:         # First rewrite the files list in case it's been modified
610:         @spec[ "files" ] = file_list
611: 
612:         # Next update the job with the values in the spec
613:         P4Global.tagged.save_job( @spec )
614: 
615:         # Now update the metafile with the job -o output
616:         if ( exists? )
617:             metafile.edit
618:         else
619:             metafile.add
620:         end
621: 
622:         metafile.mkdir
623:         metafile.write( P4Global.plain.fetch_job( @id.to_s ) )
624: 
625:         # Now submit
626:         change = P4Global.tagged.fetch_change
627:         change[ "Description" ] = desc
628:         P4Global.tagged.submit_spec( change )
629: 
630:         @exists = true
631:     end

[Validate]