… | |
… | |
40 | # else |
40 | # else |
41 | # define WORDACCESS_UNSAFE 1 |
41 | # define WORDACCESS_UNSAFE 1 |
42 | # endif |
42 | # endif |
43 | #endif |
43 | #endif |
44 | |
44 | |
|
|
45 | typedef DB_ENV DB_ENV_ornull; |
|
|
46 | typedef DB_TXN DB_TXN_ornull; |
|
|
47 | typedef DBC DBC_ornull; |
|
|
48 | typedef DB DB_ornull; |
|
|
49 | |
45 | typedef SV SV8; /* byte-sv, used for argument-checking */ |
50 | typedef SV SV8; /* byte-sv, used for argument-checking */ |
46 | typedef char *octetstring; |
51 | typedef char *octetstring; |
47 | |
52 | |
48 | static SV *prepare_cb; |
53 | static SV *prepare_cb; |
49 | |
54 | |
… | |
… | |
51 | strdup_ornull (const char *s) |
56 | strdup_ornull (const char *s) |
52 | { |
57 | { |
53 | return s ? strdup (s) : 0; |
58 | return s ? strdup (s) : 0; |
54 | } |
59 | } |
55 | |
60 | |
|
|
61 | inline void |
|
|
62 | sv_to_dbt (DBT *dbt, SV *sv) |
|
|
63 | { |
|
|
64 | STRLEN len; |
|
|
65 | char *data = SvPVbyte (sv, len); |
|
|
66 | |
|
|
67 | dbt->data = malloc (len); |
|
|
68 | memcpy (dbt->data, data, len); |
|
|
69 | dbt->size = len; |
|
|
70 | } |
|
|
71 | |
|
|
72 | inline void |
|
|
73 | dbt_to_sv (SV *sv, DBT *dbt) |
|
|
74 | { |
|
|
75 | SvREADONLY_off (sv); |
|
|
76 | sv_setpvn_mg (sv, dbt->data, dbt->size); |
|
|
77 | |
|
|
78 | free (dbt->data); |
|
|
79 | } |
|
|
80 | |
56 | enum { |
81 | enum { |
57 | REQ_QUIT, |
82 | REQ_QUIT, |
58 | REQ_ENV_OPEN, REQ_ENV_CLOSE, |
83 | REQ_ENV_OPEN, REQ_ENV_CLOSE, |
59 | REQ_DB_OPEN, REQ_DB_CLOSE, REQ_DB_COMPACT, REQ_DB_SYNC, REQ_DB_PUT, |
84 | REQ_DB_OPEN, REQ_DB_CLOSE, REQ_DB_COMPACT, REQ_DB_SYNC, REQ_DB_PUT, REQ_DB_GET, REQ_DB_PGET, |
|
|
85 | REQ_TXN_COMMIT, REQ_TXN_ABORT, |
60 | }; |
86 | }; |
61 | |
87 | |
62 | typedef struct aio_cb |
88 | typedef struct aio_cb |
63 | { |
89 | { |
64 | struct aio_cb *volatile next; |
90 | struct aio_cb *volatile next; |
… | |
… | |
70 | DB_TXN *txn; |
96 | DB_TXN *txn; |
71 | DBC *cursor; |
97 | DBC *cursor; |
72 | int int1, int2; |
98 | int int1, int2; |
73 | U32 uint1, uint2; |
99 | U32 uint1, uint2; |
74 | char *buf1, *buf2; |
100 | char *buf1, *buf2; |
|
|
101 | SV *sv1, *sv2; |
75 | |
102 | |
76 | DBT dbt1, dbt2, dbt3; |
103 | DBT dbt1, dbt2, dbt3; |
77 | } aio_cb; |
104 | } aio_cb; |
78 | |
105 | |
79 | typedef aio_cb *aio_req; |
106 | typedef aio_cb *aio_req; |
… | |
… | |
262 | PUSHMARK (SP); |
289 | PUSHMARK (SP); |
263 | EXTEND (SP, 1); |
290 | EXTEND (SP, 1); |
264 | |
291 | |
265 | switch (req->type) |
292 | switch (req->type) |
266 | { |
293 | { |
|
|
294 | case REQ_DB_GET: |
|
|
295 | case REQ_DB_PGET: |
|
|
296 | dbt_to_sv (req->sv1, &req->dbt3); |
|
|
297 | SvREFCNT_dec (req->sv1); |
|
|
298 | break; |
|
|
299 | |
|
|
300 | case REQ_DB_CLOSE: |
|
|
301 | SvREFCNT_dec (req->sv1); |
|
|
302 | break; |
267 | } |
303 | } |
268 | |
304 | |
269 | errno = req->result; |
305 | errno = req->result; |
270 | |
306 | |
271 | PUTBACK; |
307 | PUTBACK; |
… | |
… | |
608 | req->result = req->db->sync (req->db, req->uint1); |
644 | req->result = req->db->sync (req->db, req->uint1); |
609 | break; |
645 | break; |
610 | |
646 | |
611 | case REQ_DB_PUT: |
647 | case REQ_DB_PUT: |
612 | req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1); |
648 | req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1); |
|
|
649 | break; |
|
|
650 | |
|
|
651 | case REQ_DB_GET: |
|
|
652 | req->result = req->db->get (req->db, req->txn, &req->dbt1, &req->dbt3, req->uint1); |
|
|
653 | break; |
|
|
654 | |
|
|
655 | case REQ_DB_PGET: |
|
|
656 | req->result = req->db->pget (req->db, req->txn, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1); |
|
|
657 | break; |
|
|
658 | |
|
|
659 | case REQ_TXN_COMMIT: |
|
|
660 | req->result = req->txn->commit (req->txn, req->uint1); |
|
|
661 | break; |
|
|
662 | |
|
|
663 | case REQ_TXN_ABORT: |
|
|
664 | req->result = req->txn->abort (req->txn); |
613 | break; |
665 | break; |
614 | |
666 | |
615 | default: |
667 | default: |
616 | req->result = ENOSYS; |
668 | req->result = ENOSYS; |
617 | break; |
669 | break; |
… | |
… | |
706 | req->pri = req_pri |
758 | req->pri = req_pri |
707 | |
759 | |
708 | #define REQ_SEND \ |
760 | #define REQ_SEND \ |
709 | req_send (req) |
761 | req_send (req) |
710 | |
762 | |
711 | #define SvPTR(var, arg, type, class) \ |
763 | #define SvPTR(var, arg, type, class, nullok) \ |
712 | if (!SvOK (arg)) \ |
764 | if (!SvOK (arg)) \ |
|
|
765 | { \ |
|
|
766 | if (!nullok) \ |
|
|
767 | Perl_croak (# var " must be a " # class " object, not undef"); \ |
|
|
768 | \ |
713 | (var) = 0; \ |
769 | (var) = 0; \ |
|
|
770 | } \ |
714 | else if (sv_derived_from ((arg), # class)) \ |
771 | else if (sv_derived_from ((arg), # class)) \ |
715 | { \ |
772 | { \ |
716 | IV tmp = SvIV ((SV*) SvRV (arg)); \ |
773 | IV tmp = SvIV ((SV*) SvRV (arg)); \ |
717 | (var) = INT2PTR (type, tmp); \ |
774 | (var) = INT2PTR (type, tmp); \ |
|
|
775 | if (!var) \ |
|
|
776 | Perl_croak (# var " is not a valid " # class " object anymore"); \ |
718 | } \ |
777 | } \ |
719 | else \ |
778 | else \ |
720 | Perl_croak (# var " is not of type " # class) |
779 | Perl_croak (# var " is not of type " # class); \ |
|
|
780 | \ |
721 | |
781 | |
722 | inline void |
782 | static void |
723 | set_dbt (DBT *dbt, SV *sv) |
783 | ptr_nuke (SV *sv) |
724 | { |
784 | { |
725 | STRLEN len; |
785 | assert (SvROK (sv)); |
726 | char *data = SvPVbyte (sv, len); |
786 | sv_setiv (SvRV (sv), 0); |
727 | |
|
|
728 | dbt->data = malloc (len); |
|
|
729 | memcpy (dbt->data, data, len); |
|
|
730 | dbt->size = len; |
|
|
731 | } |
787 | } |
732 | |
788 | |
733 | MODULE = BDB PACKAGE = BDB |
789 | MODULE = BDB PACKAGE = BDB |
734 | |
790 | |
735 | PROTOTYPES: ENABLE |
791 | PROTOTYPES: ENABLE |
736 | |
792 | |
737 | BOOT: |
793 | BOOT: |
… | |
… | |
777 | const_iv (REGION_INIT) |
833 | const_iv (REGION_INIT) |
778 | const_iv (TIME_NOTGRANTED) |
834 | const_iv (TIME_NOTGRANTED) |
779 | const_iv (TXN_NOSYNC) |
835 | const_iv (TXN_NOSYNC) |
780 | const_iv (TXN_SNAPSHOT) |
836 | const_iv (TXN_SNAPSHOT) |
781 | const_iv (TXN_WRITE_NOSYNC) |
837 | const_iv (TXN_WRITE_NOSYNC) |
|
|
838 | const_iv (WRITECURSOR) |
782 | const_iv (YIELDCPU) |
839 | const_iv (YIELDCPU) |
783 | const_iv (ENCRYPT_AES) |
840 | const_iv (ENCRYPT_AES) |
784 | const_iv (XA_CREATE) |
841 | const_iv (XA_CREATE) |
785 | const_iv (BTREE) |
842 | const_iv (BTREE) |
786 | const_iv (HASH) |
843 | const_iv (HASH) |
… | |
… | |
801 | const_iv (RENUMBER) |
858 | const_iv (RENUMBER) |
802 | const_iv (REVSPLITOFF) |
859 | const_iv (REVSPLITOFF) |
803 | const_iv (INORDER) |
860 | const_iv (INORDER) |
804 | const_iv (CONSUME) |
861 | const_iv (CONSUME) |
805 | const_iv (CONSUME_WAIT) |
862 | const_iv (CONSUME_WAIT) |
|
|
863 | const_iv (GET_BOTH) |
|
|
864 | //const_iv (SET_RECNO) |
|
|
865 | //const_iv (MULTIPLE) |
806 | const_iv (SNAPSHOT) |
866 | const_iv (SNAPSHOT) |
807 | const_iv (JOIN_ITEM) |
867 | const_iv (JOIN_ITEM) |
808 | const_iv (RMW) |
868 | const_iv (RMW) |
809 | |
869 | |
810 | const_iv (NOTFOUND) |
870 | const_iv (NOTFOUND) |
… | |
… | |
1006 | { |
1066 | { |
1007 | dREQ (REQ_ENV_CLOSE); |
1067 | dREQ (REQ_ENV_CLOSE); |
1008 | req->env = env; |
1068 | req->env = env; |
1009 | req->uint1 = flags; |
1069 | req->uint1 = flags; |
1010 | REQ_SEND; |
1070 | REQ_SEND; |
|
|
1071 | ptr_nuke (ST (0)); |
1011 | } |
1072 | } |
1012 | |
1073 | |
1013 | DB * |
1074 | DB * |
1014 | db_create (DB_ENV *env = 0, U32 flags = 0) |
1075 | db_create (DB_ENV *env = 0, U32 flags = 0) |
1015 | CODE: |
1076 | CODE: |
1016 | { |
1077 | { |
1017 | errno = db_create (&RETVAL, env, flags); |
1078 | errno = db_create (&RETVAL, env, flags); |
1018 | if (errno) |
1079 | if (errno) |
1019 | croak ("db_env_create: %s", db_strerror (errno)); |
1080 | croak ("db_env_create: %s", db_strerror (errno)); |
|
|
1081 | |
|
|
1082 | if (RETVAL) |
|
|
1083 | RETVAL->app_private = (void *)newSVsv (ST (0)); |
1020 | } |
1084 | } |
1021 | OUTPUT: |
1085 | OUTPUT: |
1022 | RETVAL |
1086 | RETVAL |
1023 | |
1087 | |
1024 | void |
1088 | void |
1025 | db_open (DB *db, DB_TXN *txnid, octetstring file, octetstring database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef) |
1089 | db_open (DB *db, DB_TXN_ornull *txnid, octetstring file, octetstring database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef) |
1026 | CODE: |
1090 | CODE: |
1027 | { |
1091 | { |
1028 | dREQ (REQ_DB_OPEN); |
1092 | dREQ (REQ_DB_OPEN); |
1029 | req->db = db; |
1093 | req->db = db; |
1030 | req->txn = txnid; |
1094 | req->txn = txnid; |
… | |
… | |
1041 | CODE: |
1105 | CODE: |
1042 | { |
1106 | { |
1043 | dREQ (REQ_DB_CLOSE); |
1107 | dREQ (REQ_DB_CLOSE); |
1044 | req->db = db; |
1108 | req->db = db; |
1045 | req->uint1 = flags; |
1109 | req->uint1 = flags; |
|
|
1110 | req->sv1 = (SV *)db->app_private; |
1046 | REQ_SEND; |
1111 | REQ_SEND; |
|
|
1112 | ptr_nuke (ST (0)); |
1047 | } |
1113 | } |
1048 | |
1114 | |
1049 | void |
1115 | void |
1050 | db_compact (DB *db, DB_TXN *txn = 0, SV *start = 0, SV *stop = 0, SV *unused1 = 0, U32 flags = DB_FREE_SPACE, SV *unused2 = 0, SV *callback = &PL_sv_undef) |
1116 | db_compact (DB *db, DB_TXN_ornull *txn = 0, SV *start = 0, SV *stop = 0, SV *unused1 = 0, U32 flags = DB_FREE_SPACE, SV *unused2 = 0, SV *callback = &PL_sv_undef) |
1051 | CODE: |
1117 | CODE: |
1052 | { |
1118 | { |
1053 | dREQ (REQ_DB_COMPACT); |
1119 | dREQ (REQ_DB_COMPACT); |
1054 | req->db = db; |
1120 | req->db = db; |
1055 | req->txn = txn; |
1121 | req->txn = txn; |
1056 | set_dbt (&req->dbt1, start); |
1122 | sv_to_dbt (&req->dbt1, start); |
1057 | set_dbt (&req->dbt2, stop); |
1123 | sv_to_dbt (&req->dbt2, stop); |
1058 | req->uint1 = flags; |
1124 | req->uint1 = flags; |
1059 | REQ_SEND; |
1125 | REQ_SEND; |
1060 | } |
1126 | } |
1061 | |
1127 | |
1062 | void |
1128 | void |
… | |
… | |
1068 | req->uint1 = flags; |
1134 | req->uint1 = flags; |
1069 | REQ_SEND; |
1135 | REQ_SEND; |
1070 | } |
1136 | } |
1071 | |
1137 | |
1072 | void |
1138 | void |
1073 | db_put (DB *db, DB_TXN *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
1139 | db_put (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
1074 | CODE: |
1140 | CODE: |
1075 | { |
1141 | { |
1076 | dREQ (REQ_DB_PUT); |
1142 | dREQ (REQ_DB_PUT); |
1077 | req->db = db; |
1143 | req->db = db; |
1078 | req->txn = 0; |
1144 | req->txn = txn; |
1079 | set_dbt (&req->dbt1, key); |
1145 | sv_to_dbt (&req->dbt1, key); |
1080 | set_dbt (&req->dbt2, data); |
1146 | sv_to_dbt (&req->dbt2, data); |
1081 | req->uint1 = flags; |
1147 | req->uint1 = flags; |
1082 | REQ_SEND; |
1148 | REQ_SEND; |
1083 | } |
1149 | } |
1084 | |
1150 | |
|
|
1151 | void |
|
|
1152 | db_get (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
|
|
1153 | CODE: |
|
|
1154 | { |
|
|
1155 | dREQ (REQ_DB_GET); |
|
|
1156 | req->db = db; |
|
|
1157 | req->txn = txn; |
|
|
1158 | sv_to_dbt (&req->dbt1, key); |
|
|
1159 | req->dbt3.flags = DB_DBT_MALLOC; |
|
|
1160 | req->uint1 = flags; |
|
|
1161 | req->sv1 = SvREFCNT_inc (data); |
|
|
1162 | SvREADONLY_on (data); |
|
|
1163 | REQ_SEND; |
|
|
1164 | } |
|
|
1165 | |
|
|
1166 | void |
|
|
1167 | db_pget (DB *db, DB_TXN_ornull *txn, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
|
|
1168 | CODE: |
|
|
1169 | { |
|
|
1170 | dREQ (REQ_DB_PGET); |
|
|
1171 | req->db = db; |
|
|
1172 | req->txn = txn; |
|
|
1173 | sv_to_dbt (&req->dbt1, key); |
|
|
1174 | sv_to_dbt (&req->dbt2, pkey); |
|
|
1175 | req->dbt3.flags = DB_DBT_MALLOC; |
|
|
1176 | req->uint1 = flags; |
|
|
1177 | req->sv1 = SvREFCNT_inc (data); |
|
|
1178 | SvREADONLY_on (data); |
|
|
1179 | REQ_SEND; |
|
|
1180 | } |
|
|
1181 | |
|
|
1182 | void |
|
|
1183 | db_txn_commit (DB_TXN *txn, U32 flags = 0, SV *callback = &PL_sv_undef) |
|
|
1184 | CODE: |
|
|
1185 | { |
|
|
1186 | dREQ (REQ_TXN_COMMIT); |
|
|
1187 | req->txn = txn; |
|
|
1188 | req->uint1 = flags; |
|
|
1189 | REQ_SEND; |
|
|
1190 | ptr_nuke (ST (0)); |
|
|
1191 | } |
|
|
1192 | |
|
|
1193 | void |
|
|
1194 | db_txn_abort (DB_TXN *txn, SV *callback = &PL_sv_undef) |
|
|
1195 | CODE: |
|
|
1196 | { |
|
|
1197 | dREQ (REQ_TXN_ABORT); |
|
|
1198 | req->txn = txn; |
|
|
1199 | REQ_SEND; |
|
|
1200 | ptr_nuke (ST (0)); |
|
|
1201 | } |
|
|
1202 | |
1085 | |
1203 | |
1086 | MODULE = BDB PACKAGE = BDB::Env |
1204 | MODULE = BDB PACKAGE = BDB::Env |
1087 | |
1205 | |
|
|
1206 | void |
|
|
1207 | DESTROY (DB_ENV_ornull *env) |
|
|
1208 | CODE: |
|
|
1209 | if (env) |
|
|
1210 | env->close (env, 0); |
|
|
1211 | |
1088 | int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0) |
1212 | int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0) |
1089 | CODE: |
1213 | CODE: |
1090 | RETVAL = env->set_cachesize (env, gbytes, bytes, ncache); |
1214 | RETVAL = env->set_cachesize (env, gbytes, bytes, ncache); |
1091 | OUTPUT: |
1215 | OUTPUT: |
1092 | RETVAL |
1216 | RETVAL |
… | |
… | |
1107 | CODE: |
1231 | CODE: |
1108 | RETVAL = env->set_timeout (env, timeout * 1000000, flags); |
1232 | RETVAL = env->set_timeout (env, timeout * 1000000, flags); |
1109 | OUTPUT: |
1233 | OUTPUT: |
1110 | RETVAL |
1234 | RETVAL |
1111 | |
1235 | |
|
|
1236 | DB_TXN * |
|
|
1237 | txn_begin (DB_ENV *env, DB_TXN_ornull *parent = 0, U32 flags = 0) |
|
|
1238 | CODE: |
|
|
1239 | errno = env->txn_begin (env, parent, &RETVAL, flags); |
|
|
1240 | if (errno) |
|
|
1241 | croak ("txn_begin: %s", db_strerror (errno)); |
|
|
1242 | OUTPUT: |
|
|
1243 | RETVAL |
1112 | |
1244 | |
1113 | MODULE = BDB PACKAGE = BDB::Db |
1245 | MODULE = BDB PACKAGE = BDB::Db |
1114 | |
1246 | |
|
|
1247 | void |
|
|
1248 | DESTROY (DB_ornull *db) |
|
|
1249 | CODE: |
|
|
1250 | if (db) |
|
|
1251 | { |
|
|
1252 | SV *env = (SV *)db->app_private; |
|
|
1253 | db->close (db, 0); |
|
|
1254 | SvREFCNT_dec (env); |
|
|
1255 | } |
|
|
1256 | |
1115 | int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0) |
1257 | int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0) |
1116 | CODE: |
1258 | CODE: |
1117 | RETVAL = db->set_cachesize (db, gbytes, bytes, ncache); |
1259 | RETVAL = db->set_cachesize (db, gbytes, bytes, ncache); |
1118 | OUTPUT: |
1260 | OUTPUT: |
1119 | RETVAL |
1261 | RETVAL |
… | |
… | |
1183 | CODE: |
1325 | CODE: |
1184 | RETVAL = db->set_q_extentsize (db, extentsize); |
1326 | RETVAL = db->set_q_extentsize (db, extentsize); |
1185 | OUTPUT: |
1327 | OUTPUT: |
1186 | RETVAL |
1328 | RETVAL |
1187 | |
1329 | |
|
|
1330 | MODULE = BDB PACKAGE = BDB::Txn |
1188 | |
1331 | |
|
|
1332 | void |
|
|
1333 | DESTROY (DB_TXN_ornull *txn) |
|
|
1334 | CODE: |
|
|
1335 | if (txn) |
|
|
1336 | txn->abort (txn); |
|
|
1337 | |
|
|
1338 | int set_timeout (DB_TXN *txn, NV timeout, U32 flags) |
|
|
1339 | CODE: |
|
|
1340 | RETVAL = txn->set_timeout (txn, timeout * 1000000, flags); |
|
|
1341 | OUTPUT: |
|
|
1342 | RETVAL |
|
|
1343 | |
|
|
1344 | |