FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
zig-postgres/src/postgres.zig at main · rofrol/zig-postgres · GitHub
rofrol
/
zig-postgres
Public
forked from
jane0009/zig-postgres
Notifications
You must be signed in to change notification settings
Fork
2
Star
20
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
zig-postgres
/
src
/
postgres.zig
Copy path
More file actions
More file actions
Latest commit
History
History
History
175 lines (139 loc) · 6.67 KB
Breadcrumbs
zig-postgres
/
src
/
postgres.zig
Copy path
File metadata and controls
175 lines (139 loc) · 6.67 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
const
std
=
@import
(
"std"
);
pub
const
c
=
@cImport
({
@cInclude
(
"libpq-fe.h"
);
});
const
build_options
=
@import
(
"build_options"
);
pub
const
Builder
=
@import
(
"./sql_builder.zig"
).
Builder
;
pub
const
Parser
=
@import
(
"./parser.zig"
);
const
helpers
=
@import
(
"./helpers.zig"
);
const
Definitions
=
@import
(
"./definitions.zig"
);
const
Error
=
Definitions
.
Error
;
const
Allocator
=
std
.
mem
.
Allocator
;
const
ArrayList
=
std
.
ArrayList
;
pub
const
Result
=
@import
(
"./result.zig"
).
Result
;
pub
const
FieldInfo
=
@import
(
"./result.zig"
).
FieldInfo
;
const
print
=
std
.
debug
.
print
;
pub
const
Pg
=
struct
{
const
Self
=
@This
();
connection
:
*
c.PGconn
,
allocator
:
std.mem.Allocator
,
pub
fn
connect
(
allocator
:
std.mem.Allocator
,
address
: []
const
u8
)
!
Self
{
var
conn_info
=
try
std
.
cstr
.
addNullByte
(
allocator
,
address
);
var
connection
:
*
c.PGconn
=
undefined
;
defer
allocator
.
free
(
conn_info
);
if
(
c
.
PQconnectdb
(
conn_info
))
|
conn
|
{
connection
=
conn
;
}
if
(
c
.
PQstatus
(
connection
)
!=
c
.
CONNECTION_OK
) {
return
Error
.
ConnectionFailure
;
}
return
Self
{
.
allocator
=
allocator
,
.
connection
=
connection
,
};
}
pub
fn
insert
(
self
:
Self
,
data
:
anytype
)
!
Result
{
var
temp_memory
=
std
.
heap
.
ArenaAllocator
.
init
(
std
.
heap
.
page_allocator
);
var
allocator
=
temp_memory
.
allocator
();
var
builder
=
Builder
.
new
(
.Insert
,
allocator
);
const
type_info
=
@typeInfo
(
@TypeOf
(
data
));
defer
{
builder
.
deinit
();
temp_memory
.
deinit
();
}
switch
(
type_info
) {
.Pointer
=
>
{
const
pointer_info
=
@typeInfo
(
type_info
.
Pointer
.
child
);
if
(
pointer_info
==
.Array
) {
// For each item in inserted array
for
(
data
)
|
child
,
child_index
|
{
//Set table name as first items struct name.
if
(
child_index
==
0
) {
const
struct_name
=
@typeName
(
@TypeOf
(
child
));
_
=
builder
.
table
(
helpers
.
toLowerCase
(
struct_name
.
len
,
struct_name
)[0
..
]);
}
const
struct_fields
=
@typeInfo
(
@TypeOf
(
child
)).
Struct
.
fields
;
const
is_extended
=
@hasDecl
(
@TypeOf
(
child
),
"onSave"
);
inline
for
(
struct_fields
)
|
field
|
{
const
field_type_info
=
@typeInfo
(
field
.
type
);
const
field_value
=
@field
(
child
,
field
.
name
);
//Add first child struct keys as column value
if
(
field_type_info
==
.Optional
) {
if
(
field_value
!=
null
)
try
builder
.
addColumn
(
field
.
name
);
}
else
if
(
child_index
==
0
) {
try
builder
.
addColumn
(
field
.
name
);
}
builder
.
autoAdd
(
child
,
FieldInfo
{ .
name
=
field
.
name
, .
type
=
field
.
type
},
field_value
,
is_extended
)
catch
unreachable
;
}
}
}
if
(
pointer_info
==
.Struct
) {
//Struct pointer
const
struct_info
=
@typeInfo
(
type_info
.
Pointer
.
child
).
Struct
;
const
struct_name
=
@typeName
(
type_info
.
Pointer
.
child
);
const
is_extended
=
@hasDecl
(
type_info
.
Pointer
.
child
,
"onSave"
);
_
=
builder
.
table
(
helpers
.
toLowerCase
(
struct_name
.
len
,
struct_name
)[0
..
]);
inline
for
(
struct_info
.
fields
)
|
field
|
{
const
field_type_info
=
@typeInfo
(
field
.
type
);
const
field_value
=
@field
(
data
,
field
.
name
);
if
(
field_type_info
==
.Optional
) {
if
(
field_value
!=
null
)
try
builder
.
addColumn
(
field
.
name
);
}
else
{
try
builder
.
addColumn
(
field
.
name
);
}
builder
.
autoAdd
(
data
,
FieldInfo
{ .
name
=
field
.
name
, .
type
=
field
.
type
},
field_value
,
is_extended
)
catch
unreachable
;
}
}
},
.Struct
=
>
{
const
struct_info
=
@typeInfo
(
@TypeOf
(
data
)).
Struct
;
const
struct_name
=
@typeName
(
@TypeOf
(
data
));
const
is_extended
=
@hasDecl
(
@TypeOf
(
data
),
"onSave"
);
var
buf
: [
1024
]
u8
=
undefined
;
const
table_name
=
helpers
.
extWithoutDotLowerCase
(
struct_name
.
len
,
struct_name
,
&
buf
);
_
=
builder
.
table
(
table_name
);
inline
for
(
struct_info
.
fields
)
|
field
|
{
const
field_type_info
=
@typeInfo
(
field
.
type
);
const
field_value
=
@field
(
data
,
field
.
name
);
if
(
field_type_info
==
.Optional
) {
if
(
field_value
!=
null
)
try
builder
.
addColumn
(
field
.
name
);
}
else
{
try
builder
.
addColumn
(
field
.
name
);
}
builder
.
autoAdd
(
data
,
FieldInfo
{ .
name
=
field
.
name
, .
type
=
field
.
type
},
field_value
,
is_extended
)
catch
unreachable
;
}
},
else
=
>
@compileError
(
"type "
++
@typeName
(
@TypeOf
(
data
))
++
" not supported yet"
),
}
// _ = builder.table("users");
try
builder
.
end
();
//Exec command
return
try
self
.
exec
(
builder
.
command
());
}
pub
fn
exec
(
self
:
Self
,
query
: []
const
u8
)
!
Result
{
var
cstr_query
=
try
std
.
cstr
.
addNullByte
(
self
.
allocator
,
query
);
defer
self
.
allocator
.
free
(
cstr_query
);
var
res
:
?
*
c.PGresult
=
c
.
PQexec
(
self
.
connection
,
cstr_query
);
// var response_code = @enumToInt(c.PQresultStatus(res));
var
response_code
=
c
.
PQresultStatus
(
res
);
if
(
response_code
!=
c
.
PGRES_TUPLES_OK
and
response_code
!=
c
.
PGRES_COMMAND_OK
and
response_code
!=
c
.
PGRES_NONFATAL_ERROR
) {
std
.
debug
.
print
(
"Error {s}
\n
"
, .{
c
.
PQresultErrorMessage
(
res
)});
c
.
PQclear
(
res
);
return
Error
.
QueryFailure
;
}
if
(
res
)
|
result
|
{
return
Result
.
new
(
result
);
}
else
{
return
Error
.
QueryFailure
;
}
}
pub
fn
execValues
(
self
:
Self
,
comptime
query
: []
const
u8
,
values
:
anytype
)
!
Result
{
var
temp_memory
=
std
.
heap
.
ArenaAllocator
.
init
(
std
.
heap
.
page_allocator
);
defer
temp_memory
.
deinit
();
const
allocator
=
temp_memory
.
allocator
();
return
self
.
exec
(
try
Builder
.
buildQuery
(
query
,
values
,
allocator
));
}
pub
fn
deinit
(
self
:
*
Self
)
void
{
c
.
PQfinish
(
self
.
connection
);
}
};
Back
|
FazBrowse Home
|
New Git URL