Class Informix::Slob
In: lib/informix.rb
ext/informixc.c
Parent: Object

The Slob class is the Ruby interface for handling Smart Large Objects. It provides methods for every action applicable to an SLOB.

Examples:

  # Storing BLOBs read from files
  Slob = Informix::Slob
  db.execute("create table album (filename varchar(30), picture blob)")
  st = db.prepare("insert into album values(?, ?)")
  Dir.glob("*jpg") do |filename|
     slob = db.slob(Slob::BLOB)
     slob.write(File.read(filename)) # same as slob <<File.read(filename)
     slob.close
     st.execute(filename, slob)
   end

  # Retrieving BLOBs and writing them to files
  db.each_hash("select filename, picture from album") do |r|
    slob = r['picture'].open
    File.open(r['filename'], "w") do |f|
      f.write r['picture'].read(r['picture'].size)
    end
    slob.close
  end

Methods

<<   atime   close   ctime   estbytes   extsz   extsz=   flags   flags=   lock   maxbytes   mtime   new   open   pos=   read   refcnt   rewind   sbspace   seek   size   stat   tell   truncate   unlock   write  

Classes and Modules

Class Informix::Slob::Stat

Constants

CLOB = INT2FIX(XID_CLOB)
BLOB = INT2FIX(XID_BLOB)
RDONLY = INT2FIX(LO_RDONLY)   Access modes
DIRTY_READ = INT2FIX(LO_DIRTY_READ)
WRONLY = INT2FIX(LO_WRONLY)
APPEND = INT2FIX(LO_APPEND)
RDWR = INT2FIX(LO_RDWR)
BUFFER = INT2FIX(LO_BUFFER)
NOBUFFER = INT2FIX(LO_NOBUFFER)
LOCKALL = INT2FIX(LO_LOCKALL)
LOCKRANGE = INT2FIX(LO_LOCKRANGE)
SEEK_SET = INT2FIX(LO_SEEK_SET)
SEEK_CUR = INT2FIX(LO_SEEK_CUR)
SEEK_END = INT2FIX(LO_SEEK_END)
LOG = INT2FIX(LO_LOG)   Creation-time flags
NOLOG = INT2FIX(LO_NOLOG)
KEEP_LASTACCESS_TIME = INT2FIX(LO_KEEP_LASTACCESS_TIME)
NOKEEP_LASTACCESS_TIME = INT2FIX(LO_NOKEEP_LASTACCESS_TIME)
CURRENT_END = INT2FIX(LO_CURRENT_END)   Ranges
MAX_END = INT2FIX(LO_MAX_END)
SHARED_MODE = INT2FIX(LO_SHARED_MODE)   Lock modes
EXCLUSIVE_MODE = INT2FIX(LO_EXCLUSIVE_MODE)

External Aliases

tell -> pos
new -> _new

Public Class methods

Creates a Slob object.

The Slob object is passed to the block if it‘s given, and automatically closes it when the block terminates, returning the value of the block.

type can be Slob::BLOB or Slob::CLOB

options can be a Hash object with the following possible keys:

  :sbspace     => Sbspace name
  :estbytes    => Estimated size, in bytes
  :extsz       => Allocation extent size
  :createflags => Create-time flags
  :openflags   => Access mode
  :maxbytes    => Maximum size
  :col_info    => Get the previous values from the column-level storage
                  characteristics for the specified database column

[Source]

     # File lib/informix.rb, line 314
314:     def self.new(dbname, query, options = nil)
315:       slob = _new(dbname, query, options)
316:       return slob if !block_given?
317:       begin
318:         yield slob
319:       ensure
320:         slob.close
321:       end
322:     end

Public Instance methods

Writes data to the Smart Large Object. If data is not a String object it will be converted to String using to_s.

Returns self.

[Source]

/*
 * call-seq:
 * slob << data   => slob
 *
 * Writes <i>data</i> to the Smart Large Object. If <i>data</i> is not a
 * String object it will be converted to String using <code>to_s</code>.
 *
 * Returns self.
 */
