//ExecuteQueryToFormattedString executes a query and serializes the results to a string in the format provided func (model *Model) ExecuteQueryToFormattedString(query *Query, format string) (string, error) { var librdf_query *C.librdf_query cQueryString := C.CString(query.queryString) if cQueryString != nil { defer C.free(unsafe.Pointer(cQueryString)) } cName := C.CString(query.name) if cName != nil { defer C.free(unsafe.Pointer(cName)) } cFormat := C.CString(format) if cFormat != nil { defer C.free(unsafe.Pointer(cFormat)) } librdf_query = C.librdf_new_query(query.world.librdf_world, (*C.char)(unsafe.Pointer(cName)), nil, (*C.uchar)(unsafe.Pointer(cQueryString)), nil) if librdf_query == nil { return "", errors.New("Unable to create query for execution") } results := C.librdf_model_query_execute(model.librdf_model, librdf_query) if results == nil { return "", errors.New("Failed to execute query") } var cFormattedString *C.uchar isBindings := C.librdf_query_results_is_bindings(results) isBoolean := C.librdf_query_results_is_boolean(results) if isBindings == 0 || isBoolean == 0 { cFormattedString = C.librdf_query_results_to_string2(results, (*C.char)(unsafe.Pointer(cFormat)), nil, nil, nil) } else { var serializer *C.librdf_serializer if serializer = C.librdf_new_serializer(query.world.librdf_world, (*C.char)(unsafe.Pointer(cFormat)), nil, nil); serializer == nil { return "", errors.New("Failed to build serializer") } defer C.librdf_free_serializer(serializer) var stream *C.librdf_stream if stream = C.librdf_query_results_as_stream(results); stream == nil { return "", errors.New("Failed to build stream from results") } defer C.librdf_free_stream(stream) cFormattedString = C.librdf_serializer_serialize_stream_to_string(serializer, nil, stream) } if cFormattedString == nil { return "", errors.New("Failed to build formatted string from results") } defer C.free(unsafe.Pointer(cFormattedString)) formattedString := C.GoString((*C.char)(unsafe.Pointer(cFormattedString))) return formattedString, nil }
//ExecuteQueryToResultsChannel executes the given query and returns a channel used to read the results func (model *Model) ExecuteQueryToResultsChannel(query *Query, bufferSize int) (chan *QueryResultItem, error) { var err error = nil chanQueryResultItem := make(chan *QueryResultItem, bufferSize) cQueryString := C.CString(query.queryString) if cQueryString != nil { defer C.free(unsafe.Pointer(cQueryString)) } cName := C.CString(query.name) if cName != nil { defer C.free(unsafe.Pointer(cName)) } librdf_query := C.librdf_new_query(query.world.librdf_world, (*C.char)(unsafe.Pointer(cName)), nil, (*C.uchar)(unsafe.Pointer(cQueryString)), nil) if librdf_query == nil { return nil, errors.New("Failed to create new query") } results := C.librdf_model_query_execute(model.librdf_model, librdf_query) if results == nil { err = errors.New("Error executing query") } if C.librdf_query_results_finished(results) != 0 { return nil, errors.New("Query returned no results") } go func() { for C.librdf_query_results_finished(results) == 0 { item := new(QueryResultItem) cBindingCount := C.librdf_query_results_get_bindings_count(results) bindingCount := int(cBindingCount) if bindingCount == 0 { continue } item.NameNodePairs = make([]NameNodePair, bindingCount, bindingCount) for i := 0; i < bindingCount; i++ { cName := C.librdf_query_results_get_binding_name(results, C.int(i)) librdf_node := C.librdf_query_results_get_binding_value(results, C.int(i)) item.NameNodePairs[i].Name = C.GoString(cName) node := new(Node) node.world = query.world node.librdf_node = librdf_node item.NameNodePairs[i].Node = node } chanQueryResultItem <- item C.librdf_query_results_next(results) } close(chanQueryResultItem) }() return chanQueryResultItem, err }