Beispiel #1
0
//
// AddField adds a fully created field directly rather than by some of its
// attributes, as the other "Field" methods do.
// The same *ODocument is returned to allow call chaining.
//
func (doc *ODocument) AddField(name string, field *OField) *ODocument {
	ogl.Debugf("ODocument.AddField name== %v\n", name)   // DEBUG
	ogl.Debugf("ODocument.AddField field== %v\n", field) // DEBUG
	doc.Fields[name] = field
	doc.entryOrder = append(doc.entryOrder, name)
	return doc
}
Beispiel #2
0
func doExec(dbc *obinary.DBClient, cmd string, args []driver.Value) (driver.Result, error) {
	strargs := valuesToStrings(args)

	retval, docs, err := obinary.SQLCommand(dbc, cmd, strargs...)
	ogl.Debugf("exec1: %T: %v\n", retval, retval)
	if err != nil {
		return ogonoriResult{-1, -1}, err
	}

	if docs == nil {
		ogl.Debugln("exec2")
		nrows, err := strconv.ParseInt(retval, 10, 64)
		if err != nil {
			ogl.Debugf("exec3: %T: %v\n", err, err)
			nrows = -1
		}
		return ogonoriResult{nrows, -1}, err
	}

	lastdoc := docs[len(docs)-1]
	// sepIdx := strings.Index(lastDoc.RID, ":")
	// if sepIdx < 0 {
	// 	return ogonoriResult{len64(docs), -1}, fmt.Errorf("RID of returned doc not of expected format: %v", lastDoc.RID)
	// }
	// lastId, err := strconv.ParseInt(lastDoc.RID[sepIdx+1:], 10, 64)
	// if err != nil {
	// 	return ogonoriResult{len64(docs), -1}, fmt.Errorf("Couldn't parse ID from doc RID: %v: %v", lastDoc.RID, err)
	// }
	return ogonoriResult{len64(docs), lastdoc.RID.ClusterPos}, err
}
Beispiel #3
0
//
// serializeDocument writes the classname and the serialized record
// (header and data sections) of the ODocument to the obuf.WriteBuf.
//
// Because this method writes the classname but NOT the serialization
// version, this method is safe for recursive calls for EMBEDDED types.
//
func (serde ORecordSerializerV0) serializeDocument(wbuf *obuf.WriteBuf, doc *oschema.ODocument) error {
	err := varint.WriteString(wbuf, doc.Classname)
	if err != nil {
		return oerror.NewTrace(err)
	}
	ogl.Debugf("serdebuf A: %v\n", wbuf.Bytes()) // DEBUG
	ogl.Debugf("doc A: %v\n", doc)               // DEBUG

	return serde.writeSerializedRecord(wbuf, doc)
}
Beispiel #4
0
//
// readSingleDocument is called by readSingleRecord when it has determined that the server
// has sent a docuemnt ('d'), not flat data ('f') or raw bytes ('b').
// It should be called *after* the single byte below on the first line has been already
// read and determined to be 'd'.  The rest the stream (NOT including the EOT byte) will
// be read.  The serialized document will be turned into an oschema.ODocument.
//
//     Writing byte (1 byte): 100 [OChannelBinaryServer]   <- 'd'=document ('f'=flat data, 'b'=raw bytes)
//     Writing short (2 bytes): 11 [OChannelBinaryServer]  <- cluster-id  (RID part 1)
//     Writing long (8 bytes): 0 [OChannelBinaryServer]    <- cluster-pos (RID part 2)
//     Writing int (4 bytes): 1 [OChannelBinaryServer]     <- version
//     Writing bytes (4+26=30 bytes): [0, 14, 80, 97, 116, ... , 110, 107, 1] <- serialized record
//
func readSingleDocument(dbc *DBClient) (*oschema.ODocument, error) {
	clusterId, err := rw.ReadShort(dbc.conx)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	clusterPos, err := rw.ReadLong(dbc.conx)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	recVersion, err := rw.ReadInt(dbc.conx)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	recBytes, err := rw.ReadBytes(dbc.conx)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}
	rid := oschema.ORID{ClusterID: clusterId, ClusterPos: clusterPos}
	doc, err := createDocumentFromBytes(rid, recVersion, recBytes, dbc)
	ogl.Debugf("::single record doc:::::: %v\n", doc)
	return doc, err
}
Beispiel #5
0
func readEmbeddedLinkBag(rdr io.Reader) (*oschema.OLinkBag, error) {
	bs := make([]byte, 1)
	n, err := rdr.Read(bs)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}
	if n != 1 {
		return nil, oerror.IncorrectNetworkRead{Expected: 1, Actual: n}
	}

	if bs[0] == 1 {
		uuid, err := readLinkBagUUID(rdr)
		if err != nil {
			return nil, oerror.NewTrace(err)
		}
		ogl.Debugf("read uuid %v - now what?\n", uuid)

	} else {
		// if b wasn't zero, then there's no UUID and b was the first byte of an int32
		// specifying the size of the embedded bag collection
		// TODO: I'm not sure this is the right thing - the OrientDB is pretty hazy on how this works
		switch rdr.(type) {
		case *bytes.Buffer:
			buf := rdr.(*bytes.Buffer)
			buf.UnreadByte()

		case *obuf.ReadBuf:
			buf := rdr.(*obuf.ReadBuf)
			buf.UnreadByte()

		default:
			panic("Unknown type of buffer in binserde#readEmbeddedLinkBag")
		}
	}

	bagsz, err := rw.ReadInt(rdr)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}
	links := make([]*oschema.OLink, bagsz)

	for i := int32(0); i < bagsz; i++ {
		clusterID, err := rw.ReadShort(rdr)
		if err != nil {
			return nil, oerror.NewTrace(err)
		}

		clusterPos, err := rw.ReadLong(rdr)
		if err != nil {
			return nil, oerror.NewTrace(err)
		}

		orid := oschema.ORID{ClusterID: clusterID, ClusterPos: clusterPos}
		links[i] = &oschema.OLink{RID: orid}
	}

	return oschema.NewOLinkBag(links), nil
}
Beispiel #6
0
//
// loadSchema loads record #0:1 for the current database, caching the
// SchemaVersion, GlobalProperties and Classes info in the current ODatabase
// object (dbc.currDB).
//
func loadSchema(dbc *DBClient, schemaRID oschema.ORID) error {
	docs, err := FetchRecordByRID(dbc, schemaRID, "*:-1 index:0") // fetchPlan used by the Java client
	if err != nil {
		return err
	}
	// TODO: this idea of returning multiple docs has to be wrong
	if len(docs) != 1 {
		return fmt.Errorf("Load Record %s should only return one record. Returned: %d", schemaRID, len(docs))
	}

	/* ---[ schemaVersion ]--- */
	dbc.currDB.SchemaVersion = docs[0].GetField("schemaVersion").Value.(int32)

	/* ---[ globalProperties ]--- */
	globalPropsFld := docs[0].GetField("globalProperties")

	var globalProperty oschema.OGlobalProperty
	for _, pfield := range globalPropsFld.Value.([]interface{}) {
		pdoc := pfield.(*oschema.ODocument)
		globalProperty = oschema.NewGlobalPropertyFromDocument(pdoc)
		dbc.currDB.GlobalProperties[int(globalProperty.Id)] = globalProperty
	}

	ogl.Debugln("=======================================")
	ogl.Debugln("=======================================")
	ogl.Debugf("dbc.currDB.SchemaVersion: %v\n", dbc.currDB.SchemaVersion)
	ogl.Debugf("len(dbc.currDB.GlobalProperties): %v\n", len(dbc.currDB.GlobalProperties))
	ogl.Debugf("dbc.currDB.GlobalProperties: %v\n", dbc.currDB.GlobalProperties)
	ogl.Debugln("=======================================")
	ogl.Debugln("=======================================")

	/* ---[ classes ]--- */
	var oclass *oschema.OClass
	classesFld := docs[0].GetField("classes")
	for _, cfield := range classesFld.Value.([]interface{}) {
		cdoc := cfield.(*oschema.ODocument)
		oclass = oschema.NewOClassFromDocument(cdoc)
		dbc.currDB.Classes[oclass.Name] = oclass
	}

	return nil
}
Beispiel #7
0
func doQuery(dbc *obinary.DBClient, query string, args []driver.Value) (driver.Rows, error) {
	var (
		docs []*oschema.ODocument
		err  error
	)

	strargs := valuesToStrings(args)
	fetchPlan := ""
	docs, err = obinary.SQLQuery(dbc, query, fetchPlan, strargs...)
	ogl.Debugf("oC.Q:  %v\n", docs)
	return NewRows(docs), err
}
Beispiel #8
0
func valuesToStrings(args []driver.Value) []string {
	strargs := make([]string, len(args))
	for i, valarg := range args {
		ogl.Debugf("valarg: %T: %v; isValue=%v\n", valarg, valarg, driver.IsValue(valarg)) // DEBUG
		switch valarg.(type) {
		case string:
			strargs[i] = valarg.(string)
		case int64:
			strargs[i] = strconv.FormatInt(valarg.(int64), 10)
		case float64:
			strargs[i] = strconv.FormatFloat(valarg.(float64), 'f', -1, 10)
		case bool:
			strargs[i] = strconv.FormatBool(valarg.(bool))
		case []byte:
			strargs[i] = string(valarg.([]byte))
		case time.Time:
			strargs[i] = valarg.(time.Time).String() // TODO: this is probably not the format we want -> fix it later
		default:
			_, file, line, _ := runtime.Caller(0)
			ogl.Warn(fmt.Sprintf("Unexpected type in ogonoriConn#Exec: %T. (%s:%d)", valarg, file, line))
		}
	}
	return strargs
}
Beispiel #9
0
//
// Implements database/sql/driver.ValueConverter interface
// TODO: haven't detected when this is called yet
//
func (doc *ODocument) ConvertValue(v interface{}) (driver.Value, error) {
	ogl.Debugf("** ODocument.ConvertValue: %T: %v\n", v, v)

	return []byte(`{"a": 1}`), nil // FIXME: bogus
}
Beispiel #10
0
// TODO: what datatypes can the params be? => right now allowing only string
func serializeSimpleSQLParams(dbc *DBClient, params []string) ([]byte, error) {
	// Java client uses Map<Object, Object>
	// Entry: {0=Honda, 1=Accord}, so positional params start with 0
	// OSQLQuery#serializeQueryParameters(Map<O,O> params)
	//   creates an ODocument
	//   params.put("params", convertToRIDsIfPossible(params))
	//   the convertToRIDsIfPossible is the one that handles Set vs. Map vs. ... vs. else -> primitive which is what simple strings are
	//  then the serialization is done via ODocument#toStream -> ORecordSerializer#toStream
	//    serializeClass(document)  => returns null
	//    only field name in the document is "params"
	//    when the embedded map comes in {0=Honda, 1=Accord}, it calls writeSingleValue

	if len(params) == 0 {
		return nil, nil
	}

	doc := oschema.NewDocument("")

	// the params must be serialized as an embedded map of form:
	// {params => {0=>paramVal1, 1=>paramVal2}}
	// which in ogonori is a Field with:
	//   Field.Name = params
	//   Field.Value = {0=>paramVal1, 1=>paramVal2}} (map[string]interface{})

	paramsMap := oschema.NewEmbeddedMapWithCapacity(2)
	for i, pval := range params {
		paramsMap.Put(strconv.Itoa(i), pval, oschema.STRING)
	}
	doc.FieldWithType("params", paramsMap, oschema.EMBEDDEDMAP)

	ogl.Debugf("DOC XX: %v\n", doc)

	// buf := new(bytes.Buffer)
	// err := buf.WriteByte(dbc.serializationVersion)
	// if err != nil {
	// 	return nil, oerror.NewTrace(err)
	// }
	serde := dbc.RecordSerDes[int(dbc.serializationVersion)]
	serializedBytes, err := serde.Serialize(dbc, doc)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	ogl.Debugf("serialized params: %v\n", serializedBytes)

	return serializedBytes, nil

	// ------------------------
	// final byte type = network.readByte();
	//  switch (type) {
	//  case 'n':
	//    result = null;
	//    break;

	//  case 'r':
	//    result = OChannelBinaryProtocol.readIdentifiable(network);
	//    if (result instanceof ORecord)
	//      database.getLocalCache().updateRecord((ORecord) result);
	//    break;

	//  case 'l':
	//    final int tot = network.readInt();
	//    final Collection<OIdentifiable> list = new ArrayList<OIdentifiable>(tot);
	//    for (int i = 0; i < tot; ++i) {
	//      final OIdentifiable resultItem = OChannelBinaryProtocol.readIdentifiable(network);
	//      if (resultItem instanceof ORecord)
	//        database.getLocalCache().updateRecord((ORecord) resultItem);
	//      list.add(resultItem);
	//    }
	//    result = list;
	//    break;

	//  case 'a':  // 'a' means "serialized result"
	//    final String value = new String(network.readBytes());
	//    result = ORecordSerializerStringAbstract.fieldTypeFromStream(null, ORecordSerializerStringAbstract.getType(value),
	//        value);
	//    break;

	//  default:
	//    OLogManager.instance().warn(this, "Received unexpected result from query: %d", type);
	//  }

	// return nil, nil
}
Beispiel #11
0
//
// SQLCommand executes SQL commands that are not queries. Any SQL statement
// that does not being with "SELECT" should be sent here.  All SELECT
// statements should go to the SQLQuery function.
//
// Commands can be optionally paramterized using ?, such as:
//
//     INSERT INTO Foo VALUES(a, b, c) (?, ?, ?)
//
// The values for the placeholders (currently) must be provided as strings.
//
// Constraints (for now):
// 1. cmds with only simple positional parameters allowed
// 2. cmds with lists of parameters ("complex") NOT allowed
// 3. parameter types allowed: string only for now
//
// SQL commands in OrientDB tend to return one of two types - a string return value or
// one or more documents. The meaning are specific to the type of query.
//
// ----------------
// For example:
// ----------------
//  for a DELETE statement:
//    retval = number of rows deleted (as a string)
//    docs = empty list
//
//  for an INSERT statement:
//    n = ?
//    docs = ?
//
//  for an CREATE CLASS statement:
//    retval = cluster id of the class (TODO: or it might be number of classes in cluster)
//    docs = empty list
//
//  for an DROP CLASS statement:
//    retval = "true" if successful, "" if class didn't exist (technically it returns null)
//    docs = empty list
//
func SQLCommand(dbc *DBClient, sql string, params ...string) (retval string, docs []*oschema.ODocument, err error) {
	dbc.buf.Reset()

	err = writeCommandAndSessionId(dbc, REQUEST_COMMAND)
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	mode := byte('s') // synchronous only supported for now
	err = rw.WriteByte(dbc.buf, mode)
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	// need a separate buffer to write the command-payload to, so
	// we can calculate its length before writing it to main dbc.buf
	commandBuf := new(bytes.Buffer)

	// "classname" (command-type, really) and the sql command
	err = rw.WriteStrings(commandBuf, "c", sql) // c for command(non-idempotent)
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	// SQLCommand
	//  (text:string)
	//  (has-simple-parameters:boolean)
	//  (simple-paremeters:bytes[])  -> serialized Map (EMBEDDEDMAP??)
	//  (has-complex-parameters:boolean)
	//  (complex-parameters:bytes[])  -> serialized Map (EMBEDDEDMAP??)

	serializedParams, err := serializeSimpleSQLParams(dbc, params)
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	// has-simple-parameters
	err = rw.WriteBool(commandBuf, serializedParams != nil)
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	if serializedParams != nil {
		rw.WriteBytes(commandBuf, serializedParams)
	}

	// FIXME: no complex parameters yet since I don't understand what they are
	// has-complex-paramters => HARDCODING FALSE FOR NOW
	err = rw.WriteBool(commandBuf, false)
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	serializedCmd := commandBuf.Bytes()

	// command-payload-length and command-payload
	err = rw.WriteBytes(dbc.buf, serializedCmd)
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	// send to the OrientDB server
	_, err = dbc.conx.Write(dbc.buf.Bytes())
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	/* ---[ Read Response ]--- */

	err = readStatusCodeAndSessionId(dbc)
	if err != nil {
		return "", nil, oerror.NewTrace(err)
	}

	// for synchronous commands the remaining content is an array of form:
	// [(synch-result-type:byte)[(synch-result-content:?)]]+
	// so the final value will by byte(0) to indicate the end of the array
	// and we must use a loop here

	for {
		resType, err := rw.ReadByte(dbc.conx)
		if err != nil {
			return "", nil, oerror.NewTrace(err)
		}
		// This implementation assumes that SQLCommand can never have "supplementary records"
		// from an extended fetchPlan
		if resType == byte(0) {
			break
		}

		resultType := rune(resType)
		ogl.Debugf("resultType for SQLCommand: %v (%s)\n", resultType, string(rune(resultType)))

		if resultType == 'n' { // null result
			// do nothing - anything need to be done here?

		} else if resultType == 'r' { // single record
			doc, err := readSingleRecord(dbc)
			if err != nil {
				return "", nil, oerror.NewTrace(err)
			}

			ogl.Debugf("r>doc = %v\n", doc) // DEBUG
			if doc != nil {
				docs = make([]*oschema.ODocument, 1)
				docs[0] = doc
			}

		} else if resultType == 'l' { // collection of records
			ogl.Debugln("... resultType l")
			collectionDocs, err := readResultSet(dbc)
			if err != nil {
				return "", nil, oerror.NewTrace(err)
			}

			if docs == nil {
				docs = collectionDocs
			} else {
				docs = append(docs, collectionDocs...)
			}

		} else if resultType == 'a' { // serialized type
			serializedRec, err := rw.ReadBytes(dbc.conx)
			if err != nil {
				return "", nil, oerror.NewTrace(err)
			}
			// TODO: for now I'm going to assume that this always just returns a string
			//       need a use case that violates this assumption
			retval = string(serializedRec)
			if err != nil {
				return "", nil, oerror.NewTrace(err)
			}

		} else {
			_, file, line, _ := runtime.Caller(0)
			// TODO: I've not yet tested this route of code -> how do so?
			ogl.Warnf(">> Got back resultType %v (%v): Not yet supported: line:%d; file:%s\n",
				resultType, string(rune(resultType)), line, file)
			// TODO: returning here is NOT the correct long-term behavior
			return "", nil, fmt.Errorf("Got back resultType %v (%v): Not yet supported: line:%d; file:%s\n",
				resultType, string(rune(resultType)), line, file)
		}
	}

	return retval, docs, err
}
Beispiel #12
0
//
// FetchRecordByRID takes an ORID and reads that record from the database.
// NOTE: for now I'm assuming all records are Documents (they can also be "raw bytes" or "flat data")
// and for some reason I don't understand, multiple records can be returned, so I'm returning
// a slice of ODocument
//
// TODO: may also want to expose options: ignoreCache, loadTombstones bool
// TODO: need to properly handle fetchPlan
func FetchRecordByRID(dbc *DBClient, orid oschema.ORID, fetchPlan string) ([]*oschema.ODocument, error) {
	dbc.buf.Reset()

	err := writeCommandAndSessionId(dbc, REQUEST_RECORD_LOAD)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	err = rw.WriteShort(dbc.buf, orid.ClusterID)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	err = rw.WriteLong(dbc.buf, orid.ClusterPos)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	err = rw.WriteString(dbc.buf, fetchPlan)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	ignoreCache := true // hardcoding for now
	err = rw.WriteBool(dbc.buf, ignoreCache)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	loadTombstones := false // hardcoding for now
	err = rw.WriteBool(dbc.buf, loadTombstones)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	// send to the OrientDB server
	_, err = dbc.conx.Write(dbc.buf.Bytes())
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	/* ---[ Read Response ]--- */

	err = readStatusCodeAndSessionId(dbc)
	if err != nil {
		return nil, oerror.NewTrace(err)
	}

	// this query can return multiple records (though I don't understand why)
	// so must do this in a loop
	docs := make([]*oschema.ODocument, 0, 1)
	for {
		payloadStatus, err := rw.ReadByte(dbc.conx)
		if err != nil {
			return nil, oerror.NewTrace(err)
		}

		if payloadStatus == byte(0) {
			break
		}

		rectype, err := rw.ReadByte(dbc.conx)
		if err != nil {
			return nil, oerror.NewTrace(err)
		}

		recversion, err := rw.ReadInt(dbc.conx)
		if err != nil {
			return nil, oerror.NewTrace(err)
		}

		databytes, err := rw.ReadBytes(dbc.conx)
		if err != nil {
			return nil, oerror.NewTrace(err)
		}

		ogl.Debugf("rectype:%v, recversion:%v, len(databytes):%v\n", rectype, recversion, len(databytes))

		if rectype == 'd' {
			// we don't know the classname so set empty value
			doc := oschema.NewDocument("")
			doc.RID = orid
			doc.Version = recversion

			// the first byte specifies record serialization version
			// use it to look up serializer
			serde := dbc.RecordSerDes[int(databytes[0])]
			// then strip off the version byte and send the data to the serde
			err = serde.Deserialize(dbc, doc, obuf.NewReadBuffer(databytes[1:]))
			if err != nil {
				return nil, fmt.Errorf("ERROR in Deserialize for rid %v: %v\n", orid, err)
			}
			docs = append(docs, doc)

		} else {
			return nil,
				fmt.Errorf("Only `document` records are currently supported by the client. Record returned was type: %v", rectype)
		}
	}

	return docs, nil
}
Beispiel #13
0
//
// readDataValue reads the next data section from `buf` according
// to the type of the property (property.Typ) and updates the OField object
// to have the value.
//
func (serde ORecordSerializerV0) readDataValue(buf *obuf.ReadBuf, datatype oschema.ODataType) (interface{}, error) {
	var (
		val interface{}
		err error
	)
	switch datatype {
	case oschema.BOOLEAN:
		val, err = rw.ReadBool(buf)
		ogl.Debugf("DEBUG BOOL: +readDataVal val: %v\n", val) // DEBUG

	case oschema.INTEGER:
		var i64 int64
		i64, err = varint.ReadVarIntAndDecode64(buf)
		if err == nil {
			val = int32(i64)
		}
		ogl.Debugf("DEBUG INT: +readDataVal val: %v\n", val) // DEBUG

	case oschema.SHORT:
		var i32 int32
		i32, err = varint.ReadVarIntAndDecode32(buf)
		if err == nil {
			val = int16(i32)
		}
		ogl.Debugf("DEBUG SHORT: +readDataVal val: %v\n", val) // DEBUG

	case oschema.LONG:
		val, err = varint.ReadVarIntAndDecode64(buf)
		ogl.Debugf("DEBUG LONG: +readDataVal val: %v\n", val) // DEBUG

	case oschema.FLOAT:
		val, err = rw.ReadFloat(buf)
		ogl.Debugf("DEBUG FLOAT: +readDataVal val: %v\n", val) // DEBUG

	case oschema.DOUBLE:
		val, err = rw.ReadDouble(buf)
		ogl.Debugf("DEBUG DOUBLE: +readDataVal val: %v\n", val) // DEBUG

	case oschema.DATETIME:
		// OrientDB DATETIME is precise to the second
		val, err = serde.readDateTime(buf)
		ogl.Debugf("DEBUG DATEIME: +readDataVal val: %v\n", val) // DEBUG

	case oschema.DATE:
		// OrientDB DATE is precise to the day
		val, err = serde.readDate(buf)
		ogl.Debugf("DEBUG DATE: +readDataVal val: %v\n", val) // DEBUG

	case oschema.STRING:
		val, err = varint.ReadString(buf)
		ogl.Debugf("DEBUG STR: +readDataVal val: %v\n", val) // DEBUG

	case oschema.BINARY:
		val, err = varint.ReadBytes(buf)
		ogl.Debugf("DEBUG BINARY: +readDataVal val: %v\n", val) // DEBUG

	case oschema.EMBEDDED:
		doc := oschema.NewDocument("")
		err = serde.Deserialize(nil, doc, buf)
		val = interface{}(doc)
		// ogl.Debugf("DEBUG EMBEDDEDREC: +readDataVal val: %v\n", val) // DEBUG

	case oschema.EMBEDDEDLIST:
		val, err = serde.readEmbeddedCollection(buf)
		// ogl.Debugf("DEBUG EMBD-LIST: +readDataVal val: %v\n", val) // DEBUG

	case oschema.EMBEDDEDSET:
		val, err = serde.readEmbeddedCollection(buf) // TODO: may need to create a set type as well
		// ogl.Debugf("DEBUG EMBD-SET: +readDataVal val: %v\n", val) // DEBUG

	case oschema.EMBEDDEDMAP:
		val, err = serde.readEmbeddedMap(buf)
		// ogl.Debugf("DEBUG EMBD-MAP: +readDataVal val: %v\n", val) // DEBUG

	case oschema.LINK:
		// a link is two int64's (cluster:record) - we translate it here to a string RID
		val, err = serde.readLink(buf)
		ogl.Debugf("DEBUG LINK: +readDataVal val: %v\n", val) // DEBUG

	case oschema.LINKLIST, oschema.LINKSET:
		val, err = serde.readLinkList(buf)
		ogl.Debugf("DEBUG LINK LIST/SET: +readDataVal val: %v\n", val) // DEBUG

	case oschema.LINKMAP:
		val, err = serde.readLinkMap(buf)
		ogl.Debugf("DEBUG LINKMap: +readDataVal val: %v\n", val) // DEBUG

	case oschema.BYTE:
		val, err = rw.ReadByte(buf)
		ogl.Debugf("DEBUG BYTE: +readDataVal val: %v\n", val) // DEBUG

	case oschema.LINKBAG:
		val, err = serde.readLinkBag(buf)
		ogl.Debugf("DEBUG LINKBAG: +readDataVal val: %v\n", val) // DEBUG

	case oschema.CUSTOM:
		// TODO: impl me -> how? when is this used?
		panic("ORecordSerializerV0#readDataValue CUSTOM NOT YET IMPLEMENTED")
	case oschema.DECIMAL:
		// TODO: impl me -> Java client uses BigDecimal for this
		panic("ORecordSerializerV0#readDataValue DECIMAL NOT YET IMPLEMENTED")
	default:
		// ANY and TRANSIENT are do nothing ops
	}

	return val, err
}
Beispiel #14
0
//
// writeDataValue is part of the Serialize functionality
// TODO: change name to writeSingleValue ?
//
func (serde ORecordSerializerV0) writeDataValue(buf *obuf.WriteBuf, value interface{}, datatype oschema.ODataType) (err error) {
	switch datatype {
	case oschema.STRING:
		err = varint.WriteString(buf, value.(string))
		ogl.Debugf("DEBUG STR: -writeDataVal val: %v\n", value.(string)) // DEBUG

	case oschema.BOOLEAN:
		err = rw.WriteBool(buf, value.(bool))
		ogl.Debugf("DEBUG BOOL: -writeDataVal val: %v\n", value.(bool)) // DEBUG

	case oschema.INTEGER:
		var i32val int32
		i32val, err = toInt32(value)
		if err == nil {
			err = varint.EncodeAndWriteVarInt32(buf, i32val)         // TODO: are serialized integers ALWAYS varint encoded?
			ogl.Debugf("DEBUG INT: -writeDataVal val: %v\n", i32val) // DEBUG
		}

	case oschema.SHORT:
		// TODO: needs toInt16 conversion fn
		err = varint.EncodeAndWriteVarInt32(buf, int32(value.(int16)))
		ogl.Debugf("DEBUG SHORT: -writeDataVal val: %v\n", value.(int16)) // DEBUG

	case oschema.LONG:
		var i64val int64
		i64val, err = toInt64(value)
		if err == nil {
			err = varint.EncodeAndWriteVarInt64(buf, i64val)          // TODO: are serialized longs ALWAYS varint encoded?
			ogl.Debugf("DEBUG LONG: -writeDataVal val: %v\n", i64val) // DEBUG
		}

	case oschema.FLOAT:
		var f32 float32
		f32, err = toFloat32(value)
		if err == nil {
			err = rw.WriteFloat(buf, f32)
		}
		ogl.Debugf("DEBUG FLOAT: -writeDataVal val: %v\n", value) // DEBUG

	case oschema.DOUBLE:
		var f64 float64
		f64, err = toFloat64(value)
		if err == nil {
			err = rw.WriteDouble(buf, f64)
		}
		ogl.Debugf("DEBUG DOUBLE: -writeDataVal val: %v\n", value.(float64)) // DEBUG

	case oschema.DATETIME:
		err = writeDateTime(buf, value)
		ogl.Debugf("DEBUG DATETIME: -writeDataVal val: %v\n", value) // DEBUG

	case oschema.DATE:
		err = writeDate(buf, value)
		ogl.Debugf("DEBUG DATE: -writeDataVal val: %v\n", value) // DEBUG

	case oschema.BINARY:
		err = varint.WriteBytes(buf, value.([]byte))
		ogl.Debugf("DEBUG BINARY: -writeDataVal val: %v\n", value.([]byte)) // DEBUG

	case oschema.EMBEDDED:
		err = serde.serializeDocument(buf, value.(*oschema.ODocument))
		ogl.Debugf("DEBUG EMBEDDED: -writeDataVal val: %v\n", value) // DEBUG

	case oschema.EMBEDDEDLIST:
		err = serde.serializeEmbeddedCollection(buf, value.(oschema.OEmbeddedList))
		ogl.Debugf("DEBUG EMBD-LIST: -writeDataVal val: %v\n", value) // DEBUG

	case oschema.EMBEDDEDSET:
		err = serde.serializeEmbeddedCollection(buf, value.(oschema.OEmbeddedList))
		ogl.Debugf("DEBUG EMBD-SET: -writeDataVal val: %v\n", value) // DEBUG

	case oschema.EMBEDDEDMAP:
		err = serde.writeEmbeddedMap(buf, value.(oschema.OEmbeddedMap))
		ogl.Debugf("DEBUG EMBEDDEDMAP:  val %v\n", value.(oschema.OEmbeddedMap))

	case oschema.LINK:
		err = serde.writeLink(buf, value.(*oschema.OLink))
		ogl.Debugf("DEBUG LINK:  val %v\n", value) // DEBUG

	case oschema.LINKLIST:
		err = serde.writeLinkList(buf, value.([]*oschema.OLink))
		ogl.Debugf("DEBUG LINKLIST:  val %v\n", value) // DEBUG

	case oschema.LINKSET:
		err = serde.writeLinkList(buf, value.([]*oschema.OLink))
		ogl.Debugf("DEBUG LINKSET:  val %v\n", value) // DEBUG

	case oschema.LINKMAP:
		err = serde.writeLinkMap(buf, value.(map[string]*oschema.OLink))
		ogl.Debugf("DEBUG LINKMAP:  val %v\n", value) // DEBUG

	case oschema.BYTE:
		err = rw.WriteByte(buf, value.(byte))
		ogl.Debugf("DEBUG BYTE: -writeDataVal val: %v\n", value.(byte)) // DEBUG

	case oschema.DECIMAL:
		// TODO: impl me -> Java client uses BigDecimal for this
		panic("ORecordSerializerV0#writeDataValue DECIMAL NOT YET IMPLEMENTED")

	case oschema.CUSTOM:
		// TODO: impl me
		panic("ORecordSerializerV0#writeDataValue CUSTOM NOT YET IMPLEMENTED")
	case oschema.LINKBAG:
		panic("ORecordSerializerV0#writeDataValue LINKBAG NOT YET IMPLEMENTED")
	default:
		// ANY and TRANSIENT are do nothing ops
	}
	return err
}
Beispiel #15
0
//
// Columns returns the names of the columns. The number of
// columns of the result is inferred from the length of the
// slice.  If a particular column name isn't known, an empty
// string should be returned for that entry.
//
func (rows *ogonoriRows) Columns() []string {
	ogl.Debugf("** ogonoriRows.Columns = %v\n", rows.cols)
	return rows.cols
}