static VALUE
rb_slob_addstr(VALUE self, VALUE data)
{
        rb_slob_write(self, data);
        return self;
}

Returns the time of last access as a Time object.

[Source]

/*
 * call-seq:
 * slob.atime  => time
 *
 * Returns the time of last access as a Time object.
 */
static VALUE
rb_slob_atime(VALUE self)
{
        return slob_stat(self, slob_atime);
}

Closes the Smart Large Object and returns self.

[Source]

/*
 * call-seq:
 * slob.close  => slob
 *
 * Closes the Smart Large Object and returns __self__.
 */
static VALUE
rb_slob_close(VALUE self)
{
        slob_t *slob;

        Data_Get_Struct(self, slob_t, slob);
        if (slob->fd != -1) {
/*
 *              EXEC SQL begin declare section;
 */
#line 639 "informixc.ec"
#line 640 "informixc.ec"
  char *did;
/*
 *              EXEC SQL end   declare section;
 */
#line 641 "informixc.ec"


                did = slob->database_id;
/*
 *              EXEC SQL set connection :did;
 */
#line 644 "informixc.ec"
  {
#line 644 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 644 "informixc.ec"
  }
                if (SQLCODE < 0)
                        return self;

                ifx_lo_close(slob->fd);
                slob->fd = -1;
        }

        return self;
}

Returns the time of last change in status as a Time object.

[Source]

/*
 * call-seq:
 * stat.ctime  => time
 *
 * Returns the time of last change in status as a Time object.
 */
static VALUE
rb_slob_ctime(VALUE self)
{
        return slob_stat(self, slob_ctime);
}

Returns the estimated size of the SLOB

[Source]

/*
 * call-seq:
 * slob.estbytes  => fixnum or bignum
 *
 * Returns the estimated size of the SLOB
 */
static VALUE
rb_slob_estbytes(VALUE self)
{
        return slob_specget(self, slob_estbytes);
}

Returns the allocation extent size of the SLOB

[Source]

/*
 * call-seq:
 * slob.extsz  => fixnum
 *
 * Returns the allocation extent size of the SLOB
 */
static VALUE
rb_slob_extsz(VALUE self)
{
        return slob_specget(self, slob_extsz);
}

Sets the allocation extent size for the SLOB

[Source]

/*
 * call-seq:
 * slob.extsz = fixnum    => fixnum
 *
 * Sets the allocation extent size for the SLOB
 */
static VALUE
rb_slob_set_extsz(VALUE self, VALUE value)
{
        return slob_specset(self, slob_extsz, value);
}

Returns the create-time flags of the SLOB

[Source]

/*
 * call-seq:
 * slob.flags  => fixnum
 *
 * Returns the create-time flags of the SLOB
 */
static VALUE
rb_slob_flags(VALUE self)
{
        return slob_specget(self, slob_flags);
}

Sets the create-time flags of the SLOB

[Source]

/*
 * call-seq:
 * slob.flags = fixnum    => fixnum
 *
 * Sets the create-time flags of the SLOB
 */
static VALUE
rb_slob_set_flags(VALUE self, VALUE value)
{
        return slob_specset(self, slob_flags, value);
}

Locks range number of bytes, starting from offset bytes from whence, in mode mode.

Returns self.

Possible values:

  offset  =>  integer
  whence  =>  Slob::SEEK_SET, Slob::SEEK_CUR, Slob::SEEK_END
  range   =>  integer, Slob::CURRENT_END, Slob::MAX_END
  mode    =>  Slob::SHARED_MODE, Slob::EXCLUSIVE_MODE

[Source]

/*
 * call-seq:
 * slob.lock(offset, whence, range, mode)  =>  slob
 *
 * Locks _range_ number of bytes, starting from _offset_ bytes from
 * _whence_, in _mode_ mode.
 *
 * Returns _self_.
 *
 * Possible values:
 *
 *   offset  =>  integer
 *   whence  =>  Slob::SEEK_SET, Slob::SEEK_CUR, Slob::SEEK_END
 *   range   =>  integer, Slob::CURRENT_END, Slob::MAX_END
 *   mode    =>  Slob::SHARED_MODE, Slob::EXCLUSIVE_MODE
 */
