File: test067.cxx

package info (click to toggle)
libpqxx 4.0.1%2Bdfsg3-8
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 16,012 kB
  • ctags: 9,469
  • sloc: sh: 11,289; cpp: 10,801; xml: 1,256; makefile: 287; ansic: 195; python: 159
file content (119 lines) | stat: -rw-r--r-- 3,261 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <cstdio>
#include <iostream>
#include <vector>

#include "test_helpers.hxx"

using namespace PGSTD;
using namespace pqxx;


// Test program for libpqxx.  See which fields in a query are null, and figure
// out whether any fields are lexicographically sorted.  Use asyncconnection.
namespace
{
template<typename VEC, typename VAL>
void InitVector(VEC &V, typename VEC::size_type s, VAL val)
{
  V.resize(s);
  for (typename VEC::iterator i = V.begin(); i != V.end(); ++i) *i = val;
}


void test_067(transaction_base &orgT)
{
  connection_base &C(orgT.conn());
  orgT.abort();

  const string Table = "pg_tables";

  // Tell C we won't be needing it for a while (not true, but let's pretend)
  C.deactivate();

  // Now set up some data structures
  vector<int> NullFields;		// Maps column to no. of null fields
  vector<bool> SortedUp, SortedDown;	// Does column appear to be sorted?

  // ...And reactivate C (not really needed, but it sounds more polite)
  C.activate();

  work T(C, "test67");

  result R( T.exec("SELECT * FROM " + Table) );

  InitVector(NullFields, R.columns(), 0);
  InitVector(SortedUp, R.columns(), true);
  InitVector(SortedDown, R.columns(), true);

  for (result::const_iterator i = R.begin(); i != R.end(); i++)
  {
    PQXX_CHECK_EQUAL(
	(*i).rownumber(),
	i->rownumber(),
	"operator*() is inconsistent with operator->().");

    PQXX_CHECK_EQUAL(i->size(), R.columns(), "result::columns() is broken.");

    // Look for null fields
    for (pqxx::tuple::size_type f=0; f<i->size(); ++f)
    {
      NullFields[f] += i.at(f).is_null();

      string A, B;
      PQXX_CHECK_EQUAL(
	i[f].to(A),
	i[f].to(B, string("")),
	"Variants of to() disagree on nullness.");

      PQXX_CHECK_EQUAL(A, B, "to() variants return different values.");
    }

    // Compare fields to those of preceding row
    if (i != R.begin())
    {
      const result::const_iterator j = i - 1;

      // First perform some sanity checks on j vs. i and how libpqxx handles
      // their interrelationship...
      PQXX_CHECK_EQUAL(i - j, 1, "Successor is at wrong distance.");

      // ...Now let's do meaningful stuff with j, such as finding out which
      // fields may be sorted.  Don't do anything fancy like trying to
      // detect numbers and comparing them as such, just compare them as
      // simple strings.
      for (pqxx::tuple::size_type f = 0; f < R.columns(); ++f)
      {
	if (!j[f].is_null() && !i[f].is_null())
	{
	  const bool U = SortedUp[f], D = SortedDown[f];
	  SortedUp[f] = (U && (j[f].as<string>() <= i[f].as<string>()));
	  SortedDown[f] = (D && (j[f].as<string>() >= i[f].as<string>()));
	}
      }
    }
  }

  // Now report on what we've found
  cout << "Read " << to_string(R.size()) << " rows." << endl;
  cout << "Field \t Field Name\t Nulls\t Sorted" << endl;

  for (pqxx::tuple::size_type f = 0; f < R.columns(); ++f)
  {
    cout << to_string(f) << ":\t"
	 << R.column_name(f) << '\t'
	 << NullFields[f] << '\t'
	 << (SortedUp[f] ?
		(SortedDown[f] ? "equal" : "up" ) :
		(SortedDown[f] ? "down" : "no" ) )
	 << endl;

    PQXX_CHECK_BOUNDS(
	NullFields[f],
	0,
	int(R.size()+1),
	"Found impossible number of nulls.");
  }
}
} // namespace

PQXX_REGISTER_TEST_CT(test_067, asyncconnection, nontransaction)