1/*
2** Zabbix
3** Copyright (C) 2001-2021 Zabbix SIA
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18**/
19
20package oracle
21
22import (
23	"context"
24	"database/sql"
25	"encoding/json"
26	"strings"
27
28	"zabbix.com/pkg/zbxerr"
29)
30
31// customQueryHandler executes custom user queries
32func customQueryHandler(ctx context.Context, conn OraClient,
33	params map[string]string, extraParams ...string) (interface{}, error) {
34	queryName := params["QueryName"]
35
36	queryArgs := make([]interface{}, len(extraParams))
37	for i, v := range extraParams {
38		queryArgs[i] = v
39	}
40
41	rows, err := conn.QueryByName(ctx, queryName, queryArgs...)
42	if err != nil {
43		return nil, zbxerr.ErrorCannotFetchData.Wrap(err)
44	}
45	defer rows.Close()
46
47	// JSON marshaling
48	var data []string
49
50	columns, err := rows.Columns()
51	if err != nil {
52		return nil, zbxerr.ErrorCannotFetchData.Wrap(err)
53	}
54
55	values := make([]interface{}, len(columns))
56	valuePointers := make([]interface{}, len(values))
57
58	for i := range values {
59		valuePointers[i] = &values[i]
60	}
61
62	results := make(map[string]interface{})
63
64	for rows.Next() {
65		err = rows.Scan(valuePointers...)
66		if err != nil {
67			if err == sql.ErrNoRows {
68				return nil, zbxerr.ErrorEmptyResult.Wrap(err)
69			}
70
71			return nil, zbxerr.ErrorCannotFetchData.Wrap(err)
72		}
73
74		for i, value := range values {
75			results[columns[i]] = value
76		}
77
78		jsonRes, _ := json.Marshal(results)
79		data = append(data, strings.TrimSpace(string(jsonRes)))
80	}
81
82	return "[" + strings.Join(data, ",") + "]", nil
83}
84