static VALUE
rb_slob_lock(VALUE self, VALUE offset, VALUE whence, VALUE range, VALUE mode)
{
        slob_t *slob;
        mint ret;
        ifx_int8_t offset8, range8;
/*
 *      EXEC SQL begin declare section;
 */
#line 941 "informixc.ec"
#line 942 "informixc.ec"
  char *did;
/*
 *      EXEC SQL end   declare section;
 */
#line 943 "informixc.ec"


        Data_Get_Struct(self, slob_t, slob);

        if (slob->fd == -1)
                rb_raise(rb_eProgrammingError, "Open the Slob object first");

        did = slob->database_id;
/*
 *      EXEC SQL set connection :did;
 */
#line 951 "informixc.ec"
  {
#line 951 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 951 "informixc.ec"
  }
        if (SQLCODE < 0)
                raise_ifx_extended();

        NUM2INT8(offset, &offset8);
        NUM2INT8(range, &range8);
        ret = ifx_lo_lock(slob->fd, &offset8, FIX2INT(whence), &range8, FIX2INT(mode));
        if (ret < 0)
                raise_ifx_extended();

        return self;
}

Returns the maximum size of the SLOB

[Source]

/*
 * call-seq:
 * slob.maxbytes  => fixnum or bignum
 *
 * Returns the maximum size of the SLOB
 */
static VALUE
rb_slob_maxbytes(VALUE self)
{
        return slob_specget(self, slob_maxbytes);
}

Returns the time of last modification as a Time object.

[Source]

/*
 * call-seq:
 * stat.mtime  => time
 *
 * Returns the time of last modification as a Time object.
 */
static VALUE
rb_slob_mtime(VALUE self)
{
        return slob_stat(self, slob_mtime);
}

Opens the Smart Large Object in access mode.

Access modes:

Slob::RDONLY:Read only
Slob::DIRTY_READ:Read uncommitted data
Slob::WRONLY:Write only
Slob::APPEND:Append data to the end, if combined with RDWR or WRONLY; read only otherwise
Slob::RDWR:Read/Write
Slob::BUFFER:Use standard database server buffer pool
Slob::NOBUFFER:Use private buffer from the session pool of the database server
Slob::LOCKALL:Lock the entire Smart Large Object
Slob::LOCKRANGE:Lock a range of bytes

Returns self.

[Source]

/*
 * call-seq:
 * slob.open(access = Slob::RDONLY)  => slob
 *
 * Opens the Smart Large Object in <i>access</i> mode.
 *
 * Access modes:
 *
 * Slob::RDONLY::               Read only
 * Slob::DIRTY_READ::   Read uncommitted data
 * Slob::WRONLY::       Write only
 * Slob::APPEND::       Append data to the end, if combined with RDWR or WRONLY; read only otherwise
 * Slob::RDWR::         Read/Write
 * Slob::BUFFER::       Use standard database server buffer pool
 * Slob::NOBUFFER::     Use private buffer from the session pool of the database server
 * Slob::LOCKALL::              Lock the entire Smart Large Object
 * Slob::LOCKRANGE::    Lock a range of bytes
 *
 * Returns __self__.
 */
static VALUE
rb_slob_open(int argc, VALUE *argv, VALUE self)
{
        VALUE access;
        slob_t *slob;
        mint error;
/*
 *      EXEC SQL begin declare section;
 */
#line 602 "informixc.ec"
#line 603 "informixc.ec"
  char *did;
/*
 *      EXEC SQL end   declare section;
 */
#line 604 "informixc.ec"


        Data_Get_Struct(self, slob_t, slob);

        if (slob->fd != -1) /* Already open */
                return self;

        did = slob->database_id;
/*
 *      EXEC SQL set connection :did;
 */
#line 612 "informixc.ec"
  {
#line 612 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 612 "informixc.ec"
  }
        if (SQLCODE < 0)
                raise_ifx_extended();

        rb_scan_args(argc, argv, "01", &access);

        slob->fd = ifx_lo_open(&slob->lo, NIL_P(access)? LO_RDONLY: FIX2INT(access), &error);

        if (slob->fd == -1)
                raise_ifx_extended();

        return self;
}

