-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRowDescriptor.cpp
More file actions
112 lines (101 loc) · 2.69 KB
/
RowDescriptor.cpp
File metadata and controls
112 lines (101 loc) · 2.69 KB
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
// Copyright © 2023 CCP ehf.
#include "RowDescriptor.h"
#include "utils.h"
#include <atlstr.h>
//Set up the object from the DynamicAccessor
// layout is: [binary columns, null flags, Object columns ]
DelayedException* RowDescriptor::Init( ACCESSOR& a )
{
//first pass. Build column list, count sizes;
int sizes[6] = { 0 };
mNObjects = 0;
mColumnList.clear();
DBORDINAL i;
DBORDINAL nc = a.GetColumnCount();
for( i = 0; i < nc; i++ )
{
CW2A name( a.GetColumnName( i + 1 ) );
mColumnList.push_back( ColumnDescriptor( name ) );
ColumnDescriptor& cd = mColumnList.back();
DBTYPE type;
if( !a.GetColumnType( i + 1, &type ) )
{
CString msg;
msg.Format( "Couldn't get column type of column %d", i );
PYDBERROR( msg );
}
int size;
DelayedException* de = ColumnDescriptor::TypeTranslate( type, size );
if( de )
return de;
sizes[size]++;
cd.mType = type;
cd.mSize = size;
}
//now, compute offsets, starting with the largest (real) size
int offsets[5];
int offset = 0; //totaloffset to extra data
for( i = 4; i > 0; i-- )
{ //regular ints
offsets[i] = offset;
offset += sizes[i] * ( 1 << ( i - 1 ) );
}
//bools
offset *= 8; //turn into bits;
offsets[0] = offset; //start of boolean flags, in bits
offset += sizes[0]; //space required for bits
//null flags
mSNull = offset; //start of null flags in bits
offset += (int)mColumnList.size(); //space required for bits,
//round up to bytes again
offset = ( offset + 7 ) / 8;
mDataLen = offset; //this is the length of the data and null flags (in bytes).
//pointers
mNObjects = sizes[5];
if( mNObjects )
{
offset = ( offset + ( sizeof( void* ) - 1 ) ) & ~( sizeof( void* ) - 1 ); //round up in size.
mSObjects = offset / sizeof( void* ); //get offset for the object counter.
mTotalLen = offset + mNObjects * sizeof( void* );
}
else
{
mSObjects = 0;
mTotalLen = mDataLen;
}
//second pass, compute offsets and modify sizes
for( i = 0; i < (int)mColumnList.size(); i++ )
{
ColumnDescriptor& cd = mColumnList[i];
if( cd.mSize > 0 && cd.mSize < 5 )
{
//an intergral object or flag
cd.mOffset = offsets[cd.mSize];
int size = 1 << ( cd.mSize - 1 );
offsets[cd.mSize] += size;
cd.mSize = size;
}
else if( cd.mSize == 0 )
{
//bools
cd.mOffset = offsets[0]++;
cd.mSize = -1;
}
else
{
//pointers
cd.mOffset = offset;
cd.mSize = sizeof( void* );
offset += cd.mSize;
}
}
return 0;
}
PyObject* RowDescriptor::ToPython( PyObject* blueModule )
{
TTIMER2( "DB::NSession::ToPython::RowDescriptor" );
BluePy raw( PyCapsule_New( &mColumnList, "DBRowDescriptor", 0 ) );
if( !raw )
return 0;
return PyObject_CallMethod( blueModule, (char*)"DBRowDescriptor", (char*)"O", raw.o );
}