-
Notifications
You must be signed in to change notification settings - Fork 0
/
insert.cpp
105 lines (84 loc) · 2.84 KB
/
insert.cpp
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
#include "catalog.h"
#include "query.h"
#include "index.h"
#include "utility.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Status Updates::Insert(const string& relation, // Name of the relation
const int attrCnt, // Number of attributes specified in INSERT statement
const attrInfo attrList[]) // Value of attributes specified in INSERT statement
{
Status status;
AttrDesc *attrs;
Record record;
RID rid;
int real_attrCnt = 0;
int record_size = 0;
void* record_mem = NULL;
try {
// Open heap file
HeapFile heap(relation, status);
if(status != OK) throw status;
// get attribute data
status = attrCat->getRelInfo(relation, real_attrCnt, attrs);
if(status != OK) throw status;
// If the relational attr count isn't equal to attr count specified
// This handles if no value is specified and # attr is right
if (real_attrCnt != attrCnt) throw ATTRTYPEMISMATCH;
// Get the size in bytes the record should be
for (int i = 0; i < attrCnt; ++i) {
record_size += attrs[i].attrLen;
}
// Memory allocation for record
record_mem = operator new(record_size);
if (record_mem == NULL) throw INSUFMEM;
int inserted = 0;
for (int i = 0; i < attrCnt; ++i) {
for (int j = 0; j < attrCnt; ++j) {
// Ensures in correct order according to attrs
if(strcmp(attrList[j].attrName, attrs[i].attrName) == 0) {
// Throw error if the value to be inserted is larger than the
// length it allows, as per https://piazza.com/class/hzcwxwdhmhv5r0?cid=1118
if(attrList[j].attrType == STRING) {
if(strlen((char*)attrList[j].attrValue) > attrs[i].attrLen) {
throw ATTRTYPEMISMATCH;
}
}
void* insert_location = (char*)record_mem + attrs[i].attrOffset;
memcpy(insert_location, attrList[j].attrValue, attrs[i].attrLen);
inserted++;
break;
}
}
}
// Throw error if not inserting the exact amount of attributes
if(inserted != attrCnt) throw ATTRNOTFOUND;
record.data = record_mem;
record.length = record_size;
status = heap.insertRecord(record, rid);
if(status != OK) throw status;
for (int i = 0; i < attrCnt; ++i) {
if(attrs[i].indexed == false) continue;
Index idx(
relation,
attrs[i].attrOffset,
attrs[i].attrLen,
static_cast<Datatype>(attrs[i].attrType), // https://piazza.com/class/hzcwxwdhmhv5r0?cid=999
NONUNIQUE, // not unique (https://piazza.com/class/hzcwxwdhmhv5r0?cid=995)
status
);
if(status != OK) throw status;
status = idx.insertEntry((char*)record.data + attrs[i].attrOffset, rid);
if(status != OK) throw status;
}
// no exceptions thrown, so status is OK
status = OK;
} catch (Status s) {
status = s;
}
// Free memory
if(attrs) delete[] attrs;
if(record_mem) operator delete(record_mem);
return status;
}