Seeks to the given position (in bytes) in slob.

[Source]

/*
 * call-seq:
 * slob.pos = integer    => integer
 *
 * Seeks to the given position (in bytes) in _slob_.
 */
static VALUE
rb_slob_set_pos(VALUE self, VALUE pos)
{
        return rb_slob_seek(self, pos, LO_SEEK_SET);
}

Reads at most nbytes bytes from the Smart Large Object.

Returns the bytes read as a String object.

[Source]

/*
 * call-seq:
 * slob.read(nbytes)  => string
 *
 * Reads at most <i>nbytes</i> bytes from the Smart Large Object.
 *
 * Returns the bytes read as a String object.
 */
static VALUE
rb_slob_read(VALUE self, VALUE nbytes)
{
        slob_t *slob;
        mint error, ret;
        char *buffer;
        long c_nbytes;
        VALUE str;
/*
 *      EXEC SQL begin declare section;
 */
#line 671 "informixc.ec"
#line 672 "informixc.ec"
  char *did;
/*
 *      EXEC SQL end   declare section;
 */
#line 673 "informixc.ec"



        Data_Get_Struct(self, slob_t, slob);

        if (slob->fd == -1)
                rb_raise(rb_eProgrammingError, "Open the Slob object before reading");

        did = slob->database_id;
/*
 *      EXEC SQL set connection :did;
 */
#line 682 "informixc.ec"
  {
#line 682 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 682 "informixc.ec"
  }
        if (SQLCODE < 0)
                raise_ifx_extended();

        c_nbytes = FIX2LONG(nbytes);
        buffer = ALLOC_N(char, c_nbytes);
        ret = ifx_lo_read(slob->fd, buffer, c_nbytes, &error);

        if (ret == -1) {
                xfree(buffer);
                raise_ifx_extended();
        }

        str = rb_str_new(buffer, ret);
        xfree(buffer);

        return str;
}

Returns the number of references

[Source]

/*
 * call-seq:
 * stat.refcnt  => fixnum
 *
 * Returns the number of references
 */
static VALUE
rb_slob_refcnt(VALUE self)
{
        return slob_stat(self, slob_refcnt);
}

Moves the cursor position to the start of the Smart Large Object.

[Source]

/*
 * call-seq:
 * slob.rewind  => fixnum
 *
 * Moves the cursor position to the start of the Smart Large Object.
 */
static VALUE
rb_slob_rewind(VALUE self)
{
        return rb_slob_seek(self, INT2FIX(0), LO_SEEK_SET);
}

Returns the name of the sbspace where the SLOB is stored

[Source]

/*
 * call-seq:
 * slob.sbspace  => string
 *
 * Returns the name of the sbspace where the SLOB is stored
 */
static VALUE
rb_slob_sbspace(VALUE self)
{
        return slob_specget(self, slob_sbspace);
}

Sets the file position for the next read or write operation on the open Smart Large Object.

offset offset from the starting seek position whence identifies the starting seek position

Values for whence:

Slob::SEEK_SET:The start of the Smart Large Object
Slob::SEEK_CUR:The current seek position in the Smart Large Object
Slob::SEEK_END:The end of the Smart Large Object

Returns the new position.

[Source]

/*
 * call-seq:
 * slob.seek(offset, whence)  => fixnum or bignum
 *
 * Sets the file position for the next read or write
 * operation on the open Smart Large Object.
 *
 *
 * <i>offset</i>        offset from the starting seek position
 * <i>whence</i>        identifies the starting seek position
 *
 * Values for <i>whence</i>:
 *
 * Slob::SEEK_SET::     The start of the Smart Large Object
 * Slob::SEEK_CUR::     The current seek position in the Smart Large Object
 * Slob::SEEK_END::     The end of the Smart Large Object
 *
 * Returns the new position.
 */
static VALUE
rb_slob_seek(VALUE self, VALUE offset, VALUE whence)
{
        slob_t *slob;
        mint ret;
        VALUE seek_pos;
        ifx_int8_t offset8, seek_pos8;
/*
 *      EXEC SQL begin declare section;
 */
#line 786 "informixc.ec"
#line 787 "informixc.ec"
  char *did;
/*
 *      EXEC SQL end   declare section;
 */
#line 788 "informixc.ec"


        Data_Get_Struct(self, slob_t, slob);

        if (slob->fd == -1)
                rb_raise(rb_eProgrammingError, "Open the Slob object first");

        did = slob->database_id;
/*
 *      EXEC SQL set connection :did;
 */
#line 796 "informixc.ec"
  {
#line 796 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 796 "informixc.ec"
  }
        if (SQLCODE < 0)
                raise_ifx_extended();

        NUM2INT8(offset, &offset8);
        ret = ifx_lo_seek(slob->fd, &offset8, FIX2INT(whence), &seek_pos8);
        if (ret < 0)
                raise_ifx_extended();

        INT82NUM(&seek_pos8, seek_pos);

        return seek_pos;
}

Returns the size in bytes

[Source]

/*
 * call-seq:
 * stat.size  => fixnum or bignum
 *
 * Returns the size in bytes
 */
static VALUE
rb_slob_size(VALUE self)
{
        return slob_stat(self, slob_size);
}

Creates and returns an Slob::Stat object with status information for slob.

[Source]

/*
 * call-seq:
 * slob.stat  => stat
 *
 * Creates and returns an Slob::Stat object with status information for _slob_.
 */
static VALUE
rb_slob_stat(VALUE self)
{
        return rb_class_new_instance(1, &self, rb_cSlobStat);
}

Returns the current file or seek position for an open Smart Large Object

[Source]

/*
 * call-seq:
 * slob.tell  => integer
 * slob.pos   => integer
 *
 * Returns the current file or seek position for an open Smart Large Object
 */
static VALUE
rb_slob_tell(VALUE self)
{
        slob_t *slob;
        mint ret;
        VALUE seek_pos;
        ifx_int8_t seek_pos8;
/*
 *      EXEC SQL begin declare section;
 */
#line 848 "informixc.ec"
#line 849 "informixc.ec"
  char *did;
/*
 *      EXEC SQL end   declare section;
 */
#line 850 "informixc.ec"


        Data_Get_Struct(self, slob_t, slob);

        if (slob->fd == -1)
                rb_raise(rb_eProgrammingError, "Open the Slob object first");

        did = slob->database_id;
/*
 *      EXEC SQL set connection :did;
 */
#line 858 "informixc.ec"
  {
#line 858 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 858 "informixc.ec"
  }
        if (SQLCODE < 0)
                raise_ifx_extended();

        ret = ifx_lo_tell(slob->fd, &seek_pos8);
        if (ret < 0)
                raise_ifx_extended();

        INT82NUM(&seek_pos8, seek_pos);

        return seek_pos;
}

Truncates a Smart Large Object at a specified byte position.

Returns self.

[Source]

/*
 * call-seq:
 * slob.truncate(offset)  => slob
 *
 * Truncates a Smart Large Object at a specified byte position.
 *
 * Returns __self__.
 */
static VALUE
rb_slob_truncate(VALUE self, VALUE offset)
{
        slob_t *slob;
        mint ret;
        ifx_int8_t offset8;
/*
 *      EXEC SQL begin declare section;
 */
#line 885 "informixc.ec"
#line 886 "informixc.ec"
  char *did;
/*
 *      EXEC SQL end   declare section;
 */
#line 887 "informixc.ec"


        Data_Get_Struct(self, slob_t, slob);

        if (slob->fd == -1)
                rb_raise(rb_eProgrammingError, "Open the Slob object first");

        did = slob->database_id;
/*
 *      EXEC SQL set connection :did;
 */
#line 895 "informixc.ec"
  {
#line 895 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 895 "informixc.ec"
  }
        if (SQLCODE < 0)
                raise_ifx_extended();

        NUM2INT8(offset, &offset8);
        ret = ifx_lo_truncate(slob->fd, &offset8);
        if (ret < 0)
                raise_ifx_extended();

        return self;
}

Unlocks range number of bytes, starting from offset bytes from whence.

Returns self.

Possible values:

  offset  =>  integer
  whence  =>  Slob::SEEK_SET, Slob::SEEK_CUR, Slob::SEEK_END
  range   =>  integer

[Source]

/*
 * call-seq:
 * slob.unlock(offset, whence, range)  =>  slob
 *
 * Unlocks _range_ number of bytes, starting from _offset_ bytes from
 * _whence_.
 *
 * Returns _self_.
 *
 * Possible values:
 *
 *   offset  =>  integer
 *   whence  =>  Slob::SEEK_SET, Slob::SEEK_CUR, Slob::SEEK_END
 *   range   =>  integer
 */
static VALUE
rb_slob_unlock(VALUE self, VALUE offset, VALUE whence, VALUE range)
{
        slob_t *slob;
        mint ret;
        ifx_int8_t offset8, range8;
/*
 *      EXEC SQL begin declare section;
 */
#line 985 "informixc.ec"
#line 986 "informixc.ec"
  char *did;
/*
 *      EXEC SQL end   declare section;
 */
#line 987 "informixc.ec"


        Data_Get_Struct(self, slob_t, slob);

        if (slob->fd == -1)
                rb_raise(rb_eProgrammingError, "Open the Slob object first");

        did = slob->database_id;
/*
 *      EXEC SQL set connection :did;
 */
#line 995 "informixc.ec"
  {
#line 995 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 995 "informixc.ec"
  }
        if (SQLCODE < 0)
                raise_ifx_extended();

        NUM2INT8(offset, &offset8);
        NUM2INT8(range, &range8);
        ret = ifx_lo_unlock(slob->fd, &offset8, FIX2INT(whence), &range8);
        if (ret < 0)
                raise_ifx_extended();

        return self;
}

Writes data to the Smart Large Object. If data is not a String object it will be converted to String using to_s.

Returns the number of bytes written.

[Source]

/*
 * call-seq:
 * slob.write(data)  => fixnum or bignum
 *
 * Writes <i>data</i> to the Smart Large Object. If <i>data</i> is not a
 * String object it will be converted to String using <code>to_s</code>.
 *
 * Returns the number of bytes written.
 */
static VALUE
rb_slob_write(VALUE self, VALUE data)
{
        slob_t *slob;
        mint error, ret;
        char *buffer;
        long nbytes;
        VALUE str;
/*
 *      EXEC SQL begin declare section;
 */
#line 718 "informixc.ec"
#line 719 "informixc.ec"
  char *did;
/*
 *      EXEC SQL end   declare section;
 */
#line 720 "informixc.ec"


        Data_Get_Struct(self, slob_t, slob);

        if (slob->fd == -1)
                rb_raise(rb_eProgrammingError, "Open the Slob object before writing");

        did = slob->database_id;
/*
 *      EXEC SQL set connection :did;
 */
#line 728 "informixc.ec"
  {
#line 728 "informixc.ec"
  sqli_connect_set(0, did, 0);
#line 728 "informixc.ec"
  }
        if (SQLCODE < 0)
                raise_ifx_extended();

        str = rb_obj_as_string(data);
        buffer = RSTRING_PTR(str);
        nbytes = RSTRING_LEN(str);

        ret = ifx_lo_write(slob->fd, buffer, nbytes, &error);

        if (ret == -1)
                raise_ifx_extended();

        return LONG2NUM(ret);
}

[Validate]