// // 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 }
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 }
// // 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) }
// // 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 }
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 }
// // 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 }
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 }
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 }
// // 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 }
// 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 }
// // 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 }
// // 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 }
// // 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 }
// // 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 }
// // 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 }