Пример #1
0
//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
}
Пример #2
0
//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
}