Class: Oinky::DB

Inherits:
Object
  • Object
show all
Defined in:
lib/oinky.rb

Defined Under Namespace

Classes: Savepoint

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ptr = nil, s = nil) ⇒ DB

Returns a new instance of DB.



1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
# File 'lib/oinky.rb', line 1131

def initialize(ptr = nil, s = nil)
  if ptr
    unless ptr.is_a? FFI::Pointer
      raise OinkyException.new("Can't initialize oinky DB with given value of type: #{ptr.class}")
    end
    @db_ptr = ptr
  else
    # Create an empty DB
    @db_ptr = Internal.oinky_db_new
  end
  # We must preserve a reference to the heap-string object, at least until
  # we destroy the DB instance.
  @source_buffer = s

  # Make an instance-local copy of the global default.  Changing the global
  # after this point will not alter the behavior of cursors on this instance.
  @implicit_cursor_cleanup = Oinky.implicit_cursor_cleanup

  ObjectSpace.define_finalizer( self, self.class.finalize(@db_ptr) )
end

Instance Attribute Details

#implicit_cursor_cleanupObject

Returns the value of attribute implicit_cursor_cleanup.



1128
1129
1130
# File 'lib/oinky.rb', line 1128

def implicit_cursor_cleanup
  @implicit_cursor_cleanup
end

#source_bufferObject (readonly)

Returns the value of attribute source_buffer.



1129
1130
1131
# File 'lib/oinky.rb', line 1129

def source_buffer
  @source_buffer
end

Class Method Details

.finalize(ptr) ⇒ Object



1152
1153
1154
# File 'lib/oinky.rb', line 1152

def self.finalize(ptr)
  proc { Internal.oinky_db_free(ptr) }
end

.mount(s) ⇒ Object



1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
# File 'lib/oinky.rb', line 1162

def self.mount(s)
  if s.is_a? String
    s = NativeMallocBuffer.new(s)
  end
  unless s.is_a? NativeBuffer
    raise OinkyException.new("Oinky can only mount a String or a NativeBuffer") 
  end
  ptr = FFI::MemoryPointer.new :pointer
  Internal.wrap_oinky(Internal.oinky_db_mount(ptr, s.length, s.ptr))
  return DB.new(ptr.read_pointer, s)
end

Instance Method Details

#[](tblname) ⇒ Object



1268
1269
1270
# File 'lib/oinky.rb', line 1268

def [](tblname)
  return tables[tblname]
end

#alter_table(tblname) ⇒ Object



1277
1278
1279
1280
1281
# File 'lib/oinky.rb', line 1277

def alter_table(tblname)
  self.atomic {
    yield self[tblname]
  }
end

#atomicObject

Usage:

db.atomic

db.create_table 'foo'
db.create_table 'bar'
...



1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
# File 'lib/oinky.rb', line 1213

def atomic
  sp = self.create_savepoint
  begin
    yield
    sp = nil
  ensure
    self.savepoint_rollback(sp) if sp
  end
  self
end

#cloneObject

Deep copy is this simple



1157
1158
1159
1160
# File 'lib/oinky.rb', line 1157

def clone
  str = self.serialize
  self.class.mount(str)
end

#create_savepointObject



1181
1182
1183
1184
1185
# File 'lib/oinky.rb', line 1181

def create_savepoint
  sp = FFI::MemoryPointer.new(:uint64)
  Internal.wrap_oinky(Internal.oinky_db_create_savepoint(@db_ptr, sp))
  return Savepoint.new(self, sp.read_uint64)
end

#create_table(name) ⇒ Object



1235
1236
1237
1238
1239
1240
1241
1242
1243
# File 'lib/oinky.rb', line 1235

def create_table(name)
  handle = FFI::MemoryPointer.new :pointer
  Internal.wrap_oinky(Internal.oinky_db_create_table(@db_ptr, name.to_s, handle))
  tbl = Table.new(self, handle.read_pointer)
  if block_given? 
    yield tbl
  end
  self
end

#drop_table(name) ⇒ Object



1245
1246
1247
1248
1249
1250
# File 'lib/oinky.rb', line 1245

def drop_table(name)
  name = name.name if name.is_a? Table
  dbs = Internal::DB_string.make(name.to_s)
  Internal.wrap_oinky(Internal.oinky_db_drop_table(@db_ptr, dbs))
  self
end

#modified_since?(sp) ⇒ Boolean

This is intended to support a write cache.

Determines whether the database has been modified since the given savepoint. This can generate some false positives in the case where the only relevant changes were rolled back to a former state, but this transient ambiguity can be eliminated by creating a new savepoint to test against, after each writeback.

Returns:

  • (Boolean)


1202
1203
1204
# File 'lib/oinky.rb', line 1202

def modified_since?(sp)
  Internal.oinky_db_is_modified_since(@db_ptr, sp.value) != 0
end

#savepoint_rollback(sp) ⇒ Object



1187
1188
1189
1190
1191
1192
1193
# File 'lib/oinky.rb', line 1187

def savepoint_rollback(sp)
  unless sp.is_a?(Savepoint) and (sp.db == self)
    raise OinkyException.new("ArgumentError.  SP does not match this DB instance")
  end
  Internal.wrap_oinky(Internal.oinky_db_savepoint_rollback(@db_ptr, sp.value))
  self
end

#serializeObject



1228
1229
1230
1231
1232
1233
# File 'lib/oinky.rb', line 1228

def serialize
  size = Internal.prepare_pack(@db_ptr)
  str = NativeMallocBuffer.new(size)
  Internal.wrap_oinky(Internal.oinky_db_complete_pack(@db_ptr, str.length, str.ptr))
  str
end

#table_countObject



1224
1225
1226
# File 'lib/oinky.rb', line 1224

def table_count
  Internal.oinky_table_count(@db_ptr)
end

#tablesObject



1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
# File 'lib/oinky.rb', line 1252

def tables
  sz = self.table_count()
  handles = FFI::MemoryPointer.new(:pointer, sz)
  rsz = Internal.oinky_db_get_table_handles(@db_ptr, handles, sz)
  unless rsz == sz
    raise OinkyException.new("Oinky: Unknown interface error - tablecount") 
  end
  
  map = ExHash.new
  (0..sz-1).each{|i| 
    th = Table.new(self, handles[i].read_pointer)
    map[th.name] = th
  }
  map.freeze
end

#with_table(tblname) {|| ... } ⇒ Object

Yields:

  • ()


1272
1273
1274
1275
# File 'lib/oinky.rb', line 1272

def with_table(tblname)
  yield self[tblname]
  return self
end