Compare commits

..
3191 Commits
Author SHA1 Message Date
Hide_D 7b21b60c11 fix: api 호출 순서가 거꾸로 2021-12-26 03:47:16 +09:00
Hide_D e5d8b71d0a Merge branch 'devel' into ng_depCenter 2021-12-26 03:33:57 +09:00
Hide_D d96099b9d3 fix: toast가 가려지는 부분이 있는 문제 수정 2021-12-26 03:31:32 +09:00
Hide_D ffe9fc9349 misc: 시간-턴 순서 변경. 일관성 약간 향상 2021-12-26 02:36:05 +09:00
Hide_D b7415ba521 dep: 패키지 업데이트 2021-12-26 02:01:58 +09:00
Hide_D 38e689ebb2 feat: api.php를 sammoAPI()로 통일 2021-12-26 01:58:26 +09:00
Hide_D 09caaee58d misc: 홀짝 색을 어둡게 2021-12-26 00:32:09 +09:00
Hide_D e8f8fc501d fix: 홀짝 색 일치...
- nth-child는 그 뜻이 아니다!
2021-12-26 00:06:43 +09:00
Hide_D e6038b854e misc: 턴 선택기에 색 표기 2021-12-26 00:00:56 +09:00
Hide_D dad01b45e4 fix: ui 요소 안정화
- 사령부
- 커맨드 되돌아가기
2021-12-25 23:08:53 +09:00
Hide_D 356250ba8c fix: 사령부에 500px 전환 코드 추가 2021-12-25 22:55:16 +09:00
Hide_D d1f7c13488 fix: 사령부 오른쪽 여백으로 스크롤 2021-12-25 22:49:26 +09:00
Hide_D 6f614eddd3 fix: 사령부가 덜 찬 상황에서 표기되지 않는 버그 수정 2021-12-25 22:30:23 +09:00
Hide_D 5142c94f84 feat: chiefCenter 500px 재구현
- API: 사령턴 관련
- TopBackBar에 갱신 추가
2021-12-25 21:51:47 +09:00
Hide_D c961096b70 Merge branch 'g38_ui' into devel 2021-12-23 17:19:57 +09:00
Hide_D c6050c6d21 fix: 발령시 스탯 표기 2021-12-23 17:19:00 +09:00
Hide_D 8bbc6ae02d Merge branch 'g38_ui' into devel 2021-12-23 03:17:38 +09:00
Hide_D 0adaf7d6c4 fix: 되돌아가기 위치 문제 수정 2021-12-23 03:16:24 +09:00
Hide_D 452c340112 Merge branch 'g38_ui' into devel 2021-12-23 03:06:57 +09:00
Hide_D ffabe96b15 feat: processing 검색 켬/끔 추가 2021-12-23 03:03:43 +09:00
Hide_D 3fc1183be6 feat: processing 체계를 일괄 변경 2021-12-23 01:34:45 +09:00
Hide_D de85ac9237 feat(WIP): 장비매매
- 초성 검색을 일원화
2021-12-23 00:48:53 +09:00
Hide_D 86dd573e2f feat(WIP): processing 숙련전환, 불가침제의 2021-12-22 21:15:26 +09:00
Hide_D b0c7d60d5a feat(WIP): 증여,헌납,백성동원,수몰,천도,초토화,허보 2021-12-22 02:23:06 +09:00
Hide_D 507fa102b9 refac(WIP): 파일 위치 변경 2021-12-22 02:06:40 +09:00
Hide_D 95f079474e feat(WIP): processing 물자원조
- nations, nationList를 nationList로 통합
2021-12-22 01:01:06 +09:00
Hide_D f951f313d2 feat(WIP): processing 계략 세부
- 기타 파일 잔여 코드 제거
2021-12-22 00:24:51 +09:00
Hide_D 50e11f22a1 feat(WIP): processing 선양, 장수대상임관 2021-12-22 00:10:02 +09:00
Hide_D 6dac344a35 feat(WIP): processing 임관
- 구 css 코드 남은것 해결
2021-12-21 23:19:07 +09:00
Hide_D caf51fdc06 misc: topBar 가로선 제거 2021-12-21 22:06:24 +09:00
Hide_D 7d84d383d6 misc: 징병창 선택 병종 보기 옵션 수정 2021-12-21 22:05:04 +09:00
Hide_D 80d7ad8789 fix: 국가 선택 버그 수정, 몰수 type warning 제거 2021-12-21 21:55:05 +09:00
Hide_D be5dc42eb1 misc: 지도 내 소재 도시 표기 방식 변경 2021-12-21 21:52:34 +09:00
Hide_D c8961f60fa misc: 기본 커맨드 검색모드 끔 2021-12-21 21:06:15 +09:00
Hide_D c757687eba feat: 선전포고 구현 2021-12-21 03:45:33 +09:00
Hide_D dd6d59cf97 feat(WIP): 징병, 모병 페이지 모바일 변경 2021-12-21 03:29:35 +09:00
Hide_D 909f4ec2b7 fix: 선택 할 수 없는 병종 보기 버튼 에러 2021-12-21 03:09:52 +09:00
Hide_D 4bf06d9ee5 feat: process 징병 페이지 2021-12-21 03:04:44 +09:00
Hide_D 587f9fc1ec misc: 500px 모드를 일관되게 적용.
- media-1000px, media-500px 추가
2021-12-21 00:30:29 +09:00
Hide_D 841e5c5395 misc: 동떨어진 파일 제거 2021-12-20 22:36:53 +09:00
Hide_D c383a5cc22 dep: e_lib 디렉토리 정리
- select2 하나 남음
2021-12-20 02:43:22 +09:00
Hide_D 003ea3baa7 dep: quill 제거 2021-12-20 02:26:49 +09:00
Hide_D 0fa98340c1 build: devtool 결과 최적화 2021-12-20 01:59:29 +09:00
Hide_D 64e36f038e feat(WIP): process 등용 등
- ColorSelect 색을 가득 채움,
- ColorSelect 결과값을 둥글게
- procGeneralList의 column 가변형 정의
- 등용 brief 조사 처리 버그 수정
2021-12-20 01:08:08 +09:00
Hide_D 78d95048d5 feat(WIP): processing 건국, 다른 메뉴 UI 통일
- lazy loading은 의미가 없으므로 롤백
2021-12-19 22:50:15 +09:00
Hide_D c47f8dbba3 misc: 외부 UI 안정화.
- 세부메뉴 버튼 변경
- 메인 하단바 여백
2021-12-19 22:43:03 +09:00
Hide_D 2dc206ff56 fix: 추방을 연속으로 실행하면 gennum이 과도하게 깎임 2021-12-19 19:26:43 +09:00
Hide_D 72f7811f3d feat(WIP): processing에서 vue 객체 통합, lazy loading 2021-12-19 17:22:54 +09:00
Hide_D c8146814df misc: 내 도시 위치를 '신경쓰이게' 표시 2021-12-19 04:55:28 +09:00
Hide_D a01e5df650 feat(WIP): processing, 몰수
- 초성에서 Windows 겹받침, Mac 된소리 자음(automata 초성)
- 장수 선택에에서 검은색 테마
- 양 선택기에 숫자 추가
2021-12-19 04:28:44 +09:00
Hide_D 9bd151cdc2 feat(WIP): process 국가선택 추가 2021-12-18 23:14:04 +09:00
Hide_D e2ed918437 feat(WIP): process 국기변경 2021-12-18 19:09:02 +09:00
Hide_D bc658433e2 Merge branch 'devel' into g38_ui 2021-12-18 18:03:06 +09:00
Hide_D db1dd6f3df feat: getRankVar에 RankVar가 없을 경우 기본값 지정 가능
- 토너먼트 값 회수
2021-12-18 17:58:20 +09:00
Hide_D edca481362 feat: typescript JosaUtil 2021-12-18 17:33:54 +09:00
Hide_D bc1ca6274d feat(WIP): processing, 출병 추가
- 장수 선택기 추가
- v-model 안 쓰는 바보짓 수정
- proc 전역 변수를 procRes로 묶음
2021-12-18 16:00:53 +09:00
Hide_D 2335dc7566 fix: MapLeagcyTemplate warning 제거 2021-12-18 14:16:51 +09:00
Hide_D 94ab040693 feat(WIP): processing 출병 2021-12-18 05:08:53 +09:00
Hide_D b4b4678e26 feat(WIP): processing 작업 2021-12-18 05:02:47 +09:00
Hide_D 6c93d2fd85 feat(WIP): processing을 vue로 전환 2021-12-18 04:36:06 +09:00
Hide_D 4ca33cb007 fix: 전투 시뮬레이터 UI 깨짐 수정 2021-12-16 03:34:34 +09:00
Hide_D 96515fd16c fix: 내정보/설정에 툴팁이 해제되어있음 2021-12-16 03:23:36 +09:00
Hide_D d736e2d947 refacor: customCSS 코드 분리 2021-12-16 03:23:11 +09:00
Hide_D 7631d99ce6 game: 척사 강화. 15%p -> 20%p 2021-12-16 03:12:37 +09:00
Hide_D 6ddeed82c0 fix: 500px/1000px 모드 2차 수정 2021-12-16 02:36:50 +09:00
Hide_D ffc8242aae fix: 500px/1000px 모드 설정 2021-12-16 02:32:33 +09:00
Hide_D 2767bf70d9 feat: 내 정보/설정 페이지 반응형, 500px/1000px 설정 2021-12-16 02:26:07 +09:00
Hide_D fa7c7794d0 feat: 상/하단 돌아가기 버튼을 bootstrap으로 변경 2021-12-16 01:56:44 +09:00
Hide_D 015e9e54dc feat: 임시 500px/1000px 모드 추가 2021-12-16 01:53:23 +09:00
Hide_D 7dc9863b49 fix: 지도 옵션 버튼의 초기화 이벤트 시점이 다른 점 수정
- 항상 통제 가능한 localStorage 기준으로 변경
2021-12-16 01:24:41 +09:00
Hide_D f13960a56a game: 토너먼터 자동 참가 시, 능력치에 기반 2021-12-16 01:05:59 +09:00
Hide_D ba6370d206 fix: AI 전쟁 상태 정의를 다시. 2021-12-16 01:02:41 +09:00
Hide_D 32fd8c481a fix: 토너먼트 warning 제거 2021-12-15 22:27:37 +09:00
Hide_D e9264e6f13 scenario: 애니집결 업데이트 2021-12-15 20:10:04 +09:00
Hide_D 93e6a056d4 game: 저격 버프, 견고 효과 중 저격,필살 너프
- 저격 성공시 증가하는 사기량 증가
  - 전특만, 몇몇 유니크 제외
- 저격이 성벽에도 발동
  - 사기 상승만 추가, 성벽 너프 없음
- 견고 효과 변경
  - 필살 무효 -> 필살 확률 20% 감소
  - 저격 무효 -> 저격은 받지만 부상 무효
2021-12-15 16:34:07 +09:00
Hide_D 3610f2cbd4 fix: 기본 DummyGeneral에 NPC 타입 3번 부여 2021-12-15 12:01:50 +09:00
Hide_D 0c51544e2e fix: 베팅 결과에서 실제 장수가 아닌 총합(0번)을 가져오는 버그 수정 2021-12-15 12:00:54 +09:00
Hide_D 8f1f477054 fix: mergeQueryColumn의 기본 값에 npc 추가 2021-12-15 11:57:45 +09:00
Hide_D 0b72925f09 fix: 토너먼트 값에서 npc를 안받아옴 2021-12-15 09:09:35 +09:00
Hide_D 9fb477facc game: NPC국이 접경이 사라져도 5개월가량은 기다림 2021-12-15 03:34:49 +09:00
Hide_D 3c474e5551 game: 반환은 4개월 이전에도 이루어지도록 수정 2021-12-15 03:19:02 +09:00
Hide_D 9217f0aaf5 game: 시작한지 4개월째부터 유산으로 유니그 획득 가능 2021-12-15 03:13:24 +09:00
Hide_D dddf4ccf6e build: webpack 캐시를 버전이 바뀌어도 계속 사용하도록 설정 2021-12-15 02:28:47 +09:00
Hide_D 4de010cb1e fix: 빙의 장수의 유산 포인트 적용 문제 수정
- 빙의장의 유산 포인트가 천통시엔 미적용.
- NPC 시절 베팅 결과가 반영되는 오류
  - 베팅횟수+0, 베팅성공+1, 베팅금액+ 문제
2021-12-15 02:15:38 +09:00
Hide_D d2ed7a4a80 Merge pull request 'feat: webpack 빌드 통일, TipTap 에디터 적용' (#201) from unifyBuildPath into devel
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/201
2021-12-14 02:24:17 +09:00
Hide_D 311d5c42a8 fix: 메인페이지, 임관권유 페이지에 적용 2021-12-14 02:05:59 +09:00
Hide_D 3c6a884663 feat: TipTap 이미지 적용 2021-12-14 02:03:05 +09:00
Hide_D 1bfd0018b1 feat(WIP): tiptap 에디터 기능 구현 2021-12-13 21:45:49 +09:00
Hide_D 2c3a9b93c7 feat(WIP): 새 에디터 2021-12-13 03:24:14 +09:00
Hide_D 0961220fdd feat: 국방, 임관메시지 에디터에 TipTap 적용 2021-12-13 02:03:54 +09:00
Hide_D c8b2f28c7c build: esbuild-loader에서 es2021 2021-12-12 21:55:20 +09:00
Hide_D 3f7cc163ec refac: vue 파일 구조 변경 2021-12-12 21:48:48 +09:00
Hide_D 8ede84c176 build(WIP): printDist를 모든 코드에 적용
- 현재 summernote 미작동
2021-12-12 19:26:27 +09:00
Hide_D 6a7f62f2c2 build(WIP): php단에서 변경된 dist_js에 맞게 js,css 로드
- fix: webpack 출력물 문제
- webpack splitChunks 파일 통일
2021-12-12 16:33:20 +09:00
Hide_D 0b82024caa fix: 에러 없이 emit 된 경우에만 빌드 완료 표지 출력 2021-12-12 15:28:52 +09:00
Hide_D fd057ebb05 build(WIP): 빌드 결과물을 서버 주소에 관계없이 통일 2021-12-12 13:52:55 +09:00
Hide_D 47e6958446 feat: 글꼴 속성 시험 적용 2021-12-12 12:53:50 +09:00
Hide_D 690fe46931 fix: 추가 수정 2021-12-11 23:22:12 +09:00
Hide_D 10ec7b55d0 fix: 등용 수락이 불가능한 버그 수정 2021-12-11 23:20:32 +09:00
Hide_D 5079db5ceb fix: showErrorLog 페이지 디스플레이 수정 2021-12-11 23:10:34 +09:00
Hide_D dd4f664724 fix: 유산 포인트 반영시 ownerID가 아니라 generalID 를 사용하는 버그 2021-12-11 22:56:08 +09:00
Hide_D 932e8ca093 fix: 상단 버튼 안되는 버그 수정 2021-12-11 14:05:06 +09:00
Hide_D 193e6eb9ca fix: 메인페이지 갱신 버튼이 일부만 동작하는 버그 2021-12-11 13:52:00 +09:00
Hide_D e28b878a68 fix: 베팅에 사용할 값을 가져오지 못하는 버그 수정 2021-12-11 13:19:46 +09:00
Hide_D 4d6f64cf96 build: 약간 변경 2021-12-11 12:44:51 +09:00
Hide_D 6441fc09e4 misc: scss 파일 정리 2021-12-11 12:12:16 +09:00
Hide_D d8c54b4632 fix: main 페이지가 vue로 통합되었으므로 printCSS 변경 2021-12-11 11:55:17 +09:00
Hide_D a8f2c9787d misc: main의 외부 초기화 코드를 내부로 이동 2021-12-11 11:52:02 +09:00
Hide_D dfb10c1b44 fix: initTooltip과 bootstrap-vue-3 충돌 문제 해결
- 기타 data-bs 안붙은거 마저 수정
2021-12-11 11:37:41 +09:00
Hide_D 95bd5b539f fix(WIP): bootstrap4 잔여 코드 수정 중
- 이상하게도 ingame에서 bootstrap이 충돌 중
2021-12-11 04:45:39 +09:00
Hide_D c811a56557 fix: 비급 위압이 갱신된 위압을 따르지 않음 2021-12-11 03:31:09 +09:00
Hide_D 5892ddcad8 misc: 줄어튼 선택기에 맞게 갱신버튼 이동 2021-12-11 03:30:01 +09:00
Hide_D 111a81766e misc: bootstrap4 toast 사용코드 제거 2021-12-11 03:21:47 +09:00
Hide_D 5819045a01 misc: 여백을 위해 ReservedCommand 16->15 2021-12-11 02:57:32 +09:00
Hide_D b8f19e11ff Merge pull request 'refactor: bootstrap4 => bootstrap5' (#200) from no_bootstrap4 into devel
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/200
2021-12-11 02:53:55 +09:00
Hide_D d3c73579d9 refactor: goodbye bootstrap4 2021-12-11 02:50:24 +09:00
Hide_D 5f001ee091 fix: bootstrap5 modal 2021-12-11 00:30:01 +09:00
Hide_D 741c67c7cb fix: bootstrap5 modal 2021-12-11 00:28:59 +09:00
Hide_D 9456406009 fix: login에서 modal을 Bootstrap5 Modal로 2021-12-11 00:20:11 +09:00
Hide_D 8464f96e40 refactor: common_ts 분리 후 일괄 로드 2021-12-11 00:07:59 +09:00
Hide_D 3c23e0fb93 fix: webpack image.ext revert 2021-12-10 23:33:39 +09:00
Hide_D 18807a642a fix: 앞선 refactor에서 경로 문제 수정 2021-12-10 23:12:35 +09:00
Hide_D 975f77e907 refactor: 상대경로를 @ 시작 절대경로로 2021-12-10 22:34:14 +09:00
Hide_D bd42042a61 refactor(WIP): scss, ts 공통 파일 묶기 2021-12-10 21:45:02 +09:00
Hide_D 9134a7d9f6 fix: lint error fix 2021-12-10 02:55:53 +09:00
Hide_D 53d65c31db dep: update packages 2021-12-10 02:53:12 +09:00
Hide_D 612f15ebad feat(WIP): gateway bootstrap 호출 제거 진행
- 메인페이지 미동작
2021-12-10 02:47:10 +09:00
Hide_D 33378c96ec dep: 이전 버전들과의 호환성을 위해 bootstrap5 명명 유지 2021-12-10 02:28:13 +09:00
Hide_D 703e2f51be feat(WIP): bootstrap 5 tooltip 적용
- bootstrap4 용의 popper.js 제거
- jquery기반 bootstrap tooltip 제거
2021-12-10 02:26:08 +09:00
Hide_D 7d8fa7f1c4 dep(WIP): bootstrap4 1차 제거 2021-12-10 02:02:38 +09:00
Hide_D 62089ef2c2 fix: 수비자 숙련 변경 2021-12-09 23:58:57 +09:00
Hide_D 1d946aa525 game: 수비자의 상대 병종을 0에서 0.1로 변경, 공격자 대비로는 10% 2021-12-09 01:59:04 +09:00
Hide_D 19b62a632b game: 궁병 회피 살짝 너프 2021-12-09 01:32:17 +09:00
Hide_D cbd5b7fc5e game: 백이병 추가
- 성도 특수 병종
- 숨겨진 상성 수치
2021-12-09 01:00:27 +09:00
Hide_D 58673fb385 feat: (예약)plock을 세부 구분할 예정 2021-12-09 00:51:10 +09:00
Hide_D 26ea6a6c69 fix: KVStorage의 기본 상태가 turnOnCache가 아니었던 점 수정 2021-12-09 00:36:15 +09:00
Hide_D 1727d34853 game: 빙의장도 유산 획득이 가능하도록 수정
- 유산 실 반영 시점을 은퇴, 천통 시점으로 변경
2021-12-09 00:26:47 +09:00
Hide_D fc3b854add fix: 빙의가 불가능한 버그 수정 2021-12-09 00:01:20 +09:00
Hide_D dba8e5d699 feat: 턴 선택기 실행 후 초기화시, 이전 턴 기억 2021-12-08 21:22:52 +09:00
Hide_D f3df6f7202 feat: 검색 모드 켬/끔 추가 2021-12-08 21:01:16 +09:00
Hide_D 3cbf1eba30 fix: AI 유저장 포상 버그 수정 2021-12-08 01:54:00 +09:00
Hide_D 4623cfbe06 fix: webp가 업로드 가능하나, 메시지 표기가 누락된 버그 수정 2021-12-08 01:38:23 +09:00
Hide_D d4d8e0045b misc: 턴 선택기에 기본턴 선택. 다른 턴 선택시 무효화. 2021-12-08 01:36:59 +09:00
Hide_D ea4f1643d4 misc: 하단 바 세부 항목 크기 확대 2021-12-08 01:31:34 +09:00
Hide_D 5a2ea3496e misc: 턴 입력이 아무것도 없으면 1턴 2021-12-08 01:23:58 +09:00
Hide_D 6dd77dd632 misc: 하단 바, type2 버튼에 밑줄 2021-12-08 01:19:29 +09:00
Hide_D d4279b0cb7 misc: 턴선택이 없을 경우 안내 2021-12-08 01:12:03 +09:00
Hide_D 601222a60d misc: 턴선택기 기본값을 무효화. 2021-12-08 01:11:14 +09:00
Hide_D 9c541735b7 fix: initial-scale=1 제거 2021-12-08 01:06:56 +09:00
Hide_D 858f7139ff fix: 구 sidebar 코드 제거 2021-12-08 01:01:25 +09:00
Hide_D a326ad3c66 fix: 풀모드 메시지함 grid 깨짐 수정 2021-12-08 00:55:54 +09:00
Hide_D 33751a06fe feat: 스마트폰용 하단 바 구현, 버튼 템플릿 변경 2021-12-08 00:24:40 +09:00
Hide_D 8cbe92ca46 fix: anchor 이동에서 #을 남기지 않도록 2021-12-07 02:27:42 +09:00
Hide_D 5587a358ce feat: 초성 검색에서 '알파벳' 대신 검색 추가 2021-12-07 02:03:10 +09:00
Hide_D 40b52dd517 fix: auto500px 가로모드 미설정 버그 수정 2021-12-07 01:54:22 +09:00
Hide_D 5424869d8e Revert "misc: auto500px 필요없음."
This reverts commit 2b5f38ca52.
2021-12-07 01:44:36 +09:00
Hide_D 68a2534d1b misc: auto500px 필요없음. 2021-12-07 01:38:26 +09:00
Hide_D 1699190334 misc: 스마트폰 모드에서 '명령으로' 추가 2021-12-07 01:22:09 +09:00
Hide_D d86d96acc1 misc: 초기 스마트폰 크기 관련 수정 2021-12-07 01:19:38 +09:00
Hide_D f70dbf9cf3 fix: 12px -> 12.5px 2021-12-07 01:01:39 +09:00
Hide_D 33a1681536 fix: font 정렬, 전체선택->턴 선택 2021-12-07 00:51:20 +09:00
Hide_D fcb8da95ca misc: 기본 글꼴 크기를13px -> 14px 2021-12-07 00:37:23 +09:00
Hide_D e8148ab4dc misc,dep: 기본 글꼴을 Pretendard로 일괄 적용용 2021-12-07 00:27:50 +09:00
Hide_D c14f06615e fix: 하단 버튼이 container 밖으로 벗어나는 문제 수정 2021-12-05 23:58:06 +09:00
Hide_D 1c0b28eacd game: 랜덤 임관 밸런스 수정 2021-12-05 23:47:56 +09:00
Hide_D d317a84b09 feat: 턴 선택기에 복합 커맨드 선택 적용 (#199)
- vue-multiselect 기반
- 초성 검색
- 이득, 불리 표기
- 불가 표기
- 선택후 단축 표기

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/199
Co-authored-by: hide_d <hided62@gmail.com>
Co-committed-by: hide_d <hided62@gmail.com>
2021-12-05 23:02:27 +09:00
Hide_D 3972cf0194 fix: summernote 최신 버전에서 jQuery require 우회 2021-12-05 03:32:48 +09:00
Hide_D 6d408ac2b1 dep: vue-select 4.0 추가가 2021-12-04 14:11:37 +09:00
Hide_D 8338f8aaa0 misc: 턴선택기에서 모두 선택, 당기기, 미루기 위치 조절절 2021-12-04 13:49:59 +09:00
Hide_D fbd0561420 refac: 500px 모드 변환기 분리 2021-12-04 11:42:26 +09:00
Hide_D de854cc02c misc: 턴선택기 실행버튼 크기 50% 증가 2021-12-04 11:12:42 +09:00
Hide_D 822e161e2e misc: 500px 레이아웃 순서 변경 2021-12-04 02:11:59 +09:00
Hide_D b60bf9fdf9 fix: float-tabs가 sticky보다 아래에 오는 버그 수정 2021-12-04 01:13:50 +09:00
Hide_D 14b0a043d4 feat: 500px 모드에서, 메시지 입력기가 메시지창을 쫓아감 2021-12-04 01:07:05 +09:00
Hide_D a2f5d66597 misc: 500px 레이아웃 구성 변경 2021-12-04 00:42:51 +09:00
Hide_D c02bc26799 misc: 갱신/로비로 버튼 위치 이동 2021-12-04 00:10:41 +09:00
Hide_D 932afec74a fix: buttonPlate에 gap 추가 2021-12-03 23:44:55 +09:00
Hide_D 3da67e7d97 fix: 사령부 ajax 모드 2021-12-03 16:03:02 +09:00
Hide_D 0c95b958aa feat: 메인페이지 화면비 자동 조정 2021-12-03 16:00:38 +09:00
Hide_D 8895ac329a fix: 메인 화면 오동작 요소 수정
- 설문조사 항목 표기
- 설문조사 항목 marquee로 틀어짐(제거)
- 1000xp 모드에서 도시 툴팁 가려지는 문제 수정정
2021-12-03 15:26:45 +09:00
Hide_D cf0416e976 fix: nation color-code #330000 2021-12-03 02:18:13 +09:00
Hide_D f8f3e4d9e8 feat: 500px 모드 나머지 최적화 2021-12-03 02:07:34 +09:00
Hide_D d6bee9aa6d fix: 메인 페이지, 장수 동향, 개인 기록, 중원 정세 띠 2021-12-03 00:18:18 +09:00
Hide_D 2d5e99a0d6 feat: 500xp 모드에서 오른쪽 고속 이동 툴바 2021-12-03 00:14:22 +09:00
Hide_D 97b71347a6 fix: 500px 모드를 확실하게 명시 2021-12-02 22:01:29 +09:00
Hide_D 10e3a0814f misc: 메시지 받아오는 갯수 감소 2021-12-02 21:41:33 +09:00
Hide_D f909df204a fix: .toolbarButton2 2021-11-30 02:00:35 +09:00
Hide_D 661e6cc5da misc: ReservedCommand 색을 약간 수정
- 딱히 어룰린다는 느낌은 여전히 없다.
2021-11-30 01:58:42 +09:00
Hide_D b2b911ec81 fix: 메인페이지 '이전 메시지 불러오기'를 전체 너비로 2021-11-30 01:44:02 +09:00
Hide_D f238077944 fix: 메인 페이지 시나리오 표기, 줄 바꿈 2021-11-30 01:40:49 +09:00
Hide_D 3c930dacb8 feat: 나머지 메인 버튼도 lumen 버튼으로 통일 2021-11-30 01:38:07 +09:00
Hide_D 6dcb46c0b8 feat: commandButton을 lumen 버튼으로 2021-11-30 01:09:37 +09:00
Hide_D 27c7a5a3ad feat: 국가별 색 버튼을 lumen button profile에 맞춰 작성 2021-11-30 00:54:08 +09:00
Hide_D 846bdfdc88 feat(in-progress): 턴선택기 연월에 select, 강조 표기 2021-11-29 01:19:25 +09:00
Hide_D a2026cb3fd feat(in-progress): 턴 선택기에서 select와 toggle 분리 2021-11-29 01:17:36 +09:00
Hide_D 06fa539293 feat(in-progress): 커맨드 목록 UI/UX 정리 2021-11-29 01:00:52 +09:00
Hide_D 752f69d3ef misc: common.css를 bootstrap5를 포함한 css로 변경 2021-11-28 23:09:37 +09:00
Hide_D 897997b8ac feat: 메인화면의 도시정보를 500px, 700px 가변 2021-11-28 22:22:52 +09:00
Hide_D 526fa11c20 fix: 500px 지도모드에서 tooltip 위치 조정 2021-11-28 19:24:31 +09:00
Hide_D 8eda98ff4c feat(in-progress): 메인메뉴 지도를 500px 모드에 맞게 수정 2021-11-28 18:54:37 +09:00
Hide_D 99d7a26b98 dep: bootstrap5 custom 조합 darkly + lumen 2021-11-28 18:03:18 +09:00
Hide_D 0aaadf9536 feat: 턴 선택기를 vue 기반으로 변경 2021-11-28 01:57:46 +09:00
Hide_D 9adcbecce4 feat(in-progress): 턴 조작기를 vue로 분리 2021-11-27 15:40:31 +09:00
Hide_D 6605a84f2c dep: bootstrap 2021-11-27 15:40:00 +09:00
Hide_D 6c9510d8f4 fix(in-progress): viewport width를 500으로 진행하기로 2021-11-27 02:15:39 +09:00
Hide_D 03a62dc23f fix(in-progress): viewport width를 360px 폰에서 맞게 수정 2021-11-27 02:10:08 +09:00
Hide_D 93efacbef5 feat(in-progress): 메인페이지 기본 반응형 전환.
- full, half 모드
2021-11-27 01:53:00 +09:00
Hide_D b6b28de8e2 feat(in-progress): 메인 페이지에서 table 제거 2021-11-26 21:40:55 +09:00
Hide_D faaed40b39 fix: 비쟁장에 쟁장 공식이 섞여서, 최소 포상 금쌀이 꼬이는 문제 수정 2021-11-26 19:53:12 +09:00
Hide_D 6b035f64d2 fix: branch 못 알아낸 건 unknown으로 하기 2021-11-26 19:11:50 +09:00
Hide_D 9f049dcb18 fix: branch 가져오는 표기법 다시 수정 2021-11-26 19:05:59 +09:00
Hide_D 0141449e4f fix: git ignore 빠진부분 수정정 2021-11-26 19:03:34 +09:00
Hide_D 4ce49f259d fix: origin branch를 제대로 파싱하지 못하는 버그 수정 2021-11-26 18:56:04 +09:00
Hide_D 0f35569e05 fix: 삭제된 기능인 '폐쇄중 로그인'을 UI에서도 제거 2021-11-26 18:48:00 +09:00
Hide_D 1c4dabed72 feat: 버전 표기에 branch명 같이 표기 2021-11-26 18:44:18 +09:00
Hide_D 38114c0639 game: 수비자 피살 숙련도 0, 사살 숙련도 0.9->0.8 2021-11-26 17:42:50 +09:00
Hide_D 527c8370f1 fix: 권한 없는 유저가 수락 버튼을 누를 시, 아예 메시지가 사라지는 버그 수정 2021-11-20 14:00:01 +09:00
Hide_D 6a9a57e2bc fix: '최소 전투 가능 병력 수'를 매우 높여 출병 금지가 가능한 문제 수정 2021-11-20 00:37:07 +09:00
Hide_D 7b6f1b510e feat: 전쟁 금지/허가 여부 횟수 제한 부활 2021-11-19 23:43:00 +09:00
Hide_D 94bc7547d6 game: 출병은 일반내정보다 먼저여야함 2021-11-19 23:10:32 +09:00
Hide_D 5a4552aaff fix: 방어력 증가 세팅이 잘못됨. 2021-11-17 23:08:57 +09:00
Hide_D 06e314d301 game: 보병 수비시 방어력 5% 증가 2021-11-17 23:00:40 +09:00
Hide_D 8bead301ef game: NPC 베팅 판돈 스케일 증가가 2021-11-16 23:45:33 +09:00
Hide_D 6282445f7d feat: 토너먼트 베팅에서 모든 NPC가 10원씩 베팅함
- 추가로 베팅 공지
2021-11-16 23:12:32 +09:00
Hide_D bf244533f7 game: 국력, 랜임 계산식에서 유저장 전투력 계수를 NPC의 1.5로 설정 2021-11-16 22:40:47 +09:00
Hide_D 5ebfaf24ee feat: 토너먼트 비중을 강제로 조정 2021-11-16 22:18:29 +09:00
Hide_D 0c0283dc02 feat: '능동 행동 수' 유산 포인트 추가
- 거병, 건국, 방량, 선양, 모반
- 임관, 랜덤임관, 장수대상임관, 등용수락, 하야
- 출병(500명 이상, 훈사 7070 초과)
- 인재탐색 성공(난도에 따라 추가 보정)
- 첩보(예외, 0.5)
- 증축, 감축, 국기변경, 국호변경, 천도성공
2021-11-16 21:38:55 +09:00
Hide_D 375b08be87 feat: NPC정책 최대 포상량 지정 2021-11-16 20:45:16 +09:00
Hide_D cbc8f94b0a game: 국고가 2000 밑으로 가더라도 무조건 물자조달만 하지는 않게 수정정 2021-11-16 20:01:50 +09:00
Hide_D bdac8d163d game: 전특 요구 포인트 감소, 버프 요구 포인트 감소 2021-11-16 19:37:16 +09:00
Hide_D 1f61f37841 fix: 토큰 갱신 시 UserID가 잘못된 버그 수정정 2021-11-14 22:55:37 +09:00
Hide_D 51d523ae72 game: 국력 계산식에 랜덤임관 계산식 일부를 반영 2021-11-14 18:45:28 +09:00
Hide_D 3f9e4962e6 fix: 서버 정지로 의심되는 opcache_reset 해제
- 현재 validate timestamp를 켜서 사용하도록 유도
2021-11-14 13:31:30 +09:00
Hide_D f8fc4fe56b misc: 미활용 함수/상수 제거 2021-11-14 13:20:19 +09:00
Hide_D fb64b7e412 feat: NPC 거병, 이동 로직 대폭 개선
- 근처에 세울 도시를 보고 거병
- 원하는 도시를 정하고 그 도시를 향해 이동
2021-11-14 05:06:39 +09:00
Hide_D 3209cfbc45 fix: warning 제거거 2021-11-14 04:15:04 +09:00
Hide_D 8a99476136 game: 랜덤임관 평가 기준 변경
- 전투 기준을 총 전투 대신 대인 전투로
- 내정 능력에 무력, 지력 비율 반영영
2021-11-14 02:51:40 +09:00
Hide_D eb80f8d111 feat: 자율행동 표기를 휴식(자율행동)으로 변경 2021-11-14 02:47:53 +09:00
Hide_D afde3ce54d game: 랜덤임관 가중치 변경 2021-11-14 02:39:09 +09:00
Hide_D c4b61fec17 game: 작위 보상에도 최대 보유 유니크 수 적용 2021-11-14 00:50:09 +09:00
Hide_D 0b74abf300 game: 랜덤임관 로직에 전투력과 내정능력을 적극적으로 반영영 2021-11-14 00:46:46 +09:00
Hide_D e6c3c9f1d4 fix: 자율턴에서 '월' 표기 빠짐 2021-11-13 16:48:49 +09:00
Hide_D 4e7560b4ed feat: 자율행동 휴식을 명시적으로 자율행동으로 표기 2021-11-13 16:37:47 +09:00
Hide_D 542491b278 feat: 자율턴 한계 표기 2021-11-13 16:33:11 +09:00
Hide_D d36439355d fix: 자율행동턴 시간 제한이 동작하지 않던 버그 수정 2021-11-13 16:05:03 +09:00
Hide_D 4a80815b39 game: 기간별 최대 유니크 획득 수 변경경 2021-11-13 02:25:52 +09:00
Hide_D 6dc57f2566 fix: 자동로그인 과정 버그 수정정 2021-11-11 00:37:29 +09:00
Hide_D 07e8511ce1 game: snipe_combat 제거거 2021-11-08 23:31:56 +09:00
Hide_D 8e927831f5 fix: dummySession 인자 수정정 2021-11-08 23:27:37 +09:00
Hide_D 2c533d2ab3 dep: package update 2021-11-08 16:10:01 +09:00
Hide_D 38208750e7 game: 수비자는 전멸 시 증가하는 사기량을 50%만 적용 2021-11-08 15:20:23 +09:00
Hide_D df14d7c306 game: 반계 효과 유니크 시도 확률 반감 2021-11-08 15:16:15 +09:00
Hide_D b3612db7d2 game: 피장파장 턴을 60턴 기준으로 변경(72턴 동일) 2021-11-08 15:11:24 +09:00
Hide_D 8d90da659e game: 피장파장 딜레이를 최소 72턴으로로 2021-11-08 15:10:45 +09:00
Hide_D f8ddbc0622 game: 종횡가 전략 딜레이를 1/2에서 3/4으로로 2021-11-08 15:08:21 +09:00
Hide_D 673b7054aa 자동 로그인 (#196)
자동 로그인 구현

- login_token 테이블
- reqNonce -> loginByToken
- sha512(token + nonce)

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/196
Co-authored-by: hide_d <hided62@gmail.com>
Co-committed-by: hide_d <hided62@gmail.com>
2021-11-08 04:23:07 +09:00
Hide_D 1472cbf257 game: 장비매매 시 도구 유니크 덮어지지 않게 2021-10-29 02:21:53 +09:00
Hide_D d806935c58 fix: 작위 보상이 군주인 경우 반영이 안되는 버그 수정 2021-10-27 02:04:10 +09:00
Hide_D 6b56eb79e1 fix: 403 페이지 redirect 버그 수정 2021-10-27 01:29:19 +09:00
Hide_D d2aea16744 balance: 초기 +5%, -2% 추가가 2021-10-16 21:50:41 +09:00
Hide_D bb800f032e balance: 쌍무쌍 적용 불가, 무쌍 중반 이후 대폭 너프프 2021-10-16 21:22:28 +09:00
Hide_D 64b9f9443e fix: 랜덤 임관 비중 계산식에서 u장 포함 2021-10-14 02:01:12 +09:00
Hide_D fd2d3a0e06 fix: 창 닫기가 필요한 창은 window.open으로 열어야함 2021-10-14 01:12:21 +09:00
Hide_D 08d678bdb8 fix: CreateManyNPC에서 npcCount가 0이면 fillCnt가 무시 2021-10-14 00:37:08 +09:00
Hide_D 418007e572 balance: 초반 NPC 생성 시 모든 국가를 채울 수 있을 정도로는 제공 2021-10-14 00:36:06 +09:00
Hide_D 4a1bccdf75 balance: 탈취량을 도시 내정치에 기반하도록 변경 2021-10-14 00:16:44 +09:00
Hide_D 00c0b59e9d balance: 랜임 시 의병장, 집합장 카운트는 제외 2021-10-13 02:05:04 +09:00
Hide_D ac82c8ff0b fix(misc): 상대가 치료시 '붉게' 표기 2021-10-13 02:01:41 +09:00
Hide_D f4bef8a090 fix: 인탐, 의병에서 숙련도가 지정되지 않는 버그 수정 2021-10-13 01:56:06 +09:00
Hide_D d8a1055bff fix: DummyGeneral에 유산 관련 포인트 함수가 누락된 부분 수정 2021-10-12 02:25:24 +09:00
Hide_D d672ce4d80 fix: set_error_handler를 못잡는 문제 해결
기타 소소한 버그
- 피장파장 입력시 warning을 계속 일으키는 버그(동작 문제는 없음)
- 토너먼트에서 승리,패배,무승부 외에 MustNotBeReachedException이 throw되지 않음(동작 문제는 없음)
2021-10-12 01:43:54 +09:00
Hide_D 43ec361d03 dep: update phan 2021-10-12 01:36:02 +09:00
Hide_D c3c99c5f76 fix: 공격자 전투력 판정 문제 수정 2021-10-12 01:31:16 +09:00
Hide_D eb1e1421ab fix(misc): phan 2021-10-12 01:30:37 +09:00
Hide_D e8a1d87919 Merge pull request 'balance: 무쌍 너프, NPC 출병 금지 불가' (#195) from balance_210923 into devel
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/195
2021-10-10 13:30:01 +09:00
Hide_D 921ba6811d balance: 무쌍 너프, NPC 출병 금지 불가 2021-09-23 03:59:08 +09:00
Hide_D 906dd241b4 fix: RootDB template 2021-09-23 03:08:49 +09:00
Hide_D 3f0cd2ad64 fix: illuminate 2021-09-21 03:13:07 +09:00
Hide_D 41420d1954 Illuminate: ready. (critical)
- DB에서 illuminate를 가져올 수 있도록 설정
- 업그레이듵 불가, RootDB, DB를 직접 수정해야함
2021-09-21 03:06:42 +09:00
Hide_D 6e5a72b170 fix: 자동 사령턴 조정이 되지 않는 버그 2021-09-19 15:44:49 +09:00
Hide_D 4b19e6aec8 fix: 명예의 전당 검색 2021-09-19 13:38:40 +09:00
Hide_D 58572cbc36 scenario: 쿠키런 킹덤 임시 구현 2021-09-19 03:03:05 +09:00
Hide_D 096d5766bf conf: vue-style-loader에 esbuild-loader적용 2021-09-18 04:53:26 +09:00
Hide_D f5c5b56492 dep: babel-loader + ts-loader => esbuild-loader 2021-09-18 04:31:31 +09:00
Hide_D 69c69d63e6 dep: package upgrade 2021-09-18 03:52:27 +09:00
Hide_D 3fd8b21867 misc: lint warning, 불필요 파일 정리 2021-09-18 03:49:04 +09:00
Hide_D 8660e8cd85 fix: NPC포상 설정 메시지 수정 2021-09-18 03:42:20 +09:00
Hide_D 8458f725f2 fix: 사망 시 유산 포인트 관련 환불/초기화가 없는 문제 2021-09-18 03:36:08 +09:00
Hide_D 366678c965 fix: 장수 생성창 보이기/숨기기, 턴 시간 고정 표기 수정 2021-09-18 02:49:47 +09:00
Hide_D 336b5668db fix & inheritAction: 랜덤 유니크 습득시 환불 가능하게 수정 2021-09-18 00:15:00 +09:00
Hide_D 55886269ea inheritAction: 설문조사에서는 특정 유니크 구입 기능 해제 2021-09-18 00:06:20 +09:00
Hide_D 0b3698595b fix: hash -> gitHash 2021-09-17 23:40:47 +09:00
Hide_D 05e43a39db fix: 턴 초기화, 전특 초기화 표기 방식 변경 2021-09-17 23:37:53 +09:00
Hide_D 5737ad3db2 fix: 턴 초기화, 특기 초기화 포인트 안내가 1스텝 늦음 2021-09-17 23:34:33 +09:00
Hide_D 4ac174eb9a fix: 반계시도에는 구분 코드가 동작하지 않았음 2021-09-17 23:17:13 +09:00
Hide_D 895eec10b4 fix: 비급 반계가 전특 반계와 같이 동작하지 않는 버그 수정 2021-09-17 23:07:45 +09:00
Hide_D e0d891e89a fix: 재야일 때에는 임관 년도 증가하지 않도록 2021-09-17 03:14:14 +09:00
Hide_D adf7734b85 fix: 생성하자마자 임관 1년차로 나오는 문제 수정 2021-09-17 03:12:38 +09:00
Hide_D 5362be9c21 inheritPoint: 로그 기록 2021-09-17 02:39:11 +09:00
Hide_D 847ece52f2 fix: summernote.css 2021-09-16 22:39:19 +09:00
Hide_D 851c59d22c fix: 유저전투장 긴급포상 쌀 2021-09-16 22:37:31 +09:00
Hide_D 0669534bba fix: 궁 유니크 저격 계수 2021-09-16 22:24:29 +09:00
Hide_D 05db47e62a fix: 설문조사에서 환불 불가능한 문제 수정 2021-09-16 22:06:57 +09:00
Hide_D 4a0e608d1c fix: itemTrials 삭제 후 통째로 array가 비면 array도 마저 삭제 2021-09-16 22:00:35 +09:00
Hide_D 45fe73af86 fix: eventColumn에 aux 추가 2021-09-16 21:47:32 +09:00
Hide_D 4d9fcd657f fix: vote에서 aux 2021-09-16 21:43:37 +09:00
Hide_D a057deb0fe fix: 유니크를 얻는 턴이 아니더라도 환불은 하도록 수정 2021-09-16 21:38:43 +09:00
Hide_D 4766210a7d 랜임 실패시 실행 턴. 요양 -> 인탐 2021-09-16 21:24:52 +09:00
Hide_D fd26aae6d3 schema 변경 2021-09-16 04:13:34 +09:00
Hide_DandGitea c5c092cc8e Join: 양식 일부 수정 2021-09-15 19:06:15 +00:00
Hide_DandGitea 58c0a21d90 fix: 턴 시간 변경 코드 2021-09-15 19:06:15 +00:00
Hide_DandGitea 8dc567f966 fix: LazyVarUpdate unset 2021-09-15 19:06:15 +00:00
Hide_DandGitea 942b2752f5 fix: previous inheritPoint 지정값 버그 2021-09-15 19:06:15 +00:00
Hide_DandGitea b9259353f4 misc: layout 2021-09-15 19:06:15 +00:00
Hide_DandGitea 86c614dd40 inheritAction: UI 1차 완성 2021-09-15 19:06:15 +00:00
Hide_DandGitea 1a010a16a9 miisc: 간격 조절 2021-09-15 19:06:15 +00:00
Hide_DandGitea d5b5726b1e InheritAction: UI 턴 초기화, 전투 특기 초기화, 랜덤 유니크
- 턴 초기화에 버그가 있는듯?
2021-09-15 19:06:15 +00:00
Hide_DandGitea d06f3b6bdf inheritStore: 버프/디버프 구매 UI 2021-09-15 19:06:15 +00:00
Hide_DandGitea 97a28f716c inheritAction: 특정 전특 획득 2021-09-15 19:06:15 +00:00
Hide_DandGitea f54bdfcea0 Inherit: Action 완료? 2021-09-15 19:06:15 +00:00
Hide_DandGitea 5958c4b0ba InheritAction: 유니크 입찰, 랜덤 아이템 2021-09-15 19:06:15 +00:00
Hide_DandGitea 7c3db881c7 dep: bootstrap-vue-3 추가
- 아직 없는 기능이 많으므로 단순 출력은 CoreUI Vue 동시 활용
- 불편..
2021-09-15 19:06:15 +00:00
Hide_DandGitea 51ee2e1b2c misc: License 2021-09-15 19:06:15 +00:00
Hide_DandGitea baa813004b fix: 메인페이지 지도를 반응형으로 2021-09-15 19:06:15 +00:00
Hide_DandGitea 86b5269d3d inheritPoint: 가입폼
- 기본 동작
- 턴시간에는 버그 있음
2021-09-15 19:06:15 +00:00
Hide_DandGitea 860e6dacac vue: join 생성 완료 메시지 2021-09-15 19:06:15 +00:00
Hide_DandGitea 22025bd89e vue: join 2021-09-15 19:06:15 +00:00
Hide_DandGitea ed9301455d fix: inheritSkill 연산을 위해 aux 필요 2021-09-15 19:06:15 +00:00
Hide_DandGitea 35df84e059 fix: maxPhase 연산에서는 oppose가 없음 2021-09-15 19:06:15 +00:00
Hide_DandGitea 62deebf310 fix: inheritUnique 처리 수정 2021-09-15 19:06:15 +00:00
Hide_DandGitea 7ed4bd5c01 build: join 페이지 준비 2021-09-15 19:06:15 +00:00
Hide_DandGitea c8eb9332b4 misc: 오타 수정 2021-09-15 19:06:15 +00:00
Hide_DandGitea 1df55f9168 api: gateway, ingame 모두 가능하도록 변경 2021-09-15 19:06:15 +00:00
Hide_DandGitea b726c6aa96 유산 포인트로 랜덤 유니크 획득 2021-09-15 19:06:15 +00:00
Hide_DandGitea 0a71962652 balance: 아이템 습득 확률 조정
- 아이템을 소유할 수록, 획득 확률이 기존보다 훨씬 더 낮아진다.
2021-09-15 19:06:15 +00:00
Hide_DandGitea 160946ef74 feat: 아이템 유산포인트로 입찰한 경우 최종적으로 얻는 기능 추가 2021-09-15 19:06:15 +00:00
Hide_DandGitea 1dc67317dc balance: 유니크 아이템을 얻을 수 있는 커맨드 증가
- 강행, 거병, 견문, 군량매매, 귀환, 등용, 물자조달, 이동, 장비매매, 증여, 헌납
2021-09-15 19:06:15 +00:00
Hide_DandGitea 08f4a2e8bf feat: TriggerInheritBuff 구현 2021-09-15 19:06:15 +00:00
Hide_DandGitea 11ffdaa8f7 feat: '계략약화' 특성을 onCalcOpposeStat으로 이동 2021-09-15 19:06:15 +00:00
Hide_DandGitea 0f853303a4 feat: 전투 상대방의 특정 수치를 접근할 수 있는 callback류 생성 2021-09-15 19:06:15 +00:00
Hide_DandGitea d225eb9b16 inheritBuff 준비 2021-09-15 19:06:15 +00:00
Hide_D d926e4b8bc api: 규격 정의 2021-09-12 04:59:34 +09:00
Hide_D 3e2df1d4d8 api: join 2021-09-12 03:22:11 +09:00
Hide_D d670dbf081 feat: 장수 생성 시 유산 포인트에 따라 생성해주는 기능 추가 2021-09-12 02:59:49 +09:00
Hide_D f510a312e3 fix: 은퇴용 유산 포인트 코드가 항상 적용되는 문제 수정 2021-09-12 02:07:29 +09:00
Hide_D 19c44e3d31 fix: 수뇌가 소재 도시에 도시 관련 사령턴(백동 등) 실행시 발생하는 버그 수정
- 백동 + 성수 등등
2021-09-11 19:35:30 +09:00
Hide_D d0848aee67 fix: 가오픈 정보 안나오는 버그 수정 2021-09-10 22:49:30 +09:00
Hide_D f4b4b6811c fix: bootstrap4 package order 문제
- vue3 + bootstrap5 적용 전까진 고통 받아야...
- 당분간 Popper, jQuery가 제대로 export 되었는지 확인 필요
2021-09-10 22:26:14 +09:00
Hide_D fecb3f1f7b fix: gateway tooltip 2021-09-10 21:38:32 +09:00
Hide_D 4c924c0763 fix: 내 정보 로그 추가 불러오기 안되는 문제 수정 2021-09-10 21:05:26 +09:00
Hide_D f1e8d70554 fix: browser support 범위 추가 2021-09-10 18:43:29 +09:00
Hide_D 7d11bc152e fix: 오타 수정 2021-09-09 01:27:29 +09:00
Hide_D fdf0a3135a Merge pull request '스크립트 기반을 WebPack + Babel + TypeScript + Vue3으로 변경' (#191) from ts_convert into devel
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/191
2021-09-09 01:00:42 +09:00
Hide_D 3a1a455c48 [empty] this is a empty commit 2021-09-09 00:59:10 +09:00
Hide_D 3a786e835b Squashed commit of the following:
commit 3ef363a01e
Author: hide_d <hided62@gmail.com>
Date:   Mon Sep 6 02:30:00 2021 +0900

    fix: 은퇴 시 숙련 포인트를 지나치게 많이 받는 문제 수정

commit 9e68bc90c2
Author: hide_d <hided62@gmail.com>
Date:   Mon Sep 6 02:17:56 2021 +0900

    재야에서 도시보기 warning

commit d2590607c2
Author: hide_d <hided62@gmail.com>
Date:   Sun Sep 5 23:05:06 2021 +0900

    fix: div 0

commit 2bce6e4f02
Author: hide_d <hided62@gmail.com>
Date:   Sun Sep 5 23:02:52 2021 +0900

    warning 메시지 수정

commit e64812da72
Author: hide_d <hided62@gmail.com>
Date:   Sat Sep 4 03:42:09 2021 +0900

    fix: m장, 의병장 숙련이 설정되지 않는 버그 수정

commit 7cd40fca03
Author: hide_d <hided62@gmail.com>
Date:   Sat Aug 21 16:04:03 2021 +0900

    fix: 모병/징병에서 조건 검사부 통솔 계산값

commit d1568a3b2c
Author: hide_d <hided62@gmail.com>
Date:   Sat Aug 21 02:50:54 2021 +0900

    허보에 수몰이 같이 들어간 버그 수정

commit e7dcc84afc
Author: hide_d <hided62@gmail.com>
Date:   Thu Aug 19 14:51:50 2021 +0900

    REAMDME.md 버전 수정

commit 8eaa940d4e
Author: hide_d <hided62@gmail.com>
Date:   Wed Aug 18 20:40:37 2021 +0900

    Revert "fix: 7.2에서 오동작 버그 수정"

    This reverts commit 9997675b1d.

commit 9997675b1d
Author: hide_d <hided62@gmail.com>
Date:   Wed Aug 18 20:32:47 2021 +0900

    fix: 7.2에서 오동작 버그 수정

commit 9ef566f11f
Author: hide_d <hided62@gmail.com>
Date:   Wed Aug 18 20:26:31 2021 +0900

    fix: 아이템중 WarActivateSkill 관련 중첩 해제 버그 수정
2021-09-09 00:53:35 +09:00
Hide_D c70181132f build: 서버별 build가 다를 가능성 고려 2021-09-09 00:32:42 +09:00
Hide_D 538615a1f5 fix: tryNpmInstall 이후 genJS까지 실행해야 안전 2021-09-09 00:17:27 +09:00
Hide_D aa20a60a1c fix: recent_map 에러 2021-09-08 23:55:37 +09:00
Hide_D 69fa1dac6c install: php 단에서 npm 설치 환경 구성 2021-09-08 23:50:38 +09:00
Hide_D 3ab349af6e dep: build script 변경 2021-09-08 22:39:14 +09:00
Hide_D 97ac7deb2f misc: npc_control 기존 파일 제거 2021-09-08 21:06:21 +09:00
Hide_D 3230cafb9f 요구사항에 nodejs 요구 추가 2021-09-08 20:41:55 +09:00
Hide_D 394284d8de vue: NPCControl
- 외향  모사(딱히 의미는 없으나..)
- 약간 반응형
2021-09-08 20:39:04 +09:00
Hide_D 6323b174c6 webpack: 최적화 옵션 변경 2021-09-08 03:29:43 +09:00
Hide_D 3d3e0e5139 vue: NPCControl
- 일단 모든 기능 작동
2021-09-08 03:04:40 +09:00
Hide_D ffc7d4bacc vue: NPCControl(WIP) 메인 기능 동작 2021-09-08 02:48:46 +09:00
Hide_D 598236a1d2 vue: NPCControl(WIP) 2021-09-07 03:03:25 +09:00
Hide_D 69207519bd vue-component: NumberInputWithInfo 2021-09-07 00:29:38 +09:00
Hide_D 022eb1012f ts: numberWithCommas 분리 2021-09-07 00:16:28 +09:00
Hide_D 0a9c59f91e fix: 은퇴 시 숙련 포인트를 지나치게 많이 받는 문제 수정 2021-09-06 02:30:00 +09:00
Hide_D 7ebb22b892 재야에서 도시보기 warning 2021-09-06 02:17:56 +09:00
Hide_D 3dc7fc6f14 vue: NPCControl(WIP) 2021-09-06 02:12:28 +09:00
Hide_D 90dea7517b fix: div 0 2021-09-05 23:05:06 +09:00
Hide_D eae48f9564 warning 메시지 수정 2021-09-05 23:02:52 +09:00
Hide_D dd7afba5f5 delete-old: board 2021-09-05 21:27:41 +09:00
Hide_D 73357b6777 CssMinimizer 적용 2021-09-05 18:20:39 +09:00
Hide_D 53df6bbcc6 vue: board 2021-09-05 17:52:39 +09:00
Hide_D 9871559227 vue: Board(WIP) 2021-09-05 03:59:00 +09:00
Hide_D 9cbead1ddc defer 대응 2021-09-05 03:32:57 +09:00
Hide_D 6402028c17 fix: m장, 의병장 숙련이 설정되지 않는 버그 수정 2021-09-04 03:42:09 +09:00
Hide_D 76bd65cf53 vue: inheritPoint 샘플 작성 2021-09-04 00:06:54 +09:00
Hide_D 6e4113de11 vue: inheritPoint(WIP) 2021-09-03 02:42:50 +09:00
Hide_D 12f37f76c7 dep: ready for vue3 2021-09-02 23:03:19 +09:00
Hide_D acd77b2c0a web_pack_config 2021-09-02 01:51:37 +09:00
Hide_D f4fb4ec00d misc: move gateway path 2021-09-02 00:46:33 +09:00
Hide_D 46ae4669ea misc: msg template 통합 2021-08-31 02:35:50 +09:00
Hide_D 67b2dbfe98 js2ts: kingdomList 2021-08-31 02:27:00 +09:00
Hide_D 4f3b39fbfa js2ts: seleect_general_from_pool 2021-08-31 01:03:22 +09:00
Hide_D a28fc52309 js2ts: join 2021-08-30 02:11:07 +09:00
Hide_D d5f0d60794 js2ts: history 2021-08-30 02:02:53 +09:00
Hide_D 72e65587df js2ts: processing - plugin 구조 마저 변경 2021-08-30 01:47:42 +09:00
Hide_D b4d4d90784 js2ts: hallOfFame 2021-08-30 01:43:01 +09:00
Hide_D 3f81fb759d misc: 기존파일 제거 2021-08-30 01:38:24 +09:00
Hide_D d995b39e02 js2ts: currentCity 2021-08-30 01:30:56 +09:00
Hide_D 3bd09a1aa4 core: getJSFiles -> getJSPlugins
- 각각 js를 불러오기보다.. 초기화 함수를 직접 호출
- lazy loading은 어차피 나중에 새로 만들거니까 안 함.
2021-08-30 01:14:20 +09:00
Hide_D a6ff951c98 js2ts: diplomacy
- select2 관련 문제 해결?
2021-08-30 00:27:04 +09:00
Hide_D 604b1557e8 legacy: #bg0, #bg1, #bg2 제거 2021-08-29 02:16:12 +09:00
Hide_D 279bd5c71a misc: Pooper export, summernote lang 2021-08-29 02:05:16 +09:00
Hide_D 97dfb02ab6 js2ts: dipcenter(WIP)
- summernote 이식
- summernote/imageFip plugin 이식
2021-08-29 01:39:03 +09:00
Hide_D 32c7b02303 misc: 미사용 파일 제거 2021-08-28 23:40:37 +09:00
Hide_D e135835e61 jquery-redirect 제거 2021-08-28 23:34:11 +09:00
Hide_D 7ed9a8075c js2ts: main(WIP)
- jquery-redirect 제거
- linkifyStr import
2021-08-28 23:14:07 +09:00
Hide_D ead8110fb4 watch에 dev 모드 추가 2021-08-28 23:13:22 +09:00
Hide_D 586b1b6c15 dep: js package version up
- typscript
- sass
- typescript-eslint
- vue
- core-js
2021-08-28 19:03:28 +09:00
Hide_D e1727c8d80 fix: admin_member path 2021-08-28 18:56:50 +09:00
Hide_D 7bd8a7ff35 fix: msg 기본 동작 2021-08-28 17:25:33 +09:00
Hide_D de48651ae7 feat: exportWindow
- global을 지저분하게 하지 않고, window에 출력만 해줌
2021-08-28 17:20:44 +09:00
Hide_D 9902e07be0 js2ts: msg(WIP) 2021-08-28 06:26:25 +09:00
Hide_D 5e4b38895e js2ts: msg(WIP) 2021-08-28 06:23:25 +09:00
Hide_D 38bbbf261a js2ts: msg(WIP) 2021-08-28 06:22:30 +09:00
Hide_D def0a52578 String format 확장 제거 2021-08-27 03:53:15 +09:00
Hide_D 4f1f87bda0 fix: extExpandCity (format func) 2021-08-27 03:41:32 +09:00
Hide_D 15f9faa2fa js2ts: extExpandCity
- 이부분은 완벽히 새로만들어야 하므로 유지
2021-08-27 03:39:59 +09:00
Hide_D 7257491d8b js2ts: myCityInfo(wip) 2021-08-27 03:36:35 +09:00
Hide_D c19b2a9ebe luxon -> date-fns 2021-08-26 22:50:02 +09:00
Hide_D 54e7fd0293 misc: type module 지정 2021-08-26 21:50:06 +09:00
Hide_D 21f3a2082b misc: delete old gateway install.js 2021-08-26 21:20:47 +09:00
Hide_D f647eb5a7b js2ts: gateway install 2021-08-26 21:20:08 +09:00
Hide_D d7b1db0081 feat: jqValidateForm에 Values Type 지정 2021-08-26 21:10:02 +09:00
Hide_D 11511316d1 js2ts: index(login)
- fix-workaround: popper 로드
2021-08-26 18:11:51 +09:00
Hide_D 95a93c2c44 misc: 사용하지 않은 deprecated 함수 마저 제거 2021-08-26 04:00:52 +09:00
Hide_D 815ce10c25 misc: 개발용 코드 삭제 2021-08-26 03:39:33 +09:00
Hide_D 5f13bfe8a1 js2ts: join user 2021-08-26 03:35:49 +09:00
Hide_D 5cd494c00a js2ts: admin_userlist 2021-08-26 02:28:18 +09:00
Hide_D 5a0a8bedc1 refac: escapeHtml, nl2br, TemplateEngine 분리 2021-08-26 01:37:46 +09:00
Hide_D 3b9884160b js2ts: entrance, webpack(entrance/dist_js) 2021-08-26 01:25:58 +09:00
Hide_D 5b2b01328a webpack: dynamic js build on update 2021-08-25 03:35:51 +09:00
Hide_D e5b51dcd16 genJS 2021-08-25 02:55:11 +09:00
Hide_D 4d8b816acf target별 JS 생성 2021-08-25 02:44:46 +09:00
Hide_D fa109c1b0b feat: VersionGit hash 추가. dynamic추가. 버전 변수 방식 변경 2021-08-25 02:12:35 +09:00
Hide_D b987fce627 feat: VersionGit에 'hash' 추가.(WIP) 2021-08-25 02:05:27 +09:00
Hide_D b072cc3266 gitignore 준비 2021-08-25 01:22:03 +09:00
Hide_D 366b40ea90 build: boosInfo, myPage, convertFormData 2021-08-22 20:13:08 +09:00
Hide_D 3d3daa205d js2ts: bossInfo, myPage
- convertFormData에서 null -> ''
2021-08-22 15:45:10 +09:00
Hide_D 665ebbd11a js2ts: bossInfo 2021-08-22 14:49:03 +09:00
Hide_D 52a5a7697d fix: 리셋 옵션에서 '기본사령턴' 2021-08-22 02:48:14 +09:00
Hide_D 97a38d516a dep: package 2021-08-22 02:40:27 +09:00
Hide_D e89475bf52 dep: webpack cache
- 개발용
2021-08-22 02:31:10 +09:00
Hide_D 90a78b05ce dep: overwrite
- TODO: 서버에서 npm run build를 자동으로 해야함
2021-08-22 02:11:33 +09:00
Hide_D 8c6eff15f0 dep: missing select2 2021-08-22 02:06:50 +09:00
Hide_D 824c58b391 build: board 2021-08-21 21:41:43 +09:00
Hide_D b97500430c js2ts: board 2021-08-21 21:41:32 +09:00
Hide_D bacafc67c9 build: util.ts 분리 2021-08-21 20:45:24 +09:00
Hide_D f23ebcdc2d js2ts: util.ts 분리 2021-08-21 20:45:10 +09:00
Hide_D edbe8e3561 build: betting 2021-08-21 20:38:24 +09:00
Hide_D 05d1e33b30 js2ts: betting 2021-08-21 20:38:15 +09:00
Hide_D 96b60ce0f5 fix: 모병/징병에서 조건 검사부 통솔 계산값 2021-08-21 16:04:03 +09:00
Hide_D 6174bc7ffd build: select_npc 2021-08-21 05:16:07 +09:00
Hide_D 3bd022e03a js2ts: select_npc 2021-08-21 05:15:58 +09:00
Hide_D b0cc5b0b60 build: processing 2021-08-21 04:40:55 +09:00
Hide_D 5493f70458 js2ts: processing
- select2 version dependency 문제로 import는 유지
2021-08-21 04:40:40 +09:00
Hide_D 323b3d9d16 허보에 수몰이 같이 들어간 버그 수정 2021-08-21 02:50:54 +09:00
Hide_D 1b0742ad2a build: processing plugin 2021-08-21 00:30:05 +09:00
Hide_D 2eb7217f49 js2ts: processing plugin 정리 2021-08-21 00:29:50 +09:00
Hide_D b6f5a286b0 build: recent_map 2021-08-20 04:59:13 +09:00
Hide_D 66c496fb10 gateway: 입구의 지도를 iframe으로 변경 2021-08-20 04:58:45 +09:00
Hide_D 56ca588c1e gateway: 입구의 지도를 iframe으로 변경 2021-08-20 04:58:05 +09:00
Hide_D e2b09caff3 build: processing parts 2021-08-20 03:24:14 +09:00
Hide_D a5b4a4c59f js2ts: processing parts(WIP) 2021-08-20 03:24:03 +09:00
Hide_D a70312a90a build: battle_simulator 2021-08-20 02:55:07 +09:00
Hide_D 6c6a3238cb js2ts: battle_simulator 2021-08-20 02:54:57 +09:00
Hide_D 9af10d4bcb misc: showErrorLog
현재 에러로그에는 javascript가 필요하지 않음
2021-08-20 01:40:03 +09:00
Hide_D f6e1b4611e build: install & jqValidateForm 2021-08-20 01:31:32 +09:00
Hide_D 7bc762d357 js2ts-fix: install 2021-08-20 01:31:18 +09:00
Hide_D 8edf1da92b fix: jqValidateForm에서 복합 타입(radio, checkbox) 처리 오류 수정 2021-08-20 01:30:34 +09:00
Hide_D a18baf2ffe REAMDME.md 버전 수정 2021-08-19 14:51:50 +09:00
Hide_D 2d41bf8f2f Revert "fix: 7.2에서 오동작 버그 수정"
This reverts commit 9997675b1d.
2021-08-18 20:40:37 +09:00
Hide_D 334778bdae fix: 7.2에서 오동작 버그 수정 2021-08-18 20:32:47 +09:00
Hide_D 1b46a06eee fix: 아이템중 WarActivateSkill 관련 중첩 해제 버그 수정 2021-08-18 20:26:31 +09:00
Hide_D 1e860e9443 js2ts & wip: install
- jqValidateForm에 전/후처리 추가
2021-08-18 02:59:58 +09:00
Hide_D 0b973672d2 build-misc: BundleAnalyzerPlugin 2021-08-17 02:56:11 +09:00
Hide_D 868ed85c7f build: user_info 2021-08-17 02:25:15 +09:00
Hide_D 6f2a24ec66 js2ts: user_info
- moment js 사용 대상 제거
- sha512 추가
- 비어있는 func.js 제거
2021-08-17 02:25:04 +09:00
Hide_D e5d5899a15 build: entrance 2021-08-17 01:05:54 +09:00
Hide_D 243473a97d js2ts: entrance
- j_server_get_status 반환형 수정
- getDateTimeNow 추가
- common에서 TemplateEngine 코드 버그 수정
2021-08-17 01:05:41 +09:00
Hide_D 28d71b8ce2 js2ts: install_db.php
- jqValidateForm 구현
  - async-validator + 수작업
- common.js 없이 ventor -> 타겟 ts 직접
2021-08-16 23:50:12 +09:00
Hide_D 1acbf90261 gateway printJS 변경 2021-08-16 23:46:53 +09:00
Hide_D 94229f84a3 fix-dep: 로그인 대문 dependency문제로 지도 안나오는 문제 해결 2021-08-16 16:09:54 +09:00
Hide_D cead74238a build: map 2021-08-16 03:29:54 +09:00
Hide_D 73c60ea94c js2ts: map 2021-08-16 03:29:44 +09:00
Hide_D 73638da4db misc: 미사용 파일 삭제 2021-08-16 01:11:38 +09:00
Hide_D bc218b73e1 js2ts: chiefCenter
- common: unwrap_any
- jQuery export 수정
- axios로 변경
- moment -> luxon
2021-08-16 01:06:17 +09:00
Hide_D aac6632f4b js2ts: vendor, evergreen browsers
- IE11 제외(webpack)
- vendor에 bootstrap, jquery 번들
- common.js에서 번들된 jquery, bootstrap 초기화
- 기본 printJS 코드를 common_path, vendors, common으로 고정
2021-08-15 22:55:08 +09:00
Hide_D fdba3fdc74 js2ts: ext.plugin_troop
- async await 대응
- axios 준비
- troop.css
2021-08-15 21:04:06 +09:00
Hide_D 21bb61ec82 js2ts: common 분리, troop.js 2021-08-15 20:19:47 +09:00
Hide_D ce1203d64d js->ts: common.js 2021-08-15 19:59:34 +09:00
Hide_D 56daf15c8e webpack: scss, vue (#189)
WebPack에 scss와 vue를 사용할 수 있도록 세팅.

현재는 php서버와 코드가 강하게 엮여있기 때문에 vue-cli 대신 수동으로 webpack에 등록.

파일 번들링 경로는 다음과 같음

- scss + style -> css
- ts -> js

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/189
Co-authored-by: hide_d <hided62@gmail.com>
Co-committed-by: hide_d <hided62@gmail.com>
2021-08-14 05:47:16 +09:00
Hide_D 96faa924d8 Merge pull request 'PHP8 버전 대응, 버그 수정' (#188) from php8 into devel
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/188
2021-08-13 00:00:32 +09:00
Hide_D ee8854451c fix: phan 지시에 따라 일부 버그 수정
- null && key_exists 버그
- or assign이 integer 대상이므로 직접 연산
- false 대신 0 입력한 곳 수정
- 자체 Deprecate 처리한 함수 회피
- 초기화되지 않은 [] 확인하여 처리
- sleep은 정수만 받으므로 usleep으로 변경
- 선언하지 않고 그냥 사용하던 member 변수 선언
- boolean operation 순서 틀린 부분 수정
2021-08-12 23:58:20 +09:00
Hide_D 0975e925a9 use class, function 커맨드를 php8에서 사용할 수 있도록 수정
- \ 토큰 해석 문제
- VSCode 자동 완성 문제로 use function \sammo\{ 를 모두 해제
2021-08-12 22:35:42 +09:00
Hide_D 83d6a2169b 유산 포인트 시스템, 추가 기수 대비 (#187)
- 유산 포인트
  - 기수 뒤로도 누적되는 포인트
  - 생존, 최대 임관년 수, 최대 연속 내정 성공, 병종 상성 우위 횟수, 전투 횟수, 계략 성공 횟수, 천통 기여(규모 상승, 천통 수뇌, 천통 군주), 숙련도, 토너먼트, 베팅 당첨
  - 유산 관리 페이지 제공

- 태수국
  - 181년 1월에 자동 생성되는 u장수국
  - 시간이 지나면 사실상 자동 소멸
  - 유저국과는 4칸 거리, 서로는 2칸 거리
  - 이 시스템으로 인해 m장 거병 차단

- NPC 원조시 불가침
  - 1년 세수만큼 받은 경우 24개월 불가침 제안
  - 최소 6개월
  - 불가침을 받지 않고 추가 원조한 경우 계속해서 기간 상승
  - 단, 불가침 수락 전에 선포를 할 수 있음

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/187
Co-authored-by: hide_d <hided62@gmail.com>
Co-committed-by: hide_d <hided62@gmail.com>
2021-08-11 21:57:52 +09:00
Hide_D 21e7a4d966 Dep: update
주로 PHAN
2021-08-06 22:39:09 +09:00
Hide_D 404cd24855 작위보상 비중 수정 2021-05-02 02:00:16 +09:00
Hide_D b4ad72ee67 환약을 유니크로 습득하는 버그 수정 2021-05-01 23:48:01 +09:00
Hide_D bea628b619 환약을 습득하게 되는 버그 수정 2021-05-01 23:46:33 +09:00
Hide_D 3637e54982 유니크 onCalcStat 버그 수정 2021-05-01 23:38:06 +09:00
Hide_D e0d1a0a612 아이템 효과 텍스트 수정 2021-04-30 22:36:24 +09:00
Hide_D 3040996671 무쌍 누락분 수정 2021-04-30 16:35:34 +09:00
Hide_D dd830e7500 TypeCode 추가 2021-04-29 22:38:46 +09:00
Hide_D d2dfe2c418 전투 수비 파트 약 상향 2021-04-29 21:10:47 +09:00
Hide_D 139fb6b6e0 국가 규모 승급시 아이템 습득 방식 변경 2021-04-29 20:31:32 +09:00
Hide_D c4f6976c42 유니크 아이템에 효과 추가 2021-04-29 19:50:12 +09:00
Hide_D ab428fc104 유니크 기본 획득 확률 변경 2021-04-29 18:49:19 +09:00
Hide_D aa97f78acd 무쌍 초반 버프, 후반 너프 2021-04-29 18:47:55 +09:00
Hide_D dbce900aeb 유니크 중복 획득 가능 2021-04-29 18:44:09 +09:00
Hide_D 30b382e2e7 초반 등록 NPC 30명 2021-04-29 18:30:46 +09:00
Hide_D 433c4abb86 fix: 이민족 종료 시점 2021-04-11 23:17:47 +09:00
Hide_D 64404e4092 fix: 이민족 종료조건 추가 2021-04-11 21:22:06 +09:00
Hide_D 08d483af8a fix: 후방 워프 인구 충분 판단 기준 수정 2021-04-10 16:01:21 +09:00
Hide_D fa19c17941 fix: AI 발령 턴 오류 수정 2021-04-10 15:39:03 +09:00
Hide_D c896a999ad fix: 전방 도시가 '관'처럼 인구가 적은 경우 후방 워프하지 않는 버그 수정
feat: 후방 발령 관련 로직도 후방 워프와 유사하게 재 적용
2021-04-10 11:51:10 +09:00
Hide_D f9bca935ac fix: 장수수 카운트에 "의병장"을 포함하여 계산하는 버그 수정 2021-04-02 14:39:57 +09:00
Hide_D 7abf274d89 이민족 난이도 기본 수치 변경 2021-03-29 22:45:43 +09:00
Hide_D e2ad417306 feat: 이민족 등장 2021-03-28 16:31:01 +09:00
Hide_D 2ea9655f6b fix: 이민족 2021-03-28 05:57:53 +09:00
Hide_D f450d5d9de fix: 수비자 도시 버그
fix: RaiseInvader 버그 수정 중
2021-03-28 04:12:10 +09:00
Hide_D f8f4b73a09 feat: RaiserInvader 초기 구현 2021-03-28 03:13:03 +09:00
Hide_D 926d96732d fix: 가상 역사 모드에서 후계자 지정이 사실 모드 설정을 따라가는 버그 수정 2021-03-23 13:24:34 +09:00
Hide_D 167113d6a3 fix: 빙의 해제시 owner 값 버그 수정 2021-03-23 13:19:40 +09:00
Hide_D 911cb614a5 fix: RegNPC 버그 수정, event handler 규격 버그 수정 2021-03-19 18:09:53 +09:00
Hide_D 7a939b7024 fix: RegNPC 버그 수정 2021-03-19 17:44:34 +09:00
Hide_D 6e57a60997 RegNPC 버그 수정 2021-03-19 17:36:13 +09:00
Hide_D 9f1151e699 fix: can부대구출발령 없음 2021-03-19 17:22:48 +09:00
Hide_D 3fbe1fb63d 디버그2 2021-02-28 01:39:47 +09:00
Hide_D d4906eec5a 디버그 코드 추가 2021-02-28 01:33:58 +09:00
Hide_D ebe0663e74 에러 로그용 추가 2021-02-28 01:05:27 +09:00
Hide_D 04c89b9711 긴급 호출 대비 2021-02-21 00:40:49 +09:00
Hide_D 4f2bc874e5 initFull을 할 필요가 없었던 것! 2021-02-10 21:24:04 +09:00
Hide_D 316ac5c3c8 불가침인데도 선포 가능한 버그 수정 2021-01-12 17:14:36 +09:00
Hide_D 7882aa667e 관리자 도구 수정 2021-01-07 22:22:04 +09:00
Hide_D 8b8d5eecbf 모반시도 버그 수정 2021-01-07 01:12:06 +09:00
Hide_D 65b76643ee feat: 빙의일람에 장수 선택 내역
fix: 장수 선택 내역에서 owner_name 미반영 버그 수정
fix: 온라인 장수에서 npc가 뜨는 버그 수정
2021-01-03 18:31:18 +09:00
Hide_D f33e645113 초반 m장 스탯 관련 문제 해결, 장수 선택 term 해결 2021-01-01 21:09:43 +09:00
Hide_D 528d30c317 의병모집 버그 수정 2021-01-01 19:56:29 +09:00
Hide_D 7f0a3d320c 버그 수정
- 의병 모집
- 장수 변경 시 생성 폼 남음
2021-01-01 19:54:28 +09:00
Hide_D 8e940aeb65 버그 수정. 시간 변경 2020-12-31 16:21:57 +09:00
Hide_D a77ee60809 버그.. 2020-12-31 13:34:37 +09:00
Hide_D 83383c29cd 버그 수정2 2020-12-31 13:33:45 +09:00
Hide_D b6393141e8 버그 수정 2020-12-31 13:29:57 +09:00
Hide_D 10ce1827d8 버그 수정 2020-12-31 13:27:11 +09:00
Hide_D 605f3a12ff select pool 수 증가 2020-12-31 13:24:33 +09:00
Hide_D a33539e75f 턴 변경을 합리적으로 변경 2020-12-31 08:09:23 +09:00
Hide_D b2cca3687a 버그 수정 2020-12-31 07:49:33 +09:00
Hide_D 628c54044f general_pool 에서 장수 선택 기능 추가 2020-12-31 07:43:56 +09:00
Hide_D c0e7a3eece readme 수정 2020-12-27 19:49:39 +09:00
Hide_D c7c13c19c1 일부 수정
composer update, README.md 업데이트
2020-12-27 02:11:53 +09:00
Hide_D d5f71b5878 DummySession 준비 2020-12-26 15:48:05 +09:00
Hide_D cb589e9e26 종전수락 버그 수정 2020-12-13 22:05:07 +09:00
Hide_D eaeed47297 도시 정보 출력 순서 변경 2020-11-11 23:34:53 +09:00
Hide_D e00e5c5cd7 이벤트 빼빼로 추가 2020-11-11 23:04:08 +09:00
Hide_D b3719f7166 수극 연속 사용 버그 수정 2020-09-09 14:20:15 +09:00
Hide_D 337896974b 피장파장 로그 버그 수정 2020-09-09 14:20:15 +09:00
Hide_D bb7d1fc9ab 수몰을 아무 국가에나 쓸 수 있는 버그 수정 2020-09-09 14:20:15 +09:00
Hide_D 07765c8d44 훈사 제한 버그 2020-08-17 09:21:37 +09:00
Hide_D 85cb91071e 기본 도시 정보 데이터 대폭 추가 2020-08-15 03:46:43 +09:00
Hide_D d41839845a 귀병 첫 페이즈 매우 높은 확률로 계략 시도 2020-08-11 22:43:45 +09:00
Hide_D c3d12aa55f 전쟁/선포 중인 국가에 선포 확률 대폭 감소 2020-08-11 22:36:26 +09:00
Hide_D a781e4b84c 인탐 성공 시 확률따라 추가 보정, 인탐/의병 지장 버그 수정 2020-08-11 22:33:50 +09:00
Hide_D 1fc0989fd2 계략 강화, 탈취량 시간에 따라 증가 2020-08-11 22:33:00 +09:00
Hide_D 14752260d3 회피 필살 중첩 가능 2020-07-24 14:19:05 +09:00
Hide_D 84675c874f 이호경식 버그 수정 2020-07-21 22:38:53 +09:00
Hide_D f30e6057be 버그 테스트 2020-07-21 22:34:10 +09:00
Hide_D ba8b629f0e 격노비급 버그 수정 2020-07-21 03:41:27 +09:00
Hide_D a0a45ff2aa 격노 비급 버그 수정 2020-07-21 03:32:37 +09:00
Hide_D 325f890a0b 방랑시 버그 수정 2020-07-20 23:24:15 +09:00
Hide_D 923cac5408 전략 턴 버그 수정. 글로벌 쿨 9턴으로 변경 2020-07-17 00:16:48 +09:00
Hide_D 23505326c7 격노 추가 향상 2020-07-16 02:57:37 +09:00
Hide_D 5f1a48f523 아이템 짝 안맞는 것 수정 2020-07-16 02:38:40 +09:00
Hide_D a607d39030 아이템 수정 2020-07-16 02:31:18 +09:00
Hide_D 96d108729e 위압 사기버그 수정 2020-07-15 11:55:35 +09:00
Hide_D ef15adaaf8 저격 약간 더 강화 2020-07-15 02:56:31 +09:00
Hide_D f190b74a7e 필살 조금 더 강화 2020-07-15 02:52:14 +09:00
Hide_D edbc2b88b6 버그 수정 2020-07-15 02:43:00 +09:00
Hide_D dc000cecf1 전특 대 개편 2020-07-15 02:33:21 +09:00
Hide_D 7c95a483df 기본 스탯 향상 2020-07-13 23:25:33 +09:00
Hide_D 27e5d73da1 전략별 쿨타임 적용 2020-07-13 23:21:21 +09:00
Hide_D 6306dae92d 전략 사용 방식 변경 2020-07-13 21:54:32 +09:00
Hide_D a427ddff83 수동 토너먼트 버그 수정 2020-07-07 15:24:48 +09:00
Hide_D b62ee6e820 버그 수정 2020-06-26 23:33:39 +09:00
Hide_D 3c18666080 로그인 form draw 예시 2020-06-26 23:31:45 +09:00
Hide_D 40968b301a file_cache_준비 2020-06-26 21:24:24 +09:00
Hide_D 05904d31fd webp 지원 2020-06-26 02:43:46 +09:00
Hide_D 75aeaf4ee7 후방워프 버그 수정 2020-06-26 02:30:35 +09:00
Hide_D ff4e67a9f6 중립턴, 내정워프 수정 2020-06-26 02:26:59 +09:00
Hide_D 5f672d5bd1 몰수 기준 완화 2020-06-26 00:16:56 +09:00
Hide_D 5cb39eba8b 전특 초기화에서 '쿨'을 감안함 2020-06-25 23:45:09 +09:00
Hide_D 4d8c3c75d6 새 금쌀 구매 로직 2020-06-25 23:43:35 +09:00
Hide_D 8bdd19fc06 버그 수정 2020-06-21 17:07:03 +09:00
Hide_D 0ec99d8ba1 서버 커스터마이징 가능 2020-06-21 17:03:32 +09:00
Hide_D 929d2db5a5 유저장 구출 버그 수정 예상 2020-06-20 21:43:28 +09:00
Hide_D a7ad77f433 최근 전투 페이즈 계산 버그 수정 2020-06-20 15:09:35 +09:00
Hide_D 9cd47d5deb recent_war 표기 방식 변경경 2020-06-19 20:24:50 +09:00
Hide_D 3cb5691aae 수비 기호 표시 추가 2020-06-18 01:05:34 +09:00
Hide_D dce63919fa 부대유저장발령 코드 일부 수정 2020-06-17 03:39:22 +09:00
Hide_D 1cdbedcb96 도시 치료 결과가 이상하게 뜨는 버그 수정 2020-06-16 00:26:45 +09:00
Hide_D 1586712ce5 버그 수정 2020-06-12 22:11:19 +09:00
Hide_D f059186494 구출 발령 활성화 안된 버그 수정 2020-06-12 22:08:56 +09:00
Hide_D 0af0be57b0 전방 발령 버그 수정 2020-06-12 21:16:37 +09:00
Hide_D dad2b03212 ExistsDestNation 버그 수정 2020-06-12 20:39:31 +09:00
Hide_D b6e307660f warning 수정 2020-06-12 20:28:50 +09:00
Hide_D c21c14825a 오타 수정 2020-06-11 03:28:10 +09:00
Hide_D 39f9c986e9 버그 수정 2020-06-11 03:21:26 +09:00
Hide_D 393683aebc 버그 수정 2020-06-11 03:14:12 +09:00
Hide_D a87fcb44a6 전투 시뮬레이터 장수 불러오기 완성 2020-06-11 03:13:02 +09:00
Hide_D 0a6496ddfb 관직 비우기 안되는 것 수정 2020-06-11 00:29:36 +09:00
Hide_D fa2841fac6 원조 버그 수정 2020-06-11 00:20:08 +09:00
Hide_D 861e45419b 포상 검사 로직 빠진 부분 수정 2020-06-09 20:50:57 +09:00
Hide_D 15fd943456 전쟁장 판단 기준 임시 수정, 사망 대비 장수에겐 포상안함 2020-06-09 20:32:49 +09:00
Hide_D b538bfc27e Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2020-06-09 20:30:41 +09:00
Hide_D e0f32eddc4 전쟁장 판별 코드 임시 수정 2020-06-09 20:30:34 +09:00
Hide_D 75a704c196 저격시 아이템이 무조건 소모되는 버그 수정 2020-06-09 01:45:52 +09:00
Hide_D 6565fdbe7e 무장 신산 가능 2020-06-09 01:25:35 +09:00
Hide_D 6248d72852 홀짝 버그 수정 2020-06-09 01:10:21 +09:00
Hide_D 00d1797b96 내특 동작 안하는 버그 수정 2020-06-09 01:03:58 +09:00
Hide_D 911194eba8 찐유저무쌍 비급판 2020-06-07 16:08:04 +09:00
Hide_D 0fad3ae31d 유지비를 깎고 세수를 계산하도록 수정 2020-06-06 19:21:51 +09:00
Hide_D b6988d866a 선포 동안에는 초토화 가능하도록 수정 2020-06-06 15:43:29 +09:00
Hide_D e30959a656 숙련전환 효율 향상 2020-06-06 14:33:21 +09:00
Hide_D 52eeff3466 환약 사용 여부가 안보이는 버그 수정 2020-06-06 13:45:31 +09:00
Hide_D a06ded552d 유저장은 자동 사령턴 켬끔 가능 2020-06-06 13:20:01 +09:00
Hide_D e9b8a84243 전방 발령에 공백지 배제 2020-06-06 12:55:34 +09:00
Hide_D 1fc3cfd1f2 중립 인탐 확률 감소 2020-06-06 03:07:00 +09:00
Hide_D 188b57ed7a 랜덤 임관 버그 수정 2020-06-05 18:13:21 +09:00
Hide_D c8620390ac 중립 커맨드 2020-06-05 02:25:44 +09:00
Hide_D b3f8ed2335 지도 기반 선택 버그 수정 2020-06-05 01:14:49 +09:00
Hide_D 54bf504eb4 명령 입력턴에 select2 적용 2020-06-05 01:02:33 +09:00
Hide_D c6f3bf856b select2 업그레이드 2020-06-04 23:21:47 +09:00
Hide_D 8b33a7926e 오호 장군 수정 2020-06-04 21:31:26 +09:00
Hide_D a38cb90cbf 천지비급 시나리오를 설명에 맞게 수정 2020-06-03 22:17:22 +09:00
Hide_D 1500e8e54f 서버가 닫힌 경우 리다이렉트하도록 2020-06-03 01:51:31 +09:00
Hide_D 94fd8d5e9d 세력도시 암행부 연동 버그 수정 2020-06-02 01:24:25 +09:00
Hide_D 373e0a2155 버그 수정 시도2 2020-06-02 01:06:00 +09:00
Hide_D 267298f341 사령부 공백이어도 사령턴은 보임 2020-06-02 00:24:44 +09:00
Hide_D 359d46e94d 천지비급 디버그 풀기 2020-06-02 00:08:52 +09:00
Hide_D 11f5540099 composer 반영 2020-06-01 21:14:50 +09:00
Hide_D 680e1afcfd 버그 수정 2020-06-01 02:34:56 +09:00
Hide_D e4322e60cc 환약 사용 기준 추가 2020-06-01 02:31:46 +09:00
Hide_D 82f2eecfe8 내 설정 페이지 동작 방식 일단 수정 2020-06-01 02:17:20 +09:00
Hide_D 3e3c3c559d 소모성 아이템 소비 2020-05-31 23:11:17 +09:00
Hide_D 65f5e8e964 setResultTurn 버그 수정 2020-05-31 17:21:51 +09:00
Hide_D c5fbe93890 버그 수정 2020-05-31 04:43:15 +09:00
Hide_D 307d8b6165 버그 수정 2020-05-31 04:42:11 +09:00
Hide_D bf08eb2f8b 버그 수정 2020-05-31 04:32:46 +09:00
Hide_D a569c1dfaf 버그 수정 2020-05-31 04:25:36 +09:00
Hide_D e48db0d231 장수 목록 json 버그 수정 2020-05-31 04:12:42 +09:00
Hide_D 1a5b5dbb45 격노 1회만 2020-05-31 01:47:44 +09:00
Hide_D 56f21cabe5 격노 발동은 1회만 2020-05-31 01:44:44 +09:00
Hide_D 7ac5afe05b 이벤트 특기 버그 수정 2020-05-30 22:50:48 +09:00
Hide_D b3db97f4a8 이중특기 테스트 2020-05-30 16:31:03 +09:00
Hide_D 6d1a06a9d9 긴급 쌀 시 병량패퇴를 당하지 않기 위해 강제 회피 2020-05-30 04:48:33 +09:00
Hide_D 088643df6c 워프 버그 수정 2020-05-30 04:41:47 +09:00
Hide_D fc00a0a363 의병모집, 소형b 초기 m장, 작위보상금쌀
의병모집 -> 초기 금쌀 1000
작위보상 -> 작위에 따라 금쌀*1000
소형b -> 초기 m장 10 추가
2020-05-30 04:36:42 +09:00
Hide_D 7a48fdd246 멸망시 임관 확률을 변경 가능하도록 설정 2020-05-30 03:18:23 +09:00
Hide_D 89be493882 인재탐색 변경. 영입 불가, 재야 가능 2020-05-30 03:09:48 +09:00
Hide_D 5947abf83d 대인 사살, 점령률 추가 2020-05-30 03:05:03 +09:00
Hide_D 962db6821f 대인살상률, 점령수 준비 2020-05-30 02:29:46 +09:00
Hide_D f6a3df7858 수비 켬끔 다양화 2020-05-30 02:08:16 +09:00
Hide_D 090aaed3f4 숙련 전환 효율 향상 2020-05-30 01:56:31 +09:00
Hide_D 71cb5aa9e4 성벽에 닳는 내정을 1/2 2020-05-29 19:16:24 +09:00
Hide_D 043b29ef33 격노 회피 시도 캔슬 2020-05-28 01:39:14 +09:00
Hide_D d81cf4aec3 소집해제 위치 이동 2020-05-28 01:33:27 +09:00
Hide_D 7cb46eeb82 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2020-05-26 21:44:22 +09:00
Hide_D c3b4d54414 내정 워프 버그 수정 2020-05-26 21:44:03 +09:00
Hide_D 8b9acf2d3d 실패 메시지 수정 2020-05-26 10:44:55 +09:00
Hide_D 08548181ed 첩보 가격이 저렴한 버그 수정 2020-05-26 00:47:42 +09:00
Hide_D 45f883c98b 징병창 병력 키보드 입력 버그 2020-05-25 23:28:16 +09:00
Hide_D 5f39229e47 치안강화 만땅 채우기 2020-05-24 22:52:56 +09:00
Hide_D 8c5bdc2a4b 사망시 수명 계산 버그 2020-05-24 13:41:52 +09:00
Hide_D 7b7602bce2 사령부 확실히 엔터 2020-05-23 17:21:07 +09:00
Hide_D a145792fac 헌납 비율 수정 2020-05-23 16:35:33 +09:00
Hide_D 667a550f4c 조사 수정 2020-05-23 16:30:10 +09:00
Hide_D 53e1ad8991 헌납 메시지 수정 2020-05-23 16:28:21 +09:00
Hide_D 429c949d1f AI 치안 버그 수정 2020-05-23 16:24:18 +09:00
Hide_D 1548577d65 주민선정을 매우 열심히 합니다. 2020-05-23 15:33:10 +09:00
Hide_D 82e59b297f 증축 버그 수정 2020-05-23 11:12:10 +09:00
Hide_D 1f9c994425 사령부 시간 표기 문제 2020-05-22 00:24:52 +09:00
Hide_D fc0c7a5004 호황, 풍작 색상 변경 2020-05-22 00:17:24 +09:00
Hide_D a2d0309c79 내특 중복 버그 수정 2020-05-21 12:52:00 +09:00
Hide_D 6d01fbb6e8 generalCommand 생성이 preprecessCommand보다 빠른 문제 수정 2020-05-21 12:14:46 +09:00
Hide_D be270df088 요양 입력하면 템치료 무효화 2020-05-21 02:16:20 +09:00
Hide_D 88fd94e1cc 왕조일람 국가 타입 버그 수정 2020-05-20 01:35:11 +09:00
Hide_D e460392368 인사부 임명시 색상 2020-05-20 01:31:26 +09:00
Hide_D 249cda99f4 랜덤임관에 긍정적인 메시지 추가 2020-05-20 01:26:28 +09:00
Hide_D 327fce822a Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2020-05-20 01:11:41 +09:00
Hide_D 58931354a4 NPC 포상룰 변경 2020-05-20 01:11:35 +09:00
Hide_D c8993e9832 암해부 정렬 버그 2020-05-19 16:53:20 +09:00
Hide_D 4ee2e023aa 버그 수정 2020-05-19 10:07:24 +09:00
Hide_D 22fa1b121e 수정시도2 2020-05-19 00:32:52 +09:00
Hide_D cbc6e526c3 수정시도2 2020-05-19 00:32:40 +09:00
Hide_D 96041faefd 수정시도1 2020-05-19 00:30:55 +09:00
Hide_D 894c912e19 수정시도 1 2020-05-19 00:29:24 +09:00
Hide_D 7b406a945f 버그 수정 2020-05-19 00:25:41 +09:00
Hide_D 6ff5cc90f1 버그 수정 2020-05-19 00:18:45 +09:00
Hide_D f66e56f4b5 보궁기귀 전특 중 '통장'에 타 능력치 금지 추가 2020-05-19 00:08:50 +09:00
Hide_D 8f09aab0ea NPC 자원 기준 대폭 변경 2020-05-18 23:49:13 +09:00
Hide_D b248b9ca2c 불가침 하나만 있어도 계략이 안들어가는 버그 수정 2020-05-18 23:25:53 +09:00
Hide_D 5a6a31fefa 정착장려, 주민선정 색상 문제 2020-05-18 23:24:17 +09:00
Hide_D 1e485a3883 onCalcNationalIncome 버그 2020-05-18 23:17:16 +09:00
Hide_D fed3246c84 계략 성공시 대미지 없는 문제 수정 2020-05-18 20:12:57 +09:00
Hide_D daff4a9786 징병시 부상을 무시하는 버그 수정 2020-05-18 19:35:41 +09:00
Hide_D 6e88b0c701 로그에 도시 추가 2020-05-18 14:30:39 +09:00
Hide_D 808f674173 버그 수정? 2020-05-18 09:55:00 +09:00
Hide_D ba377c9aac 등용 UI 버그 수정 2020-05-17 20:07:09 +09:00
Hide_D bb8909f552 등용 UI 버그 수정 2020-05-17 20:05:47 +09:00
Hide_D 5a4d9ffcfc 등용장 버그 수정
등용장 초반에도 보낼 수 있도록,
리스트에서 optgroup 작성 실수
2020-05-17 20:00:06 +09:00
Hide_D 5ed24a98cb npc 정책 UI 수정 2020-05-17 19:48:20 +09:00
Hide_D 6d17675ee7 npc 정책 UI
?가 아니라 본체를 선택해도 보이도록
2020-05-17 19:45:18 +09:00
Hide_D e0b8bfdeae 버그 수정 2020-05-17 18:15:02 +09:00
Hide_D 0db2009e65 NPC 생성시 스케일러 제거 2020-05-17 13:47:28 +09:00
Hide_D 5f016d74a1 버그 수정 2020-05-17 03:03:04 +09:00
Hide_D 02b9832750 npcMax 추가 감소 2020-05-16 21:12:09 +09:00
Hide_D 18a888b9d4 인탐, 의병모집 수정, npcMin, npcTotal 추가 2020-05-16 18:59:10 +09:00
Hide_D 7f20e981d2 오호장군 표기기준 버그 수정 2020-05-16 18:16:52 +09:00
Hide_D d64e08f3c4 부대장후방발령버그 2020-05-16 16:24:45 +09:00
Hide_D 8bb5324896 출병 경로 설정 메시지 버그 수정 2020-05-16 14:14:13 +09:00
Hide_D 8f2ebc6409 인재탐색 연령버그 수정 2020-05-16 12:37:13 +09:00
Hide_D 371318f62f 버그 수정 2020-05-15 21:59:10 +09:00
Hide_D 6e94403dc6 수치 버그 수정 2020-05-15 21:51:29 +09:00
Hide_D c35f6905bb 초토화 배율 변경 2020-05-15 21:50:11 +09:00
Hide_D 4eebbb3e81 초토화에 전 장수 배신 1호 추가, 반환 금액 입력 2020-05-15 21:25:01 +09:00
Hide_D 8ddfc8fb4a 한계징병 2020-05-15 12:36:01 +09:00
Hide_D 14d2661be8 npc 조작 권한 안내 2020-05-15 00:38:26 +09:00
Hide_D ec71bf29b8 애니 집결 수정 2020-05-15 00:30:14 +09:00
Hide_D b1b06d9c82 베팅장 수리 2020-05-15 00:23:10 +09:00
Hide_D 6feec9bdbd 헌납 버그 수정 2020-05-14 23:54:02 +09:00
Hide_D d00f4f281c 거래장 버그 수정 2020-05-14 23:47:08 +09:00
Hide_D 15e3ec5263 유니크템 습득 확률 버그 2020-05-14 22:05:47 +09:00
Hide_D d6ddd91fda NPC 정책 설명 추가, 부대구조 추가, 포상/몰수량 조절 2020-05-14 02:04:28 +09:00
Hide_D de79e25510 조언자 포함 2020-05-13 02:28:35 +09:00
Hide_D 08f6b4deed 외교권자만 수정 가능하도록 변경 2020-05-13 02:28:14 +09:00
Hide_D 5cd115b54f 긴천시 쌀이 250만 생기니 500으로 증량 2020-05-13 02:22:58 +09:00
Hide_D 44b6f5890c 버그 수정 2020-05-13 02:13:58 +09:00
Hide_D 5dd5933390 코드 버그 수정 2020-05-13 02:11:25 +09:00
Hide_D d55d3f2fe1 정책 반영 2020-05-13 01:56:08 +09:00
Hide_D 2e9b87f0bc 입력창 준비 2020-05-13 00:45:38 +09:00
Hide_D 800c85dd03 npc_control form 2020-05-12 03:20:20 +09:00
Hide_D 5414f7161f 첩보 버그 수정 2020-05-11 02:23:27 +09:00
Hide_D 98b5825475 응답시 새로고침, 등용수락 안되는 버그 수정 2020-05-11 02:14:33 +09:00
Hide_D bda21c421f 등용장 버그 2020-05-11 01:53:15 +09:00
Hide_D ee27b06822 이동시 사기 하락 2020-05-11 01:38:47 +09:00
Hide_D 7504d62ab1 버그 수정 2020-05-11 01:37:37 +09:00
Hide_D f66b5c91fc 출병 에러 로그 수정 2020-05-11 01:24:34 +09:00
Hide_D bf838cd561 출병 어택땅시 아국 때리는 버그 수정 2020-05-11 01:21:46 +09:00
Hide_D eeb92f5915 금쌀 구매 관련 임시 수정 2020-05-11 01:16:27 +09:00
Hide_D 4524fab6b9 이전 로그 보기 추가 2020-05-11 01:05:55 +09:00
Hide_D d1a9b40ed5 테스트용 치트템 추가 2020-05-10 22:24:20 +09:00
Hide_D 96523408bd history 간소화 2020-05-10 15:06:51 +09:00
Hide_D b5646e0988 보상 기준 변경, 버그 수정 2020-05-10 04:50:10 +09:00
Hide_D 645c5cc6c1 인탐 확률 2020-05-10 04:29:14 +09:00
Hide_D 7323983d11 발령을 위해 수정 2020-05-10 04:18:12 +09:00
Hide_D 8650c9e4b9 $connect 잘 가 2020-05-10 03:39:02 +09:00
Hide_D 7cfdb403b3 같은 장수 같은 관직 임명시 버그 2020-05-10 03:26:25 +09:00
Hide_D af30c69560 약간의 쿼리 최적화 2020-05-10 02:18:44 +09:00
Hide_D b49ecb5802 점령->멸망 순서 정정 2020-05-10 02:15:56 +09:00
Hide_D 9f0dd8358f 중원 정보 재작성 2020-05-10 02:12:25 +09:00
Hide_D 1fff99b5f2 $connect 박멸중. 2020-05-10 01:15:25 +09:00
Hide_D f3ef65ad70 접속자수 계산 코드 수정 2020-05-09 23:46:43 +09:00
Hide_D da9d59443b getVar('npc') -> getNPCType() 2020-05-09 23:18:47 +09:00
Hide_D 2e7a5c6244 장수 수 적용 관련 변경 2020-05-09 23:09:36 +09:00
Hide_D 0b6f04ed26 소소한 설문 결과 수정 2020-05-09 17:55:07 +09:00
Hide_D 4856f6c477 토너먼트 우승 처리 버그 수정 2020-05-09 17:52:06 +09:00
Hide_D 0a0b499716 핵심 디버그 코드 제외 제거 2020-05-09 17:47:51 +09:00
Hide_D 954888a879 pushGlobalHistory 해제 2020-05-09 17:41:24 +09:00
Hide_D f00a01c123 내무부 국력순 정렬 2020-05-09 17:22:35 +09:00
Hide_D 0efb3a6f30 포상 기준 변경 2020-05-09 17:16:21 +09:00
Hide_D d3a9a7b54c 버그 수정 2020-05-09 17:00:36 +09:00
Hide_D 4bbf40c5b8 디버그 코드 추가 2020-05-09 16:50:53 +09:00
Hide_D 01ab59774b 징병 버그 1차 수정 2020-05-09 15:54:02 +09:00
Hide_D 5a6f84d5d2 m장 의병장 스탯 버그 수정 2020-05-09 15:34:32 +09:00
Hide_D eea5135316 관직 임명을 3,6,9,12에 하도록 변경 2020-05-09 15:16:27 +09:00
Hide_D 9f303966eb 자가 발령 포상 몰수 2020-05-09 15:14:24 +09:00
Hide_D a31b5ea29d 특기 초기화 추가 2020-05-09 13:14:11 +09:00
Hide_D b6a6ee31ed 설문조사시 아이템을 안 가진것으로 판정하는 버그 수정 2020-05-09 12:20:52 +09:00
Hide_D 9aa7556e5b 버그 수정 2020-05-08 22:09:56 +09:00
Hide_D 12cc54b0ea 버그 수정 2020-05-08 22:03:12 +09:00
Hide_D f8c4eae715 따라 임관 추가 2020-05-08 21:49:05 +09:00
Hide_D f8d8d2122e 버그 수정 2020-05-08 21:18:58 +09:00
Hide_D 157c8e92d5 즉시 사망 안되는 문제 해결 2020-05-08 21:14:33 +09:00
Hide_D bece81b10e TriggerCaller버그 수정 2020-05-08 20:52:16 +09:00
Hide_D 99755e98ee betray가 없는 버그 수정 2020-05-08 20:18:54 +09:00
Hide_D 541de612b2 예약턴 바로 받아오도록 수정 2020-05-08 20:14:20 +09:00
Hide_D c46d9fd04a 턴 실행 순서 조정 2020-05-08 03:31:17 +09:00
Hide_D a49695ace7 자가 치료 문제 2020-05-08 03:17:30 +09:00
Hide_D b562d45531 버그 수정 2020-05-08 03:13:20 +09:00
Hide_D e9f8db58c0 백동 재수정 2020-05-08 03:11:37 +09:00
Hide_D ed3313b2bc 백동 버그 수정 2020-05-08 03:09:20 +09:00
Hide_D 7bb6a9615c 일부 수치 변경 2020-05-08 03:03:16 +09:00
Hide_D e7333508c4 관직 코드 버그 수정 2020-05-08 01:52:24 +09:00
Hide_D 6e6feb6dc1 장수, 도시가 없을 경우 문제 수정 2020-05-08 01:22:27 +09:00
Hide_D cb37e3e993 장수 출력 일부 수정 2020-05-08 01:14:15 +09:00
Hide_D 13f457eba3 연감 저장방식 수정 2020-05-08 01:09:39 +09:00
Hide_D e7f8900286 통합, 항복 제거 2020-05-07 23:48:08 +09:00
Hide_D 7199a770c0 버그 수정 2020-05-07 23:38:26 +09:00
Hide_D e560bbdeb4 천도시 인구의 비중을 조금 더 높게 2020-05-07 00:59:28 +09:00
Hide_D 6479d39f93 버그 수정 2020-05-07 00:48:13 +09:00
Hide_D 9fc9790e93 버그 수정 2020-05-07 00:43:32 +09:00
Hide_D 5a50476e9d 버그 수정 2020-05-07 00:39:25 +09:00
Hide_D b8a8776c2e run_daemon 버그 수정 2020-05-06 22:58:58 +09:00
Hide_D f155a341cb 버그 수정 2020-05-06 20:58:08 +09:00
Hide_D 253e48694a 버그 수정, 반복 도구 강화 2020-05-06 20:56:13 +09:00
Hide_D 30a090004b 버그 수정 2020-05-06 20:08:00 +09:00
Hide_D fb77443b99 버그 수정 2020-05-06 09:10:24 +09:00
Hide_D 06d88883d8 버그 수정 2020-05-06 09:08:26 +09:00
Hide_D 337c9d3241 버그 수정 2020-05-06 09:06:47 +09:00
Hide_D 1d6378c1fc 버그 수정 2020-05-06 09:01:40 +09:00
Hide_D f13cfd190e 접속장수 수 위치 이동 2020-05-06 02:25:58 +09:00
Hide_D a2823b3c29 버그 수정 2020-05-06 02:13:40 +09:00
Hide_D 169edd4f9c nation_env 수정, $connect 일부 제거 2020-05-06 01:53:00 +09:00
Hide_D d0fa094d04 국방,임관권유문을 KVStorage로 분리 2020-05-05 19:55:59 +09:00
Hide_D 6ac12d42fe json_valid 설정. officer 설정 방식 변경 2020-05-05 19:17:27 +09:00
Hide_D a378ac8738 국기 변경 수정, 아이템 보상 추가 2020-05-05 17:24:03 +09:00
Hide_D 8b8f749006 neutralize 일부 롤백
과거의 나는 다 계획이 있었구나.
2020-05-05 03:57:00 +09:00
Hide_D b004a0609b 국호변경, 국기변경, string neutralize 2020-05-05 03:44:00 +09:00
Hide_D 82d4efcbc2 버그 수정 2020-05-05 00:41:16 +09:00
Hide_D 2476726a6a 빠진 코드 추가 2020-05-05 00:19:13 +09:00
Hide_D 19a84d0cc8 getReq변경, ajax인 경우 ajax요청 2020-05-05 00:19:01 +09:00
Hide_D a688b6fdce 건국시 국가색 2020-05-04 21:02:46 +09:00
Hide_D 73e5f5d6ad testPermissionToReserve 수정 2020-05-04 20:52:33 +09:00
Hide_D 014fb9408e MinCondition 조건 약화 2020-05-04 20:37:23 +09:00
Hide_D 91f2be6759 버그 수정 2020-05-04 20:01:23 +09:00
Hide_D 76ac6cf5b5 커맨드 유효성을 2개에서 3개구성으로 변경 2020-05-04 19:51:11 +09:00
Hide_D dbba6fa942 랜임모드시 임관출력 버그 수정 2020-05-04 07:26:53 +09:00
Hide_D d0771e3392 초토화 스택 버그 2020-05-04 06:25:28 +09:00
Hide_D 6c8eca2f57 버그 수정 2020-05-04 06:24:01 +09:00
Hide_D 3aa9d8ae56 버그 수정 2020-05-04 06:22:34 +09:00
Hide_D 42e1764c44 버그 수정 2020-05-04 06:18:20 +09:00
Hide_D 5abe9bd6d5 초토화 버그 수정 2020-05-04 06:17:13 +09:00
Hide_D d5492eee93 초토화 추가 2020-05-04 06:13:15 +09:00
Hide_D a26a59b193 턴 계산 수정 2020-05-04 02:48:09 +09:00
Hide_D 3d2dbe9199 루드라사움 2020-05-04 02:04:34 +09:00
Hide_D 73749b8d22 update server 반영 2020-05-04 01:42:20 +09:00
Hide_D 50c30b7cd0 전략 구현 2020-05-03 17:30:43 +09:00
Hide_D 44305b9abf 숙련전환 추가 2020-05-03 04:09:44 +09:00
Hide_D c98d8fd199 토너먼트 버그 수정 2020-05-03 03:36:21 +09:00
Hide_D 4adc0b7c24 불가침파기제의 추가 2020-05-03 01:33:52 +09:00
Hide_D 1427ac632f 불가침, 종전 메시지 2020-05-03 00:31:04 +09:00
Hide_D 5e4ae07575 버그 수정 2020-05-02 17:52:08 +09:00
Hide_D 9c7fddfb0d 명전 살상률 수정 2020-05-02 17:29:20 +09:00
Hide_D 8ebe81b89f 토너먼트 나눗셈 버그 수정 2020-05-02 16:20:36 +09:00
Hide_D 016ca770f5 phan 처리 2020-05-02 12:01:54 +09:00
Hide_D c8948953c9 버그 수정 2020-05-02 02:25:45 +09:00
Hide_D 85ebd30c9c 장수 등록 수정 2020-05-02 02:15:59 +09:00
Hide_D 5ea6c4c449 색상 2020-05-02 02:14:48 +09:00
Hide_D bfa31d1c79 강조 수정 2020-05-02 02:13:18 +09:00
Hide_D d4f7ce7560 표시 2020-05-02 02:12:23 +09:00
Hide_D 0ef223d80e raise event 등록 CreateManyNPC 추가 2020-05-02 02:09:21 +09:00
Hide_D eb232f7bb1 버그 수정 2020-05-02 01:16:09 +09:00
Hide_D ce4f44a951 버그 수정 2020-05-02 01:15:52 +09:00
Hide_D f70cfb5d48 버그 수정 2020-05-02 01:09:41 +09:00
Hide_D 7e39be6d20 토너먼트 무명장수 코드 수정 2020-05-02 00:36:14 +09:00
Hide_D 979afdbf7b 토너먼트 롤백 2020-05-01 23:41:41 +09:00
Hide_D e662b5ed23 버그 수정 2020-05-01 21:59:53 +09:00
Hide_D fea7dcb4aa 지급률 수정 2020-05-01 18:26:49 +09:00
Hide_D 2220920afe 코드 수정 2020-05-01 18:24:05 +09:00
Hide_D 180b3c7c5d phan 1차 2020-05-01 17:33:14 +09:00
Hide_D beb7553629 메시지 컬러 수정 2020-05-01 16:09:03 +09:00
Hide_D 75934fc5ae 선양 버그 수정.. 2020-05-01 16:02:36 +09:00
Hide_D 0882e06adc 버그 수정 2020-05-01 15:28:00 +09:00
Hide_D 96bd755660 선양 코드 수정 2020-05-01 15:27:42 +09:00
Hide_D 51c96b4d04 phan 설치 2020-05-01 15:26:54 +09:00
Hide_D a529eba693 버그 수정 2020-05-01 03:36:17 +09:00
Hide_D a00b5a71fc None 처리 2020-05-01 03:27:43 +09:00
Hide_D 7f35dda305 징병 버그 다시 수정 ㅜㅜ 2020-04-30 19:58:17 +09:00
Hide_D fccebb059b 징병 입력 버그 수정 2020-04-30 19:56:38 +09:00
Hide_D cf1dc17298 버그 수정 2020-04-30 19:29:39 +09:00
Hide_D b24eabc82a 저격 설명 수정 2020-04-30 17:08:55 +09:00
Hide_D f3a26116b2 전멸시마다 저격 가능 2020-04-30 17:08:34 +09:00
Hide_D 884c1ea82c 버그 수정 2020-04-30 16:47:11 +09:00
Hide_D c65737f554 저격 버그 수정 2020-04-30 16:02:46 +09:00
Hide_D b77a11bfc2 부대후방발령 버그 수정 2020-04-30 13:44:42 +09:00
Hide_D 58fd8e3c7f 부대유저장 후방발령 버그 2020-04-30 13:40:55 +09:00
Hide_D a8cc2fc671 병종 이미지경로 변경 2020-04-30 06:31:12 +09:00
Hide_D d19ebb6b13 내정을 조금 더 고려함 2020-04-30 05:58:44 +09:00
Hide_D fad02e8736 디버그 코드 제거 2020-04-30 05:42:11 +09:00
Hide_D 11c928bf30 AI 천도 안하는 버그 수정 2020-04-30 05:41:42 +09:00
Hide_D b4262eb34b 저격 버그 수정, 필살 강화 2020-04-30 05:07:52 +09:00
Hide_D 76c4a8a966 살상률 표기 버그 수정 2020-04-30 04:34:51 +09:00
Hide_D 0a212af11e 견고 버그 수정, 저격 상향 2020-04-30 04:32:35 +09:00
Hide_D efffb46281 증축,감축,천도 버그 2020-04-30 04:03:43 +09:00
Hide_D e2ec3ef532 천도 버그 수정 2020-04-30 03:16:16 +09:00
Hide_D d3c4dd59d2 징병 로직 일부 수정 2020-04-29 00:28:27 +09:00
Hide_D dcebb79590 출병 기준 수정 2020-04-28 04:02:14 +09:00
Hide_D 0f0b989963 랜덤 성격 불가 수정 2020-04-28 02:18:02 +09:00
Hide_D 4815f6c79a 방랑군 warning 2020-04-28 02:14:10 +09:00
Hide_D 409063a339 디버그 로그 제거 2020-04-28 02:11:25 +09:00
Hide_D c831d539b6 숙련 버그 수정 2020-04-28 02:02:28 +09:00
Hide_D 7aa826fc80 버그 수정 2020-04-28 01:50:25 +09:00
Hide_D d603557c35 버그 수정 2020-04-28 01:37:52 +09:00
Hide_D c267a5c7e0 버그 수정 2020-04-28 01:09:07 +09:00
Hide_D 46764ff9aa 버그 수정 2020-04-27 14:22:07 +09:00
Hide_D f7a041d9fc 버그 수정 2020-04-27 14:12:51 +09:00
Hide_D 751336e5d1 버그 테스트 2020-04-27 14:09:23 +09:00
Hide_D b2403aedac 선정 열심히 2020-04-27 13:03:12 +09:00
Hide_D d5f9e923c4 기술연구 우선순위 낮춤 2020-04-27 12:54:16 +09:00
Hide_D c3c2022029 내정 시도율 변경 2020-04-27 03:09:05 +09:00
Hide_D fb08e86a4c 재야 부대장 사망 2020-04-27 02:53:13 +09:00
Hide_D 6f4c32c04c 디버그 코드 임시 제거 2020-04-27 02:42:10 +09:00
Hide_D 7c74a40baf 수치 수정 2020-04-27 02:39:26 +09:00
Hide_D 8bf60bb793 버그 수정 2020-04-27 02:37:11 +09:00
Hide_D 005aa959c5 부대장 동작 관련 수정 2020-04-27 02:30:52 +09:00
Hide_D d9818f6960 버그 수정 2020-04-27 02:21:11 +09:00
Hide_D f90ac9dea4 버그 수정 2020-04-27 02:18:42 +09:00
Hide_D e0036ca32b 버그 수정 2020-04-27 02:07:34 +09:00
Hide_D ad8acaf296 버그 수정 2020-04-27 00:30:48 +09:00
Hide_D 34a863a6ea 스킬 안 쓰는 버그 해결 2020-04-26 23:52:17 +09:00
Hide_D 724c7388af 특기 획득 구조 변경 2020-04-26 22:31:49 +09:00
Hide_D 2bb6ef8efb 관직 임명 보정 2020-04-26 04:48:31 +09:00
Hide_D baf4d3aa98 버그 수정 2020-04-26 04:08:47 +09:00
Hide_D f4ca4431da 버그 수정 2020-04-26 04:02:16 +09:00
Hide_D 19446a666e 버그 수정 2020-04-26 04:00:06 +09:00
Hide_D b48b09249e 버그 수정 2020-04-26 03:45:19 +09:00
Hide_D be282db1c2 버그 수정 2020-04-26 03:36:40 +09:00
Hide_D 667cf4062f 버그 수정 2020-04-26 03:23:32 +09:00
Hide_D ba442b1457 선전포고 최종 수정 2020-04-26 00:15:30 +09:00
Hide_D a07622d084 reqGold 수정 2020-04-25 23:57:31 +09:00
Hide_D 8855c92e73 수정 2020-04-25 23:54:40 +09:00
Hide_D 6a67a6a66b 디버그 수정2 2020-04-25 23:53:19 +09:00
Hide_D 6822c8137b 디버그 코드 2020-04-25 23:51:10 +09:00
Hide_D 76505aa4de 버그 수정 2020-04-25 23:39:42 +09:00
Hide_D 40fee137d4 의병모집 버그 수정 2020-04-25 23:22:51 +09:00
Hide_D 1f3259e907 의병 버그? 2020-04-25 23:18:32 +09:00
Hide_D 33b0c19d43 선포 확률 추가 수정 2020-04-25 23:15:26 +09:00
Hide_D 1de59279a6 선포 기준 변경2 2020-04-25 22:56:13 +09:00
Hide_D 184a43ccf5 선포 기준 변경 2020-04-25 22:37:51 +09:00
Hide_D efcb71e866 버그 수정 2020-04-25 21:45:41 +09:00
Hide_D 7bc720be77 버그 수정 2020-04-25 20:59:13 +09:00
Hide_D 9ecf6d3735 버그 수정 2020-04-25 20:47:11 +09:00
Hide_D ba968d6ff7 내정장 포상금 설정 2020-04-25 07:35:04 +09:00
Hide_D 5cd86a2766 선전포고 대상이 이상한 버그 수정 2020-04-25 07:02:13 +09:00
Hide_D 11325e6f07 지급률, 선포기준 수정 2020-04-25 06:43:45 +09:00
Hide_D 5b2b7dc03e 일부 설정값 수정 2020-04-25 06:30:01 +09:00
Hide_D 324a67c7da 버그 수정 2020-04-25 06:10:57 +09:00
Hide_D 6b54797aec 군량매매 버그 수정 2020-04-25 05:28:43 +09:00
Hide_D 4e7529ae44 버그 수정 2020-04-25 05:09:00 +09:00
Hide_D 086e61bb19 버그 수정 2020-04-25 04:55:59 +09:00
Hide_D c6eeeda1c3 버그 수정 2020-04-25 04:47:58 +09:00
Hide_D 6d642c8098 버그 수정 2020-04-25 04:33:53 +09:00
Hide_D 40c89a479f 버그 수정 2020-04-24 03:01:26 +09:00
Hide_D f43c811477 버그 수정 2020-04-24 02:56:09 +09:00
Hide_D 0a3277c6e7 버그 수정 2020-04-24 02:24:15 +09:00
Hide_D 667a8fea31 버그 수정 2020-04-24 02:04:41 +09:00
Hide_D 089bb027ae 버그 수정 2020-04-24 01:51:15 +09:00
Hide_D 6667d85623 버그 수정 2020-04-24 01:32:58 +09:00
Hide_D 2513465c6b 버그 수정 2020-04-24 01:28:41 +09:00
Hide_D 831266fe3c 버그 수정 2020-04-24 01:19:02 +09:00
Hide_D bea5cd1f52 버그 수정 2020-04-24 01:09:49 +09:00
Hide_D 961414559f 버그 수정 2020-04-24 00:44:31 +09:00
Hide_D ffa37160a5 버그 수정 2020-04-23 01:11:40 +09:00
Hide_D d856d12126 디버그 코드 제거 2020-04-23 00:44:57 +09:00
Hide_D 1dc16932b6 버그 수정 2020-04-23 00:36:45 +09:00
Hide_D db603c5ebd 버그 수정 2020-04-23 00:11:39 +09:00
Hide_D f837b71423 버그 수정 2020-04-22 23:55:13 +09:00
Hide_D a5b7259577 버그 수정 2020-04-22 23:36:21 +09:00
Hide_D 3f6eeb2a30 버그 수정 2020-04-22 23:35:06 +09:00
Hide_D f8434d7fe2 버그 수정 2020-04-22 23:26:28 +09:00
Hide_D b5cc8ad820 버그 수정 2020-04-22 23:22:39 +09:00
Hide_D 20c2d96dee 버그 수정 2020-04-22 23:18:50 +09:00
Hide_D c08a669aff 버그 수정 2020-04-22 03:18:01 +09:00
Hide_D c4fe77a5ba 버그 수정 2020-04-22 03:05:05 +09:00
Hide_D 6d6326e415 버그 수정 2020-04-22 02:31:53 +09:00
Hide_D 21a956eca8 버그 수정 2020-04-22 02:01:16 +09:00
Hide_D da1273c135 버그 수정 2020-04-21 02:06:03 +09:00
Hide_D aaf7870d88 range 버그 수정 2020-04-21 01:21:10 +09:00
Hide_D 03dffe1181 버그 수정 2020-04-21 01:19:24 +09:00
Hide_D 146010f3f5 명장일람 버그 수정 2020-04-20 23:04:03 +09:00
Hide_D 6526653540 디버그 코드 추가, 버그 수정 2020-04-20 03:08:08 +09:00
Hide_D 7b46a1b9ff 버그 수정 2020-04-20 00:47:35 +09:00
Hide_D 0608f9b3c7 버그 수정 2020-04-19 18:48:56 +09:00
Hide_D e63b46b004 버그 수정 2020-04-19 06:18:35 +09:00
Hide_D 17d9853e90 버그 수정 2020-04-19 05:38:25 +09:00
Hide_D 4d02639985 버그 수정 2020-04-18 22:49:50 +09:00
Hide_D 9677a55a5a db table 구조 일부 수정 2020-04-18 14:52:16 +09:00
Hide_D 87056a4052 history 관련 처리 변경 2020-04-18 14:36:05 +09:00
Hide_D aba9ee7b33 history column을 테이블로 분리 2020-04-18 14:07:07 +09:00
Hide_D ad2baeda2f 오타 수정 2020-04-18 03:59:16 +09:00
Hide_D eab8a3b94e city의 officer를 general로 이동 2020-04-18 03:57:58 +09:00
Hide_D 5d23032500 $_POST 삭제 2020-04-17 01:30:05 +09:00
Hide_D 5a2b6db3bb 투표 코드 수정 2020-04-17 01:23:52 +09:00
Hide_D 546c6a3227 인사부 일부 코드 수정 2020-04-17 01:15:19 +09:00
Hide_D 674018d2fc 통합 세력장수,암행부 query 2020-04-16 02:37:36 +09:00
Hide_D 39b65284bd experience, dedication 변경
expereince, dedication 변경을 add 함수로 변경
경험치,계급 변경을 '즉시' 하도록 변경(남은 부분 있음)
관직 임명을 c에서 j로 변경
2020-04-15 05:34:27 +09:00
Hide_D c0fee32c4c name2 -> owner_name (or orderName) 2020-04-15 02:44:06 +09:00
Hide_D 8428649377 부대 버그 2020-04-15 02:14:49 +09:00
Hide_D 430c792a9b 부대 편성 버그 수정 2020-04-15 02:13:58 +09:00
Hide_D 1e029ee517 부대 코드 변경 2020-04-15 02:13:16 +09:00
Hide_D dfbc837371 버그 수정 2020-04-14 02:38:39 +09:00
Hide_D 3e1bb44284 커맨드 활성화 2020-04-14 02:38:05 +09:00
Hide_D aacb6adb26 증축, 천도, 감축 2020-04-14 02:36:20 +09:00
Hide_D 95ac7454ae Merge branch 'ng_turn' of ssh://storage.hided.net:2525/devsam/core into ng_turn 2020-04-14 01:49:46 +09:00
Hide_D 85389c4a60 천도 추가 2020-04-14 01:49:40 +09:00
Hide_D 913289e0ef AI 구현 2020-04-13 02:45:24 +09:00
Hide_D 84efd5bfdf AI 구현중 2020-04-12 02:46:51 +09:00
Hide_D 33014dbd7d AI 구현중 2020-04-10 03:19:56 +09:00
Hide_D d0e20eb8d3 AI 커맨드 구현중 2020-04-09 03:13:14 +09:00
Hide_D a386999567 Util::range 추가 2020-04-09 02:07:50 +09:00
Hide_D 8519481f96 AI 구현중 2020-04-08 03:30:40 +09:00
Hide_D 97fdc095a5 AI턴 추가 구현 2020-04-07 02:55:59 +09:00
Hide_D 915243ee4a NPC 자동 턴 추가 구현 2020-04-06 03:01:20 +09:00
Hide_D 727e447899 AI 작업중 2020-04-04 04:52:18 +09:00
Hide_D e6ea5824f0 병종 코드, 숙련 코드 재설정
병종 상성 지정시 병종 단위가 아니라 병종 코드 자체로 지정 가능
2020-04-03 23:54:26 +09:00
Hide_D 8eee11cee9 Merge branch 'ng_turn' of ssh://storage.hided.net:2525/devsam/core into ng_turn 2020-04-01 20:24:51 +09:00
Hide_D 7aca3049d1 join 버그 수정? 2020-04-01 20:24:43 +09:00
Hide_D 03b8d0c388 AI 천도 알고리즘 2020-04-01 03:30:10 +09:00
Hide_D aa7d01f3d6 AI 뼈대 다시 잡는중 2020-03-31 02:50:07 +09:00
Hide_D b397c41c9e 신규 AI 구현 준비 2020-03-31 02:05:04 +09:00
Hide_D 0561cc3320 토너먼트값, 전투, 계략값을 분리 2020-03-29 05:03:49 +09:00
Hide_D 6f47e92050 버그 수정 2020-03-28 19:56:11 +09:00
Hide_D 9a67ac7509 __dir__ -> __DIR__ 2020-03-28 19:48:09 +09:00
Hide_D d922993eaf VAL2를 VAL_max로 변경 2020-03-28 19:43:40 +09:00
Hide_D 9fa2225283 Array type arg js 처리 2020-03-25 02:56:45 +09:00
Hide_D 35eadad96b 금액 단위를 GameConst로 이동, 원조 추가
arg 목록으로 amountList 추가
2020-03-25 02:54:33 +09:00
Hide_D 081416475e dev에서 쉽게 확인가능한 코드 이전 2020-03-23 02:11:00 +09:00
Hide_D 12492c842c MyISAM to Aria 2020-03-23 00:24:17 +09:00
Hide_D 68e01c1e73 dev 코드와 일치 2020-03-22 23:30:11 +09:00
Hide_D bdcc79ce34 dev와 composer 버전 일치 2020-03-22 23:22:50 +09:00
Hide_D 869ad39ddc 의병모집 버그 수정 2020-03-22 04:20:21 +09:00
Hide_D 30e1e35090 의병모집 구현 2020-03-22 04:16:42 +09:00
Hide_D 6c185ffd09 전략 DetailTitle/ isReservable 완화 2020-03-22 03:17:05 +09:00
Hide_D a9435f8f32 사령턴 커맨드 버그 수정 2020-03-22 02:47:44 +09:00
Hide_D 9ea8d3ec97 피장파장 추가 2020-03-22 02:34:04 +09:00
Hide_D d918234bb8 버그 수정, 허보 구현 2020-03-21 20:17:39 +09:00
Hide_D afbbbaa855 백성동원, 버그 수정 2020-03-21 19:13:13 +09:00
Hide_D a844ef31a2 오타 수정 2020-03-21 17:36:53 +09:00
Hide_D b469ce0504 수몰 구현, createGeneralObjFromDB 최적화 2020-03-21 17:36:36 +09:00
Hide_D ed2bc8c390 등용수락에서 destNationID 빠진것 추가 2020-03-13 01:45:42 +09:00
Hide_D cb246e859e 등용 수락 변경, Aux 처리 추가
nations->aux.joinedNations
dummyGeneral에 exp,ded 추가
scheme에서 nations 제거
2020-03-13 01:44:18 +09:00
Hide_D 3d6b99c004 필사즉생 디버그 수정 2020-03-12 22:02:50 +09:00
Hide_D 842942c0fe 필사즉생 구현 2020-03-12 21:57:57 +09:00
Hide_D 71c4a84833 불가침 메시지를 좀더 명확히 2020-03-12 15:59:36 +09:00
Hide_D d1bc434ced 불가침 외교 커맨드 부활. 버그 수정 2020-03-12 15:58:14 +09:00
Hide_D 59f7448aa7 Constraint 변경 내용 버그 수정 2020-03-11 22:17:26 +09:00
Hide_D 4408692565 Contraint Reason 추가 2020-03-11 21:49:41 +09:00
Hide_D 2e8607b811 지도 선택 살짝 수정 2020-03-11 21:38:49 +09:00
Hide_D 2f2890e582 선전포고에 지도 추가 2020-03-11 18:10:41 +09:00
Hide_D e2b39be3ff 선전포고 구현 2020-03-11 17:08:55 +09:00
Hide_D 7ada07a99a 버그 수정
랜덤임관, 모반시도
2020-03-08 22:55:10 +09:00
Hide_D 6b16573f6b 커맨드 brief 수정, 내무부 버그 수정 2020-03-08 20:01:49 +09:00
Hide_D 1de49fe998 증여 버그 수정, 출병을 현 코드에 맞게 수정 2020-03-08 19:30:49 +09:00
Hide_D 7109e66ad8 사령부 밀기 당기기 추가, 기존 코드 삭제 2020-03-08 13:26:56 +09:00
Hide_D d21c2f67ba 버그 수정, 커맨드 사이즈 자동 반영 2020-03-08 13:18:54 +09:00
Hide_D 0d39add09c 아이템 구매 버그 수정, 아이템 호칭문제 수정 2020-03-08 12:03:23 +09:00
Hide_D 5e1f7ea571 버그 수정 2020-03-08 09:57:32 +09:00
Hide_D 35c71bd21b arg 경고 회피, 사령부 버그 수정, 턴반복 추가 2020-03-07 23:12:59 +09:00
Hide_D e6a39f246d 발령,몰수,포상 활성화, 사령턴 턴 입력 활성화 2020-03-07 19:52:33 +09:00
Hide_D 65cd8af9e1 버그 수정, 사령부 UI 복구 2020-03-07 18:04:23 +09:00
Hide_D e916f2fc40 버그 수정.. 2020-03-06 20:01:11 +09:00
Hide_D 13da80ee85 버그 수정 2020-03-05 23:53:59 +09:00
Hide_D 4f4045363b 징병 폼 완료 2020-03-05 21:53:37 +09:00
Hide_D 9600e18c92 징병 구현중 2019-11-27 13:54:19 +09:00
Hide_D d5aefccadc 버그 수정2 2019-10-10 02:42:49 +09:00
Hide_D 9e64b268cf 버그 수정 2019-10-10 02:39:25 +09:00
Hide_D 0893bf6473 func_time_event 재작성, 수입관련 코드 수정 2019-10-10 02:36:42 +09:00
Hide_D 21f8b814e0 버그 수정. getStatValue 성능 향상 2019-10-09 15:57:18 +09:00
Hide_D 10fd22ba81 코드 일부 수정 2019-10-09 14:43:26 +09:00
Hide_D a3fef6c62f round 문제 수정 2019-10-09 12:36:06 +09:00
Hide_D d750167a00 버그 수정 2019-10-09 12:12:23 +09:00
Hide_D 241bf62fdc isConsumableNow 버그 수정 2019-10-09 11:38:28 +09:00
Hide_D bc5574615d 아이템 관련 버그 수정 2019-10-09 11:34:56 +09:00
Hide_D 48cac053fd 버그 수정 2019-10-09 03:19:50 +09:00
Hide_D 25837f6393 버그 수정 2019-10-08 02:29:07 +09:00
Hide_D b281362c98 구 코드 삭제 2019-10-07 02:06:02 +09:00
Hide_D e5050bb6c8 장수 커맨드 설명 추가 2019-10-07 00:38:52 +09:00
Hide_D 2d0c3ef881 소비 금액 반올림 2019-10-07 00:17:17 +09:00
Hide_D ee029aac10 커맨드 상세 입력 페이지 초기 구현 2019-10-07 00:09:13 +09:00
Hide_D da205c09f9 기본 커맨드 입력 가능하도록 구현 2019-10-06 22:39:13 +09:00
Hide_D 07317b86a2 오타 수정 2019-10-06 19:26:41 +09:00
Hide_D 79e2543266 NPC 수뇌 임명 버그 수정 2019-10-06 19:26:08 +09:00
Hide_D 303cbcd188 디버깅용 변경 2019-10-06 19:06:49 +09:00
Hide_D a47905541c 턴 표기 '드디어' 추가 2019-10-06 19:01:46 +09:00
Hide_D 4e988db50f 버그 수정 2019-10-06 16:14:41 +09:00
Hide_D 9dc3d83a77 세력 일람 쿼리 최적화 2019-10-06 16:05:20 +09:00
Hide_D 934c1b0cfe 버그 수정... 2019-10-06 14:49:41 +09:00
Hide_D 70181d95c7 전투 버그 수정 중 2019-10-06 02:49:54 +09:00
Hide_D 8a210103c0 장수 정보 버그 수정 2019-10-06 02:02:31 +09:00
Hide_D df96381759 기존 파일 제거 2019-10-06 01:46:38 +09:00
Hide_D 2006845ff7 턴 버그 수정, 아이템 관련 구 코드 수정 2019-10-06 01:45:50 +09:00
Hide_D 44f0e78086 turntime 관련 조정중 2019-10-05 10:52:31 +09:00
Hide_D 824956a34d 버그 수정 2019-10-05 03:11:44 +09:00
Hide_D 1e7e01b6b0 gen123 => officer432 2019-10-05 02:45:20 +09:00
Hide_D cd25aaaca6 버그 수정 2019-10-05 01:19:58 +09:00
Hide_D d481047eb4 iAction,name,info, buildiActionCache, mode, myInfo 2019-10-05 01:17:43 +09:00
Hide_D 1699ac6e08 일부 버그 수정 old 파일 삭제 2019-10-04 23:03:19 +09:00
Hide_D 79b7188578 weap -> weapon 2019-10-04 18:15:12 +09:00
Hide_D 843f469914 leader->leadership, power->strength 2019-10-04 18:07:42 +09:00
Hide_D 71254e86f4 버그 수정 2019-10-04 16:33:00 +09:00
Hide_D 07328847f4 아이템 속성이 동적으로 변경되어 static 제거 2019-10-04 14:30:45 +09:00
Hide_D 9181cbfee5 lbonus를TriggerGeneralLevel, calcLeadershipBonus로통합 2019-10-04 13:02:16 +09:00
Hide_D 4aef22aac8 stat 관련 데이터 수정 2019-10-04 12:50:48 +09:00
Hide_D 512266abf4 season merge 2019-10-04 11:44:03 +09:00
Hide_D ef64f180a2 season 반영 안된것 마저 추가 2019-10-04 11:39:08 +09:00
Hide_D 9e45800367 94f3906949...06f86c6c27 반영, 시즌 값, 부대정보, 왕조일람 2019-07-20 15:48:30 +09:00
Hide_D f027f7f225 훈련, 사기템 효과 두배 2019-07-20 15:32:01 +09:00
Hide_D 6f7ac86e7f c0a30a2640...ff00990520 까지 반영 2019-07-20 15:29:47 +09:00
Hide_D 93d298ef75 장수 생성 시 본닉 항상 추가. 사망시 본닉 출력 2019-07-20 15:22:51 +09:00
Hide_D 121a892c9a 버그 수정 2019-06-17 03:13:05 +09:00
Hide_D 9222e2bbdd 장비매매버그 수정 2019-06-17 03:11:33 +09:00
Hide_D fe78d82ace 장비매매버그 수정 2019-06-17 03:10:41 +09:00
Hide_D 77e98d9942 커맨드 선택 form 구현 중 2019-06-17 03:08:05 +09:00
Hide_D 2b1efae238 아이템 관련 속성 일부 변경, 유니크 획득 코드를 수정 2019-06-17 02:47:00 +09:00
Hide_D d70740b38c 이동 초기 구현 2019-06-16 21:41:31 +09:00
Hide_D 3ebb30795c 버그 수정, 턴 입력 form 준비 2019-06-16 21:07:08 +09:00
Hide_D 5d42730e9a js, css 출력을 위한 코드 추가 2019-06-16 17:07:43 +09:00
Hide_D 923777899e 도시 목록 임시 구현 2019-06-16 03:47:58 +09:00
Hide_D 05b9187a3b 스1 시나리오 업데이트 2019-06-14 23:56:06 +09:00
Hide_D 1198baba67 버그 수정 2019-06-13 02:43:25 +09:00
Hide_D d4b7cdc97c 아이템 int->string 반영 2019-06-10 02:20:48 +09:00
Hide_D bb7e93ac2d 쌀 거래만 가능하므로 아이템 거래는 삭제 2019-06-09 22:56:51 +09:00
Hide_D 59c0c6cfb8 아이템 코드를 String으로 바꾸었으므로 연동 대상 또한 변경 2019-06-09 22:50:39 +09:00
Hide_D 8699a43a22 버그 수정 2019-06-08 04:56:32 +09:00
Hide_D 5529651f91 TriggerCaller에 약간의 유연성 추가 2019-06-08 03:04:31 +09:00
Hide_D a6f225ae9d 구 코드 수정 2019-06-08 03:03:11 +09:00
Hide_D fceda31c11 전특 구현 완료 2019-06-08 02:56:15 +09:00
Hide_D e5a5281e10 BaseWarUnitTrigger, TriggerCaller 구조 변경, 클래스 반영 2019-06-06 22:32:35 +09:00
Hide_D ede1d89569 회피시도 추가, spl_object_hash를 spl_object_id로 변경 2019-06-06 03:34:47 +09:00
Hide_D 44b9ba96c3 전투 이벤트 갱신 2019-06-05 01:36:57 +09:00
Hide_D 7fd8bfbe4e 전투 스킬 세팅 중 2019-05-31 02:28:08 +09:00
Hide_D 17654633dc 서적 등록 2019-05-15 03:04:34 +09:00
Hide_D 8fd0a54018 명마, 무기 타입 변경 2019-05-15 03:00:00 +09:00
Hide_D efe8a476da 명마 등록 2019-05-15 02:29:21 +09:00
Hide_D ac0f6c6b6c 아이템에 consumable 개념 추가, GameConstBase에 아이템 준비 2019-05-13 03:17:48 +09:00
Hide_D 8c163515db 아이템 전량 구현, 말, 무기, 책 준비 2019-05-13 02:44:01 +09:00
Hide_D 7ce1e64ee8 WarUnitTrigger 개편, 병종 Trigger 개념 추가, 저지, 성벽부상무효 2019-05-13 00:49:44 +09:00
Hide_D b6e667a291 저격 다시 세팅, 아이템 namespace 버그 수정, 전투치료(의술) 구현 2019-05-12 21:03:21 +09:00
Hide_D 5c7522fd1f 가오픈 merge 2019-05-10 01:29:01 +09:00
Hide_D 85e9223603 서버의 오픈 시간을 기록했으므로 변경 2019-05-09 02:00:25 +09:00
Hide_D 943e2be676 커맨드 창에서 가오픈 때문에 턴이 이상하게 보이는 버그 수정 2019-05-09 01:59:06 +09:00
Hide_D 2f09df7521 가오픈 일자 표시 2019-05-09 01:34:06 +09:00
Hide_D 445e445e49 예약턴 초기 릴리즈 2019-05-09 01:28:49 +09:00
Hide_D a3925de127 턴 시간 동작 안내 2019-05-05 20:14:53 +09:00
Hide_D f20e4bd572 동작 시간 베이스로 변경 2019-05-05 20:13:48 +09:00
Hide_D 816c2ac1c4 devel merge 2019-05-05 17:58:27 +09:00
Hide_D e731371ab1 빙의 선택 시 성격과 국가 표기 2019-05-04 20:41:27 +09:00
Hide_D 5559693cb3 entrance 띄어쓰기 장수 전콘 문제 수정 2019-05-04 20:28:41 +09:00
Hide_D ca33c3b259 빙의에 약간의 편의성 추가 2019-05-04 20:09:52 +09:00
Hide_D a78fa98b3d 장수 목록에 pagenation 추가 2019-05-04 20:01:17 +09:00
Hide_D 956dc82555 장수 빙의에 장수 리스트 띄움 2019-05-04 19:46:55 +09:00
Hide_D d30a824481 디버그 코드 제거 2019-05-04 18:37:41 +09:00
Hide_D a643182eee 장수 일람 시간 문제 수정 2019-05-04 18:33:48 +09:00
Hide_D e1dbc46d8d 장수일람 API 생성 2019-05-04 18:33:09 +09:00
Hide_D e33d8776bc 서버 루트 js include 순서 변경 2019-05-04 17:08:36 +09:00
Hide_D f6d16883de 서버 기간 표기 수정 2019-05-04 17:05:48 +09:00
Hide_D 51bdd3bbfd 서버가 열린 경우 서버가 열린 기간을 표기하도록 수정 2019-05-04 17:03:03 +09:00
Hide_D 8f9ae78b8c 서버 리셋 권한자는 서버 시작, 또는 천통시 닫을 수 있음 2019-05-04 16:38:44 +09:00
Hide_D 584b7b8e45 영릉 장사 구지도 복구 2019-05-04 16:18:53 +09:00
Hide_D f74e903f1f 병종 전콘 문제 수정 2019-05-02 01:20:45 +09:00
Hide_D 4cedf112f5 sidebar 다시 제거 2019-05-02 00:53:09 +09:00
Hide_D d607a8da0f chess 맵 테스트로 추가, 전차전 php 코드 버그 수정 2019-05-02 00:50:40 +09:00
Hide_D 84a12e28df 지도 등을 추가할 경우 css, js를 새로 설정하는 기능 추가 2019-05-02 00:50:24 +09:00
Hide_D 54aa47d1a8 충차전 기본 코드 추가 2019-05-01 14:55:42 +09:00
Hide_D faaee4b945 충차전 코드 준비 2019-05-01 14:41:06 +09:00
Hide_D 0b46303f9f 시간이 지날 수록 접경 수도 농상, 성수의 디버프가 생김 2019-05-01 03:08:46 +09:00
Hide_D b98668bc60 부대장 삭턴 계산 방식 일부 변경 2019-05-01 02:57:48 +09:00
Hide_D 947e8e9512 코드 버그 수정 2019-05-01 02:47:27 +09:00
Hide_D 681918cb63 유니크 획득시 골고루 획득하도록 변경 2019-05-01 02:42:23 +09:00
Hide_D d0fae44430 도시 목록에도 전콘을 띄워줌 2019-05-01 02:33:49 +09:00
Hide_D 3e752461e8 스마트폰이더라도 neutralView(도시선택모드)에서는 두번선택 해제 2019-05-01 02:21:06 +09:00
Hide_D 1a9e6f3b1a m장 의병장 초 강화! 2019-05-01 02:06:51 +09:00
Hide_D 580275a8cf 로그인 버그 수정 2019-05-01 01:52:50 +09:00
Hide_D ee74771f16 부대장 이름을 정렬하기에 편리하도록 수정 2019-05-01 01:51:49 +09:00
Hide_D 81fa97d3ee 에러 로그 강화 2019-04-30 23:20:39 +09:00
Hide_D 00a6e9798f 수극을 통한 저격 예시 2019-04-29 02:04:45 +09:00
Hide_D 17a59cbdd5 병종이 행동에 전투에 event로 개입 가능하도록 수정 중 2019-04-29 01:01:47 +09:00
Hide_D d4c9a0a47a processWar 입출력 부근을 General Object로 변경 2019-04-29 00:13:25 +09:00
Hide_D 6423c22cf8 부대 번호를 부대장 ID로 변경 2019-04-28 20:50:25 +09:00
Hide_D e21fbaff83 WarUnit의 일부 요소를 General과 ActionSpecialWar 등으로 분리 2019-04-28 05:43:59 +09:00
Hide_D 99e6a2676b 버그 수정, 구조 변경 2019-04-28 03:49:03 +09:00
Hide_D ab47f40ee1 버그 수정 2019-04-28 02:54:01 +09:00
Hide_D a7f000e51e 버그 수정 2019-04-28 02:17:20 +09:00
Hide_D 0d9eabcaa0 버그 수정 2019-04-28 01:54:44 +09:00
Hide_D b1c63d7f5e 일부 수정. 버그 수정. 2019-04-28 00:18:36 +09:00
Hide_D 820c72820d 버그 수정 2019-04-24 02:47:50 +09:00
Hide_D 300065504b 버그 수정 2019-04-24 02:36:50 +09:00
Hide_D 8aa846b349 버그 수정 2019-04-24 01:17:21 +09:00
Hide_D ae8b94b2d7 redirect 변경 2019-04-23 12:03:36 +09:00
Hide_D 7670d55f3c 갱신 되돌림.. 2019-04-23 11:05:09 +09:00
Hide_D 528ab4e203 갱신방식 변경 2019-04-23 11:01:42 +09:00
Hide_D cf1dc90137 갱신 버튼 변경 2019-04-23 10:59:03 +09:00
Hide_D dd81dcc9c6 버그 수정 2019-04-21 22:29:08 +09:00
Hide_D a31c949734 db schema에 not null. 2019-04-21 22:17:23 +09:00
Hide_D 3536d5c413 err_log 강화 2019-04-21 22:15:41 +09:00
Hide_D 0e50216cee 버그 수정 2019-04-21 21:15:53 +09:00
Hide_D 16fed754a9 버그 수정 2019-04-21 16:57:05 +09:00
Hide_D c7748934b8 버그 수정 2019-04-21 16:27:57 +09:00
Hide_D d46b3154cc 버그 수정 2019-04-21 16:06:27 +09:00
Hide_D f8bcfba90e 버그 수정 2019-04-21 15:41:02 +09:00
Hide_D 45a4ca5298 부대장 숫자를 '능동적'으로 재 계산 2019-04-21 15:32:36 +09:00
Hide_D 88e3a9852b 버그 수정 2019-04-21 12:52:57 +09:00
Hide_D cf1f023379 버그 수정 2019-04-21 12:11:01 +09:00
Hide_D b4b6f5a1f7 버그 수정 2019-04-21 11:43:23 +09:00
Hide_D a21eef6e84 버그 수정 2019-04-21 04:53:14 +09:00
Hide_D 3beca8bba5 TimeUtil 버그 수정 2019-04-21 03:31:23 +09:00
Hide_D b5d66dba8a 버그 수정 2019-04-21 03:05:53 +09:00
Hide_D 24d01a2156 버그 수정 2019-04-21 03:04:08 +09:00
Hide_D 45d848cbb9 버그 수정 2019-04-21 02:55:32 +09:00
Hide_D e2f649dd35 버그 수정 2019-04-21 02:53:27 +09:00
Hide_D 183bffbc0e devel 반영 2019-04-21 02:42:43 +09:00
Hide_D a874415859 count를 써야할 자리에 MYDB_num_rows를 쓰는 코드 수정, 일부 정리 2019-04-21 02:34:22 +09:00
Hide_D 93b33ba383 천통시 최소 명전 등록 가능 연도를 GameConst로 2019-04-21 02:30:12 +09:00
Hide_D 26420719f3 $connect 쓰는 부분 일부 제거 2019-04-21 01:54:22 +09:00
Hide_D dc6a35d656 에러 반환 타입 수정 2019-04-21 01:47:01 +09:00
Hide_D 51da0bd7b7 버그 수정 2019-04-21 01:38:17 +09:00
Hide_D 1afb2c6883 오타 수정 2019-04-20 02:54:24 +09:00
Hide_D f78fcc2b71 여백 주기 2019-04-11 19:53:27 +09:00
Hide_D fb2d30f2c9 서버별 아이콘 적용 가능 2019-04-11 19:50:59 +09:00
Hide_D 8781e7c6ad tooltip 처리 방식을 지연 처리로 변경 2019-04-10 23:27:53 +09:00
Hide_D c34317b1e5 년, 월로 넘치더라도 그냥 자름 2019-04-08 01:56:57 +09:00
Hide_D b09730b422 스타크래프트 1 프로게이대전 추가 2019-04-08 01:51:38 +09:00
Hide_D 0f1725a7ab 인탐 조건에서 방랑군은 다시 불가능하게. 2019-04-08 01:45:05 +09:00
Hide_D b12e0358d6 방랑군이거나, 국가의 인구가 다 차더라도 인구 탐색 가능 2019-04-08 01:43:01 +09:00
Hide_D 7ef841746a 장수수 > 10, 집합장 제외 장수수 < 10일 때, 기술이 과도하게 오르는버그 수정 2019-04-08 01:33:49 +09:00
Hide_D 2b52b2379e 새 숙련도 공식 반영, 제곱식 기반에서 세제곱식 기반으로 2019-04-08 01:21:06 +09:00
Hide_D 8dd5965c44 진유저무쌍 릴리즈 2019-04-07 23:55:44 +09:00
Hide_D bc59521cc8 Merge commit 'f6eae2274f6d56403c0644829042ce4d72b80ec9' into ng_turn 2019-04-07 23:45:17 +09:00
Hide_D 815822ef40 v0.10.1까지 merge 마저 반영 2019-04-07 23:36:09 +09:00
Hide_D 9e6d33cc1a v0.10.1까지 merge 2019-04-07 23:35:54 +09:00
Hide_D 44df85f2bd [881bf08aee]v.0.10.0 커밋까지 반영 2019-04-07 23:23:46 +09:00
Hide_D 2c15c7087e devel 코드 merge 2019-04-07 22:58:44 +09:00
Hide_D 6b281628ed [f8bb7aaf30]ng_diplomacy 적용 2019-04-07 22:52:50 +09:00
Hide_D 9f74db0aff Merge commit 'b6f76562e2c6999af16502d802bd523a8484e167' into ng_turn 2019-04-07 22:44:43 +09:00
Hide_D 83ea5c7fa3 중첩된 내용 merge 2019-04-07 22:42:39 +09:00
Hide_D bf6fe3482b 이전 외교 메시지를 불러 올 수 있음 2019-04-07 22:31:08 +09:00
Hide_D f4d6803720 외교권자에게는 메시지를 보낼 수 없음 2019-04-07 22:30:00 +09:00
Hide_D 23c2a16286 1차 버그 수정 2019-04-07 22:29:46 +09:00
Hide_D afc301fad2 DB 스키마 변경 2019-04-07 22:29:29 +09:00
Hide_D 1c0a50e48f 중간반영 2019-04-07 22:28:57 +09:00
Hide_D 02e119d0da 외교부 틀 작성 2019-04-07 22:27:49 +09:00
Hide_D 06fcc383ce 국메 처리 방식을 변경. 국가간 메시지는 외교권자만 가능 2019-04-07 22:27:14 +09:00
Hide_D 408b1f76e4 외교메시지 수신 기준 변경중 2019-04-07 22:26:50 +09:00
Hide_D 3a879a37e2 [5f0258022a]기존 회의실, 기밀실 코드 삭제 2019-04-07 22:20:25 +09:00
Hide_D 9e1bb50d78 외교서신 응답 2019-04-07 22:17:46 +09:00
Hide_D 25dcf426b1 파일 명을 namespace를 고려하여 수정 2019-04-07 22:17:33 +09:00
Hide_D 7b7baaea62 외교 서신 추가 기능 2019-04-07 22:17:13 +09:00
Hide_D 36d83804d0 게시물 코드 2019-04-07 22:16:43 +09:00
Hide_D 7c46d2e27f 게시판 글, 댓글 작성 초안 2019-04-07 22:16:19 +09:00
Hide_D d4acad33ea [b422cac734]권한 세팅 2019-04-07 22:15:53 +09:00
Hide_D 91cc1159bc 왕 무장 관직 순서 변경 2019-04-07 22:08:19 +09:00
Hide_D 21b7068c90 무관 최종 관직을 실제 삼국지 관직 순서에 맞게 변경 2019-04-07 22:05:33 +09:00
Hide_D 682d2bf922 [8d6c4ed713]시중->종사 2019-04-07 21:34:36 +09:00
Hide_D 3ff6788405 [1ddce7ac2e]게시물 구조 설정 2019-04-07 21:33:09 +09:00
Hide_D e59a8606ab tui-editor와 새 게시판 준비 2019-04-07 21:31:28 +09:00
Hide_D 157285ddb6 permission, penalty 대응 준비 2019-04-07 21:31:03 +09:00
Hide_D f49c3e0ff7 [18d11b2c6a]장수 schema 수정 2019-04-07 21:30:24 +09:00
Hide_D 345877b9fd [00bbf4eae2]버튼 이동 코드 정리 2019-04-07 21:28:45 +09:00
Hide_D 37e4105585 [3cf9d39cf2]DB 스키마 정리, diplomacy 테이블 정리, 코드 정리 2019-04-07 21:27:08 +09:00
Hide_D 4a05b59b4b 병합 충돌 오타 수정 2019-04-07 21:12:20 +09:00
Hide_D 57322d75d7 [8ee2def02a]국법 기능 제거. 외교부를 위한 자리 추가 2019-04-07 21:11:46 +09:00
Hide_D 4ccc2c1f71 DB 스키마 준비 2019-04-07 21:08:38 +09:00
Hide_D 652b32619d [51e9de0e79]DB 스키마 준비 2019-04-07 21:08:28 +09:00
Hide_D 57b3611965 걸그룹 전콘 문제 일부 수정 2019-04-07 21:06:47 +09:00
Hide_D afbf9e619a 걸그룹 대전 0.5 반영 2019-04-07 21:06:23 +09:00
Hide_D 060b1da388 [ca6e97be65]지급율 -> 지급률 2019-04-07 21:04:08 +09:00
Hide_D 38024b6be4 외교 메시지는 삭제 할 수 없도록 2019-04-07 21:03:01 +09:00
Hide_D 6aede6e48b 국메 삭제 가능 2019-04-07 21:02:45 +09:00
Hide_D b27adfbe27 디버그 코드 제거 2019-04-07 21:02:18 +09:00
Hide_D b28e3b2a00 메시지 삭제 기능 추가 2019-04-07 21:01:38 +09:00
Hide_D ffe4374519 메시지 타이밍 정책 일부 수정 2019-04-07 21:01:17 +09:00
Hide_D 793df087ae 페이지당 갱신 시간을 10초에서 5초로 변경 2019-04-07 20:58:19 +09:00
Hide_D 85eadd5856 메시지를 띄울 때 flex 적용 2019-04-07 20:57:48 +09:00
Hide_D 359efe0036 로그아웃 되었을 경우 무한히 호출하는 버그 수정 2019-04-07 20:56:56 +09:00
Hide_D 3186691b7b 이전 메시지 가져오기 기능 추가 2019-04-07 20:56:19 +09:00
Hide_D 044c795f38 부상으로 인한 전투 우선순위 감소를 완화 2019-04-07 20:55:31 +09:00
Hide_D f7128449ca 등갑, 맹수 너프 2019-04-07 20:54:27 +09:00
Hide_D 3d0c5165b7 자객병의 기동을 8로 상향 2019-04-07 20:54:00 +09:00
Hide_D fc6cda86df selector에 검은색 추가 2019-04-07 20:53:35 +09:00
Hide_D 59877e181e 도시 목록에 select2를 시험 적용 2019-04-07 20:52:41 +09:00
Hide_D 506b1a17d1 암행부의 장수수에서 '부대장'이 제외됩니다. 2019-04-07 20:42:15 +09:00
Hide_D 214c2ba0ad 임관턴이 어찌저찌 어거지로 동작하던 버그 수정 2019-04-07 20:40:30 +09:00
Hide_D 387312bc87 랜덤임관 인자 버그 수정 2019-04-07 20:36:49 +09:00
Hide_D 3d3da04e58 [4103831401,+]부대장은 기술연구, 전투시 기술,전략턴에 영향을 주지 않도록 변경 2019-04-07 20:33:47 +09:00
Hide_D 7ec0cbb43c 통합, 합병시 부대장까지 같이 포함되는 문제 수정 2019-04-07 19:58:38 +09:00
Hide_D 1cd834579c select2 설치 2019-04-07 19:56:52 +09:00
Hide_D a11005c14b [eaa9e6d840]불필요한 가로바 길이 줄임 2019-04-07 19:55:54 +09:00
Hide_D ea1480e286 [e5da1905c6]추방시 명성 안깎이는 버그 수정 2019-04-07 19:53:30 +09:00
Hide_D f1dd328c38 [864b94f62a]반계 상향 2019-04-07 19:51:19 +09:00
Hide_D 44295de206 [cac19cad4d]수비 우선 순위를 부상여부, 수뇌여부, 훈사 여부를 반영하도록 변경 2019-04-07 19:48:51 +09:00
Hide_D b273082492 세력 장수 쿼리 버그 수정 2019-04-07 17:15:16 +09:00
Hide_D da088d88ba 세력장수 본닉 2019-04-06 14:46:07 +09:00
Hide_D fd13570074 천통시 장수 일람 2019-04-06 14:25:12 +09:00
Hide_D b5630a9dae 오타(?) 수정 2019-03-26 15:47:17 +09:00
Hide_D 0e2cab6409 명전 재 갱신 코드 추가 2019-03-26 15:44:04 +09:00
Hide_D 38dc587318 명전 등록시 문자 문제 수정 2019-03-26 15:36:38 +09:00
Hide_D 6fbddcb7c2 cache control 수정 2019-03-22 09:30:24 +09:00
Hide_D df1df2964d session_cache_limiter 삭제. no-cache가 기본값임 2019-03-22 09:26:52 +09:00
Hide_D 9b9c2546c8 확률 추가 수정 2019-03-15 15:15:00 +09:00
Hide_D 6ce0e72b33 인탐 확률 핫픽스 2019-03-15 15:00:12 +09:00
Hide_D a7784d7870 지연 threshold 증가 2019-03-10 17:20:44 +09:00
Hide_D 306ca3e04f 점령 시 도시 관직 초기화. 코드 정리 2019-03-10 17:19:35 +09:00
Hide_D 82988b0e08 장사-영릉이 이어진걸로 나오는 일반지도 버그 수정 2019-03-10 14:19:29 +09:00
Hide_D 8b27d0e249 불가침 서신 거부 불가능한 버그 수정 2019-03-10 00:47:13 +09:00
Hide_D bfae547240 은퇴 연령 값을 GameConst로 이동 2019-03-09 17:08:11 +09:00
Hide_D 0abd026f78 인탐, 의병에서 발생할 수 있는 숙련 예외 케이스 제거 2019-03-09 16:50:31 +09:00
Hide_D 3362a76de7 값 실수 수정 2019-03-09 16:41:41 +09:00
Hide_D 355b6c2e7d 인탐 확률 추가 수정 2019-03-09 16:23:47 +09:00
Hide_D 4e3c643e43 시나리오 최대 장수값 조절 2019-03-09 13:45:29 +09:00
Hide_D 760cb97db4 인탐 가속 조건 강화 2019-03-09 06:12:26 +09:00
Hide_D 0be6f7f57e 오타 수정 2019-03-09 03:43:15 +09:00
Hide_D d31223fa0c 커맨드 attr 수정 2019-03-09 02:30:12 +09:00
Hide_D 86ee9befc1 커맨드 버그 수정? 2019-03-09 02:26:50 +09:00
Hide_D d5689b061f 의병 고용으로는 무지장이 안나옴 2019-03-09 01:59:41 +09:00
Hide_D a3c4da4455 의병고용 버그 수정 2019-03-09 01:57:51 +09:00
Hide_D ee9f97f917 m장 합산 능력치 버그 수정 2019-03-09 01:05:47 +09:00
Hide_D 270c7377de 사령턴 실행후 재 로드시 수비 켬끔 리셋 관련 버그 수정 2019-03-09 00:59:16 +09:00
Hide_D 9044b57306 영입 금지시에는 인탐 확률 보정 없음 2019-03-09 00:41:38 +09:00
Hide_D 9ad815a44a Revert "커밋 취소"
This reverts commit 0843da7a7c.
2019-03-09 00:40:16 +09:00
Hide_D b7e432228b 커밋 취소 2019-03-09 00:39:13 +09:00
Hide_D 78da30f2ad m장이 아주 적을땐 잘 뽑히도록 2019-03-09 00:33:14 +09:00
Hide_D aeea53017f 인탐 장수 비율 4:4:2로 변경. 인탐장 숙련도 평준화. 인탐 확률 상승. 발견 추가. 2019-03-09 00:15:51 +09:00
Hide_D f21ebfc366 관리자 턴 당김 버그 수정 2019-03-09 00:00:00 +09:00
Hide_D 2549aa5809 의병, 인탐장도 적은 비중으로 장수 카운트에 추가 2019-03-08 22:20:45 +09:00
Hide_D b733b70ad8 황제가 있을 경우 황제. 없으면 이전 천통 군주의 명으로 토너먼트 개최 2019-03-06 01:44:24 +09:00
Hide_D f9f59bd7c2 토너먼트 변경이 변경 횟수를 깎지 않음. 수비 끔 시 훈사 3 감소 2019-03-06 01:09:34 +09:00
Hide_D 58933a6bcd 인자 버그 수정 2019-03-06 00:40:56 +09:00
Hide_D 45d7a29a95 수비 순서에 훈사 영향을 더 강하게 주도록 변경 2019-03-06 00:38:35 +09:00
Hide_D e9d1fdb4ee 두번 탭 해 도시 이동 기능 재 부활, 옵션 설정 가능 2019-03-05 23:06:34 +09:00
Hide_D 2785ca9f31 천통 시에는 계략 명장이 보임 2019-03-05 02:32:42 +09:00
Hide_D 12912a62aa 아이템에 장수명을 띄우는것은 비합리적으로 보임 2019-03-05 02:29:10 +09:00
Hide_D 2c2b078514 명장일람에서 계략 시도 장수 본닉이 뜨는 문제 수정 2019-03-05 02:27:22 +09:00
Hide_D 110294103f 천통 후에는 명장 일람에 장수 본닉이 뜨도록 2019-03-05 02:23:28 +09:00
Hide_D a9f3b839ec 명전에서 장수의 본닉이 뜨도록 2019-03-05 02:11:52 +09:00
Hide_D 6bd677ad6f 은퇴 후 명전 등록 시 '이전 값보다 높아진 경우'에만 경신하도록 수정 2019-03-05 01:45:03 +09:00
Hide_D 7d1c5f3510 집합장이 군주인 경우 아무에게나 선양 2019-03-05 01:20:27 +09:00
Hide_D a49508fd20 외교권자 등에서 인사부 연동이 안되는 버그 해결 2019-02-27 23:33:18 +09:00
Hide_D 5870213ff0 권한 관련 버그 수정 2019-02-27 23:23:53 +09:00
Hide_D 65c3d7f925 선양 버그 수정 2019-02-25 21:27:17 +09:00
Hide_D 33f4fd8fee 외교권자 버그 수정 2019-02-25 21:25:29 +09:00
Hide_D 9bdc34dc42 버그 수정 2019-02-24 19:41:00 +09:00
Hide_D ff654df997 본인 국가 아닌 곳에 임명 가능한 버그 수정 2019-02-24 01:12:59 +09:00
Hide_D b7758da2f3 회의실 기밀실 '타이틀'이 거꾸로 표기되는 버그 수정 2019-02-24 00:56:25 +09:00
Hide_D 747089f1a8 게시판 위아래 가운데 정렬.. 2019-02-24 00:55:13 +09:00
Hide_D 9ee3021b76 NPC 군주는 유저장 수뇌에게 외교권자 권한 부여 2019-02-24 00:52:42 +09:00
Hide_D 0c60ea66e3 자국 내 외교권자에게는 메시지 보낼 수 있도록 수정 2019-02-24 00:42:34 +09:00
Hide_D c3bb312b5f 선양시 외교권자 지정 코드 수정 2019-02-24 00:37:01 +09:00
Hide_D 7447a42d40 외교 서신 수락시, 국메, 외교 둘다 뜨도록 수정 2019-02-24 00:32:22 +09:00
Hide_D 3e9cc367af 게시판 이름 ㅇ 2019-02-24 00:23:45 +09:00
Hide_D 4c1790014f 메시지 변경 2019-02-20 01:40:56 +09:00
Hide_D 03fc7a579a 비재야망명 버그 수정 2019-02-17 23:57:26 +09:00
Hide_D a53db257cf 외교부 버그 수정 2019-02-14 21:28:15 +09:00
Hide_D b093cab493 한칸 띄움 2019-02-03 02:18:07 +09:00
Hide_D 9b484dc819 간이 툴바 생성 2019-02-03 01:54:58 +09:00
Hide_D 5ab26a9f8c 메시지 자동 링크 2019-02-03 00:28:29 +09:00
Hide_D b800a63bd2 고대무장 신대륙국가 추가 2019-01-31 02:24:18 +09:00
Hide_D 43a5e47fb3 애니집결 5차 반영 2019-01-31 02:14:10 +09:00
Hide_D 319545106e 외교부 버튼 조건 변경 2019-01-30 02:54:38 +09:00
Hide_D 39b261b8a0 버그 수정 2019-01-30 00:04:33 +09:00
Hide_D c9e61d1098 버그 수정 2019-01-30 00:03:36 +09:00
Hide_D 0bffdaa5fc 외교 메시지 과거 권한 문제 수정 2019-01-30 00:02:28 +09:00
Hide_D 9228510834 댓글 입력도 투명하게 2019-01-29 23:46:47 +09:00
Hide_D 0b002a8946 댓글 엔터시 입력 2019-01-29 23:43:37 +09:00
Hide_D ad43ddabe6 Merge branch 'ng_diplomacy' of ssh://storage.hided.net:2525/devsam/core into ng_diplomacy 2019-01-29 23:40:35 +09:00
Hide_D 24c022a329 회의실 기밀실 템플릿 2019-01-29 23:40:28 +09:00
Hide_D 0e48cee0d6 하야 임관시 권한 초기화 2019-01-29 17:12:04 +09:00
Hide_D 4ad1794d95 버그 수정 2019-01-29 02:57:24 +09:00
Hide_D 46cf25b585 승인시 이전 내용 중첩 2019-01-29 02:53:39 +09:00
Hide_D b3d78fc30f 파기 요청 추가 2019-01-29 02:48:41 +09:00
Hide_D 556bc06da4 시중->종사, 감찰부 권한 정리 2019-01-28 20:33:44 +09:00
Hide_D 7e8f9c463b 공개, 비밀 문구 변경 2019-01-26 06:58:12 +09:00
Hide_D 568c7779b6 템플릿 미완 부분 수정 2019-01-26 06:56:19 +09:00
Hide_D 0a0d237f4d 대체된 메시지 보기 가능 2019-01-26 06:44:34 +09:00
Hide_D c243ccbdce 틀 일부 수정 2019-01-26 06:36:48 +09:00
Hide_D 64b79d6af5 외교부 추가 2019-01-26 06:30:29 +09:00
Hide_D 016c0f3743 외교 메시지 필터링에 invalid 옵션 추가 2019-01-26 04:03:15 +09:00
Hide_D fd1599e0a7 외교 메시지 전송시 알림 2019-01-26 03:50:08 +09:00
Hide_D 7408aa6b72 조언자 인원수로 보여줌 2019-01-26 03:40:01 +09:00
Hide_D e6b2107fa9 외교부 틀 작성중. 재야의 외교 메시지는 항상 보이도록 2019-01-26 03:31:04 +09:00
Hide_D 9aff52eaad 권한 문제 수정 2019-01-25 23:29:35 +09:00
Hide_D bf5bda0f85 내무부 권한 수정 2019-01-25 22:35:49 +09:00
Hide_D ffbf2d0a93 국적 변경시 permission 초기화 2019-01-25 20:30:02 +09:00
Hide_D 82f59ef5a2 게시물 순서 변경 2019-01-25 20:17:36 +09:00
Hide_D c2c40abbb4 외교권자 기밀실 버튼 활성화 2019-01-25 19:49:29 +09:00
Hide_D bb54d732d0 수락 불가능한 문제 해결 2019-01-25 19:46:32 +09:00
Hide_D eee4e0c676 없는것보단 나은 회의실 css 2019-01-25 19:40:13 +09:00
Hide_D d9457ae017 내무부 비고란 제거 2019-01-25 19:34:36 +09:00
Hide_D bbc0b18b19 외교 메시지 삭제 조건 완화 2019-01-25 19:32:13 +09:00
Hide_D da7651311e 메시지 삭제가 안되던 버그 수정 2019-01-25 19:30:33 +09:00
Hide_D 72846f0817 인사부 수정 2019-01-25 19:22:30 +09:00
Hide_D 05ef3387ab 외교권자 임명 대기중 2019-01-25 03:16:34 +09:00
Hide_D eed44e5737 외교권자 목록 출력 2019-01-25 02:18:20 +09:00
Hide_D 27c7a85a21 게시판 기능만 동작 2019-01-25 02:11:54 +09:00
Hide_D 4f6dd046ec 게시판이 '동작만 함' 2019-01-25 01:51:26 +09:00
Hide_D 89fad9ada7 이전 외교 메시지를 불러 올 수 있음 2019-01-25 01:39:45 +09:00
Hide_D bc31b49b99 외교권자에게는 메시지를 보낼 수 없음 2019-01-25 01:28:06 +09:00
Hide_D 09444e3624 1차 버그 수정 2019-01-25 01:02:13 +09:00
Hide_D 7586243a95 DB 스키마 변경 2019-01-25 00:13:04 +09:00
Hide_D 1e1c7801e1 중간반영 2019-01-24 03:34:03 +09:00
Hide_D a363f6ef5f 외교부 틀 작성 2019-01-23 03:11:07 +09:00
Hide_D 334e1fd2da 국메 처리 방식을 변경. 국가간 메시지는 외교권자만 가능 2019-01-23 02:36:03 +09:00
Hide_D 2e8e29e93c 외교메시지 수신 기준 변경중 2019-01-23 01:37:40 +09:00
Hide_D 5e5a1a3668 기존 회의실, 기밀실 코드 삭제 2019-01-22 03:17:44 +09:00
Hide_D b93b464ebf 외교서신 응답 2019-01-22 02:47:27 +09:00
Hide_D 842ba46a95 파일 명을 namespace를 고려하여 수정 2019-01-21 02:25:54 +09:00
Hide_D 03b27d8e8f 외교 서신 추가 기능 2019-01-21 02:23:23 +09:00
Hide_D c11b41c6ba 게시물 코드 2019-01-21 02:00:48 +09:00
Hide_D 018cc526ee 게시판 글, 댓글 작성 초안 2019-01-21 01:45:32 +09:00
Hide_D edf4508e6b 권한 세팅 2019-01-18 03:01:02 +09:00
Hide_D d26a1f0312 왕 무장 관직 순서 변경 2019-01-17 23:01:05 +09:00
Hide_D 2984f6a453 무관 최종 관직을 실제 삼국지 관직 순서에 맞게 변경 2019-01-17 22:59:54 +09:00
Hide_D a00058d959 시중->종사 2019-01-17 22:44:18 +09:00
Hide_D 8e56a457f1 게시물 구조 설정 2019-01-17 03:12:26 +09:00
Hide_D 74d5f021cd tui-editor와 새 게시판 준비 2019-01-17 02:54:58 +09:00
Hide_D a37715315d permission, penalty 대응 준비 2019-01-16 02:47:48 +09:00
Hide_D d9c9977610 장수 schema 수정 2019-01-16 02:26:28 +09:00
Hide_D c2f0cbb10a 버튼 이동 코드 정리 2019-01-16 02:18:42 +09:00
Hide_D a34d00d822 DB 스키마 정리, diplomacy 테이블 정리, 코드 정리 2019-01-16 01:59:07 +09:00
Hide_D 9924ec6963 국법 기능 제거. 외교부를 위한 자리 추가 2019-01-12 18:53:01 +09:00
Hide_D 9036201887 DB 스키마 준비 2019-01-12 07:21:34 +09:00
Hide_D b2435d2430 걸그룹 전콘 문제 일부 수정 2018-12-08 20:55:48 +09:00
Hide_D afd6148770 걸그룹 대전 0.5 반영 2018-12-02 22:28:10 +09:00
Hide_D b70b58a35a 지급율 -> 지급률 2018-12-01 23:37:40 +09:00
Hide_D df963c2780 외교 메시지는 삭제 할 수 없도록 2018-12-01 18:36:43 +09:00
Hide_D 1b732c76e6 국메 삭제 가능 2018-11-30 21:49:19 +09:00
Hide_D f9489b0173 디버그 코드 제거 2018-11-30 21:44:59 +09:00
Hide_D 18942c55ae 메시지 삭제 기능 추가 2018-11-30 21:29:31 +09:00
Hide_D bf34b2f1ca 메시지 타이밍 정책 일부 수정 2018-11-30 19:03:26 +09:00
Hide_D a717a021c2 페이지당 갱신 시간을 10초에서 5초로 변경 2018-11-30 02:05:33 +09:00
Hide_D dcf718d592 메시지를 띄울 때 flex 적용 2018-11-30 01:51:24 +09:00
Hide_D f5eeb2b839 로그아웃 되었을 경우 무한히 호출하는 버그 수정 2018-11-30 01:24:45 +09:00
Hide_D bc435adc11 이전 메시지 가져오기 기능 추가 2018-11-30 01:18:07 +09:00
Hide_D aeb8e82cbd 부상으로 인한 전투 우선순위 감소를 완화 2018-11-28 23:43:42 +09:00
Hide_D 5cb2ed3ccd 등갑, 맹수 너프 2018-11-28 01:24:29 +09:00
Hide_D 93b1864d1b 자객병의 기동을 8로 상향 2018-11-28 01:20:32 +09:00
Hide_D a6efffda45 selector에 검은색 추가 2018-11-28 01:14:43 +09:00
Hide_D c89d6f1a58 도시 목록에 select2를 시험 적용 2018-11-28 01:02:56 +09:00
Hide_D d4f16abfac 암행부의 장수수에서 '부대장'이 제외됩니다. 2018-11-28 00:29:53 +09:00
Hide_D 8529f3f355 임관턴이 어찌저찌 어거지로 동작하던 버그 수정 2018-11-28 00:26:29 +09:00
Hide_D 2eb136827d 랜덤 임관을 더 고르게 합니다. 2018-11-28 00:18:09 +09:00
Hide_D 9594e6eb32 부대장은 기술연구, 전투시 기술 상승에 영향을 주지 않도록 변경 2018-11-28 00:16:34 +09:00
Hide_D 9e8111994a 통합, 합병시 부대장까지 같이 포함되는 문제 수정 2018-11-28 00:14:36 +09:00
Hide_D af0c2b7129 select2 설치 2018-11-27 23:52:12 +09:00
Hide_D 96b73a0cef 도시 목록 등 불필요한 가로바 길이 줄임 2018-11-26 22:29:11 +09:00
Hide_D 6c290ee2d3 추방시 명성 안깎이는 버그 수정, 첫 하야시 패널티 없음 2018-11-26 18:12:21 +09:00
Hide_D ca53e3de3a 반계 상향 2018-11-26 18:08:57 +09:00
Hide_D 6ea3ec700a 수비 우선 순위를 부상여부, 수뇌여부, 훈사 여부를 반영하도록 변경 2018-11-26 15:17:51 +09:00
Hide_D fe3355e08e gitignore 변경 2018-11-26 15:08:33 +09:00
Hide_D 42f08f5027 첫 화면 띄우기 성공 2018-11-26 04:05:34 +09:00
Hide_D 7a1c8882e6 general_turn, nation_turn 대응 2018-11-26 01:32:42 +09:00
Hide_D 2c193e7e48 버그 1차 수정 2018-11-26 00:03:11 +09:00
Hide_D 9714c1c9f6 git ignore 변경, 소소한 버그 수정 2018-11-25 21:01:39 +09:00
Hide_D c8f72b5f14 j_set_general_command, j_set_nation_command 구현 2018-11-25 20:35:29 +09:00
Hide_D be0439f771 이전 디렉토리를 이동하도록 변경 2018-11-25 00:58:17 +09:00
Hide_D 43da95b4a5 디버그 코드 제거 2018-11-25 00:51:59 +09:00
Hide_D 3d93a63caa php의 rename을 OS의 mv로 변경 2018-11-25 00:50:41 +09:00
Hide_D 9550607da3 디버그 모드 2018-11-25 00:39:49 +09:00
Hide_D d5d9798913 rename 재수정 2018-11-25 00:37:24 +09:00
Hide_D 6cfe08235f base을 filename으로 수정 시도 2018-11-25 00:35:11 +09:00
Hide_D 49eb850ff1 파일명 에러 수정 2018-11-25 00:29:26 +09:00
Hide_D 5a558583d2 폴더명 실수.. 2018-11-24 23:46:04 +09:00
Hide_D 1e5f0d0555 이전 디렉토리를 이동하도록 변경 2018-11-24 23:44:33 +09:00
Hide_D e2b0b03c96 button에 type="button" 지정 2018-11-24 22:38:09 +09:00
Hide_D b9fb9f1b34 사령턴 반환값 수정 2018-11-24 22:29:50 +09:00
Hide_D 52fd932fd8 사령부 UI 간결화, (구현은 아직), 일부 변수명 변경 2018-11-24 22:22:27 +09:00
Hide_D b0cc200df7 data-reqArg 추가 2018-11-23 03:13:03 +09:00
Hide_D 05b32db37d 커맨드 출력 준비 2018-11-23 03:12:08 +09:00
Hide_D 41f7192532 기본 커맨드 지정 2018-11-23 02:23:19 +09:00
Hide_D fa420303dc $reqArg 지정 2018-11-23 02:07:44 +09:00
Hide_D b7fd539755 불가침 제의 구현 2018-11-22 02:48:42 +09:00
Hide_D cfb8b03446 diplomacy_ticket 테이블 추가 2018-11-22 02:26:07 +09:00
Hide_D 712601041d 구 불가침 코드 삭제 2018-11-22 02:15:24 +09:00
Hide_D 36093eccaf 선전포고 추가, DisallowDiplomacyStatus 구현 변경 2018-11-22 02:13:23 +09:00
Hide_D 58eb6d4210 sabotagelimit을 strategic_cmd_limit로 변경 2018-11-18 03:57:22 +09:00
Hide_D 2166429cbf 발령 구현 2018-11-18 03:57:09 +09:00
Hide_D 236ab10b11 단련 버그 수정 2018-11-17 21:17:39 +09:00
Hide_D 99142fdde3 몰수, 포상 구현, 증여 헌납 버그 수정 2018-11-17 15:40:34 +09:00
Hide_D ca6755d8b5 func_process_chief 백업 2018-11-17 02:17:09 +09:00
Hide_D 92ad333863 선동, 탈취, 파괴 구현 2018-11-17 01:57:21 +09:00
Hide_D 4c48272b4c 화계 구현 2018-11-17 01:44:54 +09:00
Hide_D ab5bd1db69 item의 static 변경 2018-11-17 01:33:17 +09:00
Hide_D 5d1cd10f5d sabotage 백업 2018-11-17 00:24:36 +09:00
Hide_D ef784be082 func_process_personnel.php 삭제 2018-11-17 00:24:12 +09:00
Hide_D 855c41a0e9 방랑 구현 2018-11-17 00:22:53 +09:00
Hide_D 6ef9667f72 Constraint 수정 2018-11-16 23:35:43 +09:00
Hide_D 068d384e7a 모반 구현 2018-11-15 03:42:55 +09:00
Hide_D c3699a8595 ConstraintHelper 추가 2018-11-15 03:33:44 +09:00
Hide_D 2cb7513355 국방 표기 방식 변경 2018-11-15 01:23:32 +09:00
Hide_D c58caeda4c 국방 표기 방식 변경 2018-11-13 19:55:40 +09:00
Hide_D 26fc56f2b8 extractMissingPostToGlobals(); 제거 2018-11-13 02:11:00 +09:00
Hide_D c44ae2f00c extractMissingPostToGlobals(); 제거 2018-11-13 02:10:17 +09:00
Hide_D a00b62ffcc 글 넘치는 것 해결 2018-11-11 23:52:54 +09:00
Hide_D 6a9e7aa89d msg overflow 적용 2018-11-11 23:32:19 +09:00
Hide_D 6206b38a78 해산 수정 2018-11-11 23:30:39 +09:00
Hide_D 1767bfa70d nextRuler 재구현 2018-11-11 21:29:06 +09:00
Hide_D b1d6611923 해산 구현 2018-11-11 20:46:12 +09:00
Hide_D a6a713f40e 랜임 코드 수정 2018-11-11 20:28:05 +09:00
Hide_D e76ad04207 선형 랜덤에서 값이 음수가 들어가는 경우 보정 2018-11-11 19:53:49 +09:00
Hide_D a231adbfdd 랜덤 임관시 제곱근에서 선형으로 변경 2018-11-11 19:44:14 +09:00
Hide_D 88f97ecb4e defulatGold, defaultRice 개념 지정 2018-11-11 19:38:43 +09:00
Hide_D 68a471b859 선양 추가 2018-11-09 00:14:26 +09:00
Hide_D 9393324e1f 인증 토큰 '초기화' 문구를 '연장'으로 변경 2018-11-08 16:01:01 +09:00
Hide_D 944931f7d1 거병 추가 2018-11-06 02:50:25 +09:00
Hide_D 5a56be8a75 하야 메시지 출력 수정 2018-11-06 01:34:40 +09:00
Hide_D fe7aebae05 건국 구현 2018-10-31 02:39:40 +09:00
Hide_D b6c3b0cdc3 방랑군이 아니어도 건국 가능한 버그 수정 2018-10-29 03:15:45 +09:00
Hide_D fd734fadbc 건국 조건 설정 2018-10-29 03:14:03 +09:00
Hide_D a3dc250698 글자 너비를 반각 18자까지 확장 2018-10-29 02:39:23 +09:00
Hide_D 3f2d36284f 랜임 코드 마저 반영 2018-10-28 03:35:32 +09:00
Hide_D 60d5184a7b 랜덤 임관 깃수용 코드 이식 2018-10-28 03:32:03 +09:00
Hide_D da612bdc7b 오타 수정 2018-10-28 03:15:07 +09:00
Hide_D 628a085ba8 ReqEnvValue 추가 2018-10-28 03:14:03 +09:00
Hide_D 5ae91ac620 견문 무력 버그 수정 2018-10-25 01:26:59 +09:00
Hide_D 70265c55ef 3인 임관 실패시 견문 2018-10-25 01:21:52 +09:00
Hide_D 7c3b5fc31e 견문 시 무력이 떨어지지 않도록 변경 2018-10-25 01:17:04 +09:00
Hide_D a9a830caa2 기타 설정 추가 2018-10-24 03:27:22 +09:00
Hide_D b49ff3d4ed 예약 안되는 버그 수정 2018-10-24 03:22:41 +09:00
Hide_D 42310fa170 랜임 개월 수 버그 수정 2018-10-24 01:17:03 +09:00
Hide_D bfff1d9e2f 랜임 모드 버그 수정 2018-10-24 00:54:18 +09:00
Hide_D 2c98777b9f 등용장 무효화 2018-10-23 23:33:12 +09:00
Hide_D 4a91260a31 오타 수정 설명 수정 2018-10-23 16:38:25 +09:00
Hide_D 076971bcae 오타 수정 2018-10-23 16:35:28 +09:00
Hide_D 01fcc9bcab 랜덤 임관 모드 추가 2018-10-23 15:05:19 +09:00
Hide_D f56f201bad 건국 코드 준비 2018-10-22 02:30:44 +09:00
Hide_D 45e579f0ef 하야 추가 2018-10-21 22:35:02 +09:00
Hide_D 39db811361 인재탐색 추가. gencount, npc_id 관련 수정 2018-10-21 21:53:34 +09:00
Hide_D ff87555eba 임관 추가. 유니크 복권 추첨을 General 클래스 용으로 변경 2018-10-21 15:20:27 +09:00
Hide_D 6c5c2d40bc argTest를 로직 순서에 맞게 변경 2018-10-21 14:28:29 +09:00
Hide_D c08459e370 등용 추가 2018-10-21 03:02:22 +09:00
Hide_D 42418394ed 군량매매 구현 2018-10-21 02:36:05 +09:00
Hide_D 64fd0e2f28 아이템 구현. 장비매매 추가 2018-10-21 01:55:09 +09:00
Hide_D 2de061203b 징병 모병 추가, iAction 구조 일부 변경 2018-10-20 23:31:32 +09:00
Hide_D cee0d3f03e 일부 DB 값 관련 정보 변경. update 쿼리, insert into 쿼리 일부 변경 2018-10-20 17:41:48 +09:00
Hide_D aa19ae129b 전투태세, 첩보 추가, 기존 코드 일부 정리 2018-10-20 16:45:57 +09:00
Hide_D aecbf8ccb3 견문 추가 2018-10-20 03:24:34 +09:00
Hide_D 7e5c19f507 증여 추가 2018-10-20 02:11:23 +09:00
Hide_D b178ecd494 요양 헌납 추가 2018-10-19 02:47:07 +09:00
Hide_D 05d5039fab 출병 커맨드 구현 2018-10-17 17:42:47 +09:00
Hide_D 1004e5a8bd generalSource 폐기 2018-10-17 16:01:38 +09:00
Hide_D dbcfe6fc6e createGeneralObjFromDB 추가 2018-10-17 15:34:32 +09:00
Hide_D 56698aefe6 집합, 귀환 추가 2018-10-17 02:38:51 +09:00
Hide_D cbd2e136ed 강행, 단련 추가 2018-10-17 02:01:00 +09:00
Hide_D 9846d7f8e4 이동 구현. BaseCommand에 GeneralSource 연결. 2018-10-16 02:29:33 +09:00
Hide_D d16c86a4d7 소집해제 추가. 커맨드 버그 수정 2018-10-16 01:01:50 +09:00
Hide_D 292e642d16 func_process에서 훈련, 사기 삭제 2018-10-16 00:55:44 +09:00
Hide_D 90736b52be 물자조달 턴 추가 기타 커맨드 버그 수정 2018-10-16 00:53:19 +09:00
Hide_D 928e8a200b 사기진작 추가 2018-10-15 02:09:19 +09:00
Hide_D 2ee06eab2d 훈련 턴 추가 2018-10-15 02:05:39 +09:00
Hide_D 01913983ea 턴에 canDisplay() 추가 2018-10-15 01:28:03 +09:00
Hide_D 0aa2f2c44d NPC능동 추가 2018-10-15 01:23:44 +09:00
Hide_D f66d655782 func_npc.php 삭제 2018-10-15 00:51:50 +09:00
Hide_D 4094a08198 NPC 사령턴 일부 수정 2018-10-15 00:14:44 +09:00
Hide_D 05389da412 NPC 새로짜던 사령턴 파기 2018-10-15 00:11:26 +09:00
Hide_D e38258b04b 장수 이전턴 코딩 2018-10-15 00:11:01 +09:00
Hide_D 0cd0e2f730 NPC 수뇌턴 정비 2018-10-13 01:44:20 +09:00
Hide_D d2c7483db1 NPC 일반장 턴 완성 2018-10-12 00:57:21 +09:00
Hide_D d388c52ccd 전투 턴 관련 등록 2018-10-11 23:22:44 +09:00
Hide_D 4a2954d3a4 NPC 행동 재 작성중 2018-10-11 01:07:37 +09:00
Hide_D 804b9a1d71 접경 방식 수정. 상업 투자의 접경식도 같이 수정 2018-10-11 00:33:06 +09:00
Hide_D 1067efbbee 접경 코드를 1(곧 접경), 2(공백지[출병가능]), 3(적 도시[출병가능]) 으로 구분 2018-10-11 00:28:11 +09:00
Hide_D d41ecbeed6 NPC 군주 거병시 이동 로직 수정 2018-10-10 22:24:13 +09:00
Hide_D f93148b7d7 NPC 군주턴 까지 완료 2018-10-08 03:36:43 +09:00
Hide_D 348877c7cd NPC 부대장 수치 버그 수정 2018-10-07 21:46:28 +09:00
Hide_D fb7c2573bf 부대장 수치 버그 수정 2018-10-07 21:43:21 +09:00
Hide_D e4fcc77b0a 능력치 변경시 색상 변경 2018-10-07 19:23:26 +09:00
Hide_D 5c9b79729f AI에서 '내정풀' 인식 2018-10-06 04:18:08 +09:00
Hide_D 00d4541537 NPC 행동 코드 재 구현중 2018-10-06 04:08:53 +09:00
Hide_D 1660e563ab buildGeneralCommandClass류 구현 2018-10-06 04:08:43 +09:00
Hide_D b94081c45b npc 처리용 새 클래스 준비중 2018-10-06 01:52:14 +09:00
Hide_D f7b59f0140 커맨드 관련 구 코드 이전 2018-10-06 00:13:13 +09:00
Hide_D 22aecbe4ba turn0 사용하는 부분 리팩토링 2018-10-06 00:12:16 +09:00
Hide_D be98db9023 Merge branch 'devel' into ng_turn 2018-10-05 21:50:54 +09:00
Hide_D 828e095e64 getGeneralTurnBrief 연동 코드 수정 2018-10-05 21:49:53 +09:00
Hide_D 8e1e21b960 general에 getID 추가 2018-10-05 21:04:43 +09:00
Hide_D 303d8815e3 중간 작업(getGeneralTurnBrief, turn0, npc_turn 작업 남음) 2018-10-04 02:37:54 +09:00
Hide_D ba574dda62 유틸리티 함수 추가 2018-10-04 02:07:31 +09:00
Hide_D bf630b5f7d 턴 요약 위해 getBrief 추가 2018-10-04 01:57:56 +09:00
Hide_D 9b4bf148cc general.turn0 기반 코드 일부를 general_turn 기반으로 변경 2018-10-04 01:18:23 +09:00
Hide_D f5212b4aa1 processCommand 함수 삭제 2018-10-04 01:12:38 +09:00
Hide_D eea4cdf379 스키마 수정 2018-10-04 01:10:31 +09:00
Hide_D e909b48fea 유틸리티 함수들 일부 수정. 랜덤값 뽑기 함수 하나 더 추가 2018-10-04 01:08:56 +09:00
Hide_D 258aabbdde sql 선언 수정 2018-10-04 00:20:30 +09:00
sars 478f26e75a camelCase대신 underscore_case 사용 2018-10-04 00:16:08 +09:00
sars 57cc558b9b 장수 동향, 개인 기록, 중원 정세 id 등록 2018-10-04 00:07:46 +09:00
Hide_D 29984d4b09 지난 턴 관리 부분 이상한 부분 수정 2018-10-03 22:41:49 +09:00
Hide_D e1a266e5d8 '지난 턴'을 관리하는 기능 추가 2018-10-03 22:38:05 +09:00
Hide_D a33a7317cc 턴 커맨드에 getPreReqTurn, getPostReqTurn 추가 2018-10-03 17:45:47 +09:00
Hide_D 1d0bcd857e LastTurn 관리용 객체 추가 2018-10-03 17:27:04 +09:00
Hide_D 040da2429f lock 버그 수정 2018-10-03 16:21:00 +09:00
Hide_D 978a395421 lock 버그 수정 2018-10-03 16:20:47 +09:00
Hide_D 63e5625d62 사령턴 수행용 '지난턴' 추가 2018-10-02 03:06:17 +09:00
Hide_D 38bbae13b9 버그 수정. 커맨드. 사령턴 실행. 2018-10-02 02:27:42 +09:00
Hide_D e975a8106f 코드 정리. 버그 수정. 접경 디버프 반영 2018-10-02 02:27:29 +09:00
Hide_D 6a49887ad7 preprocessCommand 정리 2018-10-02 00:15:15 +09:00
Hide_D 5565ec2ddb 우선 순위를 오름차순으로 변경 2018-10-02 00:11:27 +09:00
Hide_D 20b1f8eff8 전투 우선순위에 '유니크 아이템'의 효과가 과도하게 측정되는 버그 수정 2018-10-01 23:10:47 +09:00
Hide_D 34fd000df9 전투 우선순위에 '유니크 아이템'의 효과가 과도하게 측정되는 버그 수정 2018-10-01 23:10:27 +09:00
Hide_D 1132177e2d 의술의 도시 치료 커맨드 추가 2018-10-01 03:35:07 +09:00
Hide_D 5be39c04ef ?> 제거 2018-10-01 03:03:30 +09:00
Hide_D 0ee4593608 Trigger 추가 수정 2018-10-01 03:02:03 +09:00
Hide_D f301344587 trigger 구성을 올바르게 수정 2018-10-01 02:52:27 +09:00
Hide_D d2c5c856ab Trigger, Action 역할 재정의 2018-10-01 02:02:30 +09:00
Hide_D 5f8e4ae10c 기본 커맨드를 새 turn 테이블 기준으로 변경 2018-09-30 03:17:55 +09:00
Hide_D 4ff30b1a9d command로 새 table용 장수, 수뇌 턴 당기기,밀기 추가 2018-09-30 03:07:24 +09:00
Hide_D a0b215dab6 Command 구조 일부 수정 2018-09-30 03:04:20 +09:00
Hide_D 144e82d7e2 updateTurntime을 TurnExecutionHelper로 이동 2018-09-30 02:05:55 +09:00
Hide_D 79252ba3b0 사망, 환생을 General 클래스로 이동 2018-09-30 02:05:37 +09:00
Hide_D c5286093f9 사망 메시지를 별도로 분리 2018-09-30 02:05:12 +09:00
Hide_D 5ad194bd45 코드 병합 2018-09-29 22:37:30 +09:00
Hide_D 501113da44 gitignore 조정 2018-09-29 22:29:02 +09:00
Hide_D f0a7990404 계략 기본 성공률을 '보급'과 거꾸로 적용한 버그 수정 2018-09-27 17:00:56 +09:00
Hide_D 27f53ff4a6 임관 코드 최종 수정 2018-09-27 16:36:55 +09:00
Hide_D 9ec5dfc8b1 사실 모드 임관 수정 2018-09-27 16:29:49 +09:00
Hide_D e4c1e414c8 사실 모드 랜임 코드 버그 수정 2018-09-27 16:27:38 +09:00
Hide_D a391650472 인증 코드 자리 수 하나 감소 2018-09-25 10:45:21 +09:00
Hide_D 3cfde2b40d 주자사, 공, 황제일 때 장수 수가 내부적으로 1 차이나게 적용되는 버그 수정 2018-09-25 10:12:42 +09:00
Hide_D 8bf1ed33dc 전환 시 '빈칸' 보정, 설명 추가 2018-09-24 04:23:47 +09:00
Hide_D 422b3be0c5 flip image 추가 2018-09-24 04:17:54 +09:00
Hide_D c34e44c4ec data-flip을 허용하고, summernote에 img 태그에 data-flip을 추가하도록 2018-09-24 03:58:40 +09:00
Hide_D a2b20eca67 장수 생성시 초기 스탯으로 '임의 버튼을 클릭'하도록 지정 2018-09-24 02:16:42 +09:00
Hide_D d41c316bfb 설치 설명에서 MariaDB만 지원한다고 변경 2018-09-23 17:31:40 +09:00
Hide_D ca1d8aab84 WebUtil.php에서 drawMenu fallback 추가. 설치시 '활성화되지 않은' KakaoKey.php 파일 추가 2018-09-23 17:31:30 +09:00
Hide_D 32e3dcff7c 이미지 업로드 기능 추가 2018-09-22 03:05:58 +09:00
Hide_D 9a23470622 초반 제한 기간 텍스트 수정 2018-09-21 02:08:51 +09:00
Hide_D c37a186802 툴팁 class 수정. 지도의 년월에 올리면 초반 제한, 기술 제한 툴팁 2018-09-21 02:06:45 +09:00
Hide_D 84c17e3b22 왕조 일람 버그 수정 2018-09-20 02:26:20 +09:00
Hide_D 64e0fca124 전쟁 기한 공식을 스택형으로 변경 2018-09-20 01:15:50 +09:00
Hide_D 5c6537fd7a 멸망 시 접경 재설정 코드 버그 수정 2018-09-20 01:02:29 +09:00
Hide_D 764a82df00 버그 수정 2018-09-20 00:43:36 +09:00
Hide_D e904911fd9 후발 주자에게, 명성, 전특, 내특에 대해 일정 부분 보상 제공 2018-09-20 00:35:38 +09:00
Hide_D a7494f72f6 NPC 부대장에게 포상하지 않도록 수정 2018-09-19 23:56:33 +09:00
Hide_D b6b53b028d 부대탄 유저장도 발령하지 않도록 수정 2018-09-19 23:37:36 +09:00
Hide_D 1743ce714a 전투 코드를 모두 generator 기반으로 변경 2018-09-19 23:29:36 +09:00
Hide_D 656f0c5d11 부대장 주는 횟수 변경 2018-09-19 22:57:06 +09:00
Hide_D d80aebe1f4 집합장 때문에 총 기술치가 깎이는 버그 수정 2018-09-19 22:55:48 +09:00
Hide_D ad48bc1962 접경 내정 상승량 감소는 '수도가 아닐때' 적용 2018-09-19 03:01:38 +09:00
Hide_D d72fbb7098 부대장에게는 금쌀이 제공되지 않도록 수정 2018-09-19 02:21:38 +09:00
Hide_D 95d5eaa09b 주석 수정 2018-09-19 02:13:44 +09:00
Hide_D b997a6159e 치안에 따른 재난 확률 변경 2018-09-19 02:09:08 +09:00
Hide_D 1cd8b7a450 전쟁 중 접경에서는 농상성수 가 제대로 안 오르도록 2018-09-19 02:00:29 +09:00
Hide_D c5a8eb4261 접경지 처리시, 공백지 접경인지 적군 접경인지 구분 2018-09-19 01:49:46 +09:00
Hide_D 8891c29cbd 트래픽이 0인 경우 버그 수정 2018-09-19 01:46:15 +09:00
Hide_D 2facdfa1dd 루드라사움에서도 보병의 성벽 대미지 증가 2018-09-19 01:33:33 +09:00
Hide_D 65c9fa0c21 보병의 성벽 상대 전투력 20% 증가 2018-09-19 01:32:04 +09:00
Hide_D e53c85dbaf 돌격에 저지 불가 제거 2018-09-19 01:16:50 +09:00
Hide_D 3a231e8e61 저지 숙련 증가 2018-09-19 01:00:25 +09:00
Hide_D 4dc7776387 차병은 성벽 전투시 부상을 입지 않음 2018-09-19 00:39:15 +09:00
Hide_D 5ca043e0f1 견고 설명 수정 2018-09-19 00:29:24 +09:00
Hide_D 9ef052c814 견고 추가 상향 2018-09-19 00:28:09 +09:00
Hide_D 6d1690beaa 소울소드 리마스터 시나리오 업데이트 2018-09-18 23:19:30 +09:00
Hide_D 171656e5be 버그 수정 ㅜ 2018-09-18 03:30:40 +09:00
Hide_D 385e7f4871 천통했을 때에는 벌점이 늘어나지 않도록 수정 2018-09-18 03:26:12 +09:00
Hide_D 89c5485784 NPC 안생기는 버그 수정 2018-09-18 03:22:55 +09:00
Hide_D 02d191ec28 변수 대소문자 버그 수정 2018-09-18 03:17:20 +09:00
Hide_D 47c3090f3a NPC 생성 루프 수정 2018-09-18 03:15:40 +09:00
Hide_D 476dac1ac1 주목, 왕이되면 NPC 부대장 하나 더 추가 2018-09-18 02:56:35 +09:00
Hide_D 8ca0d0ced4 메시지 전송 시 장수명 순서대로 정렬 2018-09-18 02:31:41 +09:00
Hide_D ab197489d7 집합장 NPC 삭턴이 실행되지 않는 문제 수정 2018-09-18 02:25:03 +09:00
Hide_D 99736d187b 통합 제의 임시 삭제 2018-09-18 02:15:48 +09:00
Hide_D 197c09bd0d 집합장 턴을 그나마 확인할 수 있도록 삭턴 조정 2018-09-18 02:02:26 +09:00
Hide_D 6cc634ba1f 집합장은 턴이 항상 풀로 차도록.. 2018-09-18 02:01:55 +09:00
Hide_D 4c89ad91d2 부대장 시작 도시를 랜덤으로 2018-09-18 01:56:32 +09:00
Hide_D d66233bce0 NPC 부대장 버그 수정 2018-09-18 01:51:28 +09:00
Hide_D b485e6927e 부대장 번호 버그 수정 2018-09-18 01:47:48 +09:00
Hide_D 74b9e8bd7b 집합장 명칭을 부대장으로 변경 2018-09-18 01:46:37 +09:00
Hide_D 545742ecc0 부대 탄 사람은 발령 로직에서 최대한 배제 2018-09-18 01:27:30 +09:00
Hide_D d9f1f65352 NPC 부대 생성 버그 수정 2018-09-18 01:18:03 +09:00
Hide_D 0904d17a5f 집합장 등장 수식 수정 2018-09-18 00:36:05 +09:00
Hide_D 87171b4246 집합장 테스트 2018-09-18 00:29:44 +09:00
Hide_D 78f8b56203 reset_token에서 불필요한 명령 제거 2018-09-17 23:06:24 +09:00
Hide_D b79045eddb 전투 특기 클래스 추가, 2018-09-17 03:31:36 +09:00
Hide_D 6eb67b1a3c 일단 push 2018-09-17 02:57:44 +09:00
Hide_D 777ec39bd9 턴 수행 constraint를 상세하게 분리, argTest 추가. 턴 커맨드 실행용 클래스, ajax 파일 준비 2018-09-16 22:16:08 +09:00
Hide_D 9dcafaaa38 reset_token에서 불필요한 명령 제거 2018-09-16 17:58:56 +09:00
Hide_D 097e2fb653 턴 표기 방식 대폭 변경 2018-09-16 04:54:17 +09:00
Hide_D e7aa97634b 동결, 지연인 경우에 한해 커맨드 창의 월 표시가 다르게 되던 문제 수정.
addTurn, subTurn, cutTurn 등에서 밀리초 표기 개선
2018-09-16 04:52:13 +09:00
Hide_D 447b9f265f Auction에서 구형 Ymd his 변경 2018-09-16 04:41:00 +09:00
Hide_D 029a6f03b7 서버의 분턴 변경시 '정확히' 현재 턴에 비례해서 변경되도록 변경 2018-09-16 04:38:06 +09:00
Hide_D ae4a349d79 랜덤 턴에서 '소수점'을 다룸 2018-09-16 04:18:22 +09:00
Hide_D 35728c7911 TimeUtil 리팩토링 2018-09-16 04:14:22 +09:00
Hide_D 469330f270 TimeUtil을 소수점 시간을 고려할 수 있도록 수정 2018-09-16 03:54:24 +09:00
Hide_D 03f9c56928 정장, 선정 커맨드 문제로 명성,계급 반영 위치 이동 2018-09-15 03:49:08 +09:00
Hide_D ed2a2a8975 기술연구의 calcBaseScore는 상업 투자 것을 가져오기로 2018-09-15 03:44:10 +09:00
Hide_D b5380f183c 내정 커맨드 버그 수정, 정착장려, 주민선정 추가, RemainCityTrust 추가, succ -> success 2018-09-15 03:42:09 +09:00
Hide_D f5bcaba352 phan 타겟 버전 변경 2018-09-15 02:52:40 +09:00
Hide_D 5a70b23db9 필요없어진 gennum2 삭제. gennum 재연산 2018-09-15 02:51:33 +09:00
Hide_D fc3487e545 사용되지 않는 chemi 제거 2018-09-15 02:43:24 +09:00
Hide_D a4863dc8d7 totaltech, tech를 float tech로 일원화, NPC가 기술레벨 10을 넘으면 기연 안하는 버그 수정 2018-09-15 02:37:11 +09:00
Hide_D af12a08e25 기술연구 추가 2018-09-15 01:53:17 +09:00
Hide_D 312dc294b3 내정턴 성공 확률 계산을 실패->성공->일반에서 성공->실패->일반으로 변경 2018-09-15 01:33:44 +09:00
Hide_D d958dd5ee4 func_process 이전 코드 분리 2018-09-15 00:59:51 +09:00
Hide_D 1ddc49b17b 기본 내정턴을 클래스 기반으로 가능하도록 수정 2018-09-15 00:57:58 +09:00
Hide_D 322541b16f 농상치성수 내정 코드 구현 2018-09-15 00:40:24 +09:00
Hide_D 00cb10f029 BaseCommand에 '대상이 지정되지 않아' 대략적으로 가능성을 추측해야하는 경우 추가 2018-09-15 00:39:03 +09:00
Hide_D ed24a721ed General의 통합 interface 간소화 2018-09-15 00:38:28 +09:00
Hide_D 9fc10e0f65 농지 개간, 상업 투자를 외부 커맨드로 연결 2018-09-14 02:35:27 +09:00
Hide_D ab212e0565 모 징병 코드의 uniqueItem을 uniqueItemEx로 변경 2018-09-14 02:28:05 +09:00
Hide_D eac0049577 농지개간, 상업투자 구현, General 클래스로 checkStatChange 이동, uniqueItemEx 추가(및 재구현) 2018-09-14 02:26:41 +09:00
Hide_D 9d1d51d0d7 119 코드에서 $connect 제거 2018-09-14 00:58:55 +09:00
Hide_D 4fd3c4ada6 상업투자 구현 중 2018-09-13 03:02:51 +09:00
Hide_D dd73d8fc69 General에 iActionTrigger 활성화 2018-09-13 02:38:27 +09:00
Hide_D b89d37c8c5 getPersonalityClass 추가 2018-09-13 02:21:42 +09:00
Hide_D bc4983c771 전략 관련 보정 함수 명 변경 2018-09-13 02:10:37 +09:00
Hide_D e6c186b31b 은둔 보정 수정 2018-09-13 01:52:36 +09:00
Hide_D b106fa55d3 상업투자 구현 중 2018-09-13 01:43:44 +09:00
Hide_D 981e42c5a9 trigger 타입에서 $tunType을 한글로 변경. 성격 추가. 계략 성공 확률을 onCalcDomestic으로 통합. 2018-09-13 01:43:32 +09:00
Hide_D c160c5a555 천통시 모든 국가 등재 장수의 이름이 9글자 인 경우 발생하는 버그 수정 2018-09-12 01:46:16 +09:00
Hide_D 31c7bf5348 메뉴 아이템 길이 버그 2018-09-12 01:16:17 +09:00
Hide_D 89bf457878 Merge branch 'devel' into ng_turn 2018-09-12 00:54:48 +09:00
Hide_D 6eadf718fc meta keyword 추가 2018-09-12 00:35:50 +09:00
Hide_D effced24d1 sitemap을 위하여 메뉴를 php에서 직접 출력하도록 변경 2018-09-12 00:12:32 +09:00
Hide_D 09f399db9a robots.txt 재등록 2018-09-11 23:50:29 +09:00
Hide_D 2b73f6faea 로봇에 대문자 들어가서 삭제 2018-09-11 23:50:16 +09:00
Hide_D 943662605e Robots.txt 설명 추가 2018-09-11 23:48:02 +09:00
Hide_D 9a04962bd6 대문에 meta 태그 추가 2018-09-11 23:03:10 +09:00
Hide_D 91a36eb9a0 머지 2018-09-11 21:40:07 +09:00
Hide_D c371f6bbb5 refresh_token 변수가 잘못된 것 수정 2018-09-11 11:13:37 +09:00
Hide_D 8324e2e454 access token 체크용 디버그 2018-09-11 11:08:37 +09:00
Hide_D 30307c1b56 로그인 인증 버그 체크 2018-09-11 10:55:53 +09:00
Hide_D f139d0d2a8 로그인 인증 디버깅용 코드 추가 2018-09-10 23:12:27 +09:00
Hide_D 33843764a7 로그인 토큰을 제대로 못 받은 경우 추가 2018-09-10 23:07:44 +09:00
Hide_D aca7d7c571 createOTP 반환형 버그 2018-09-10 01:49:11 +09:00
Hide_D bff72f609c 세션 로그인시 oauth token 값이 제대로 저장 안되는 버그 수정 2018-09-10 01:09:55 +09:00
Hide_D adb03b7420 인증시 로그아웃이 바로 풀리는 버그 수정 2018-09-10 00:38:06 +09:00
Hide_D 2094e18b60 IE에서 인증이 이상한 문제 해결 2018-09-10 00:35:59 +09:00
Hide_D 541d8ddd40 토큰 시간 초과시 즉시 로그아웃 되도록 변경 2018-09-10 00:22:57 +09:00
Hide_D f996172218 Merge branch 'kakao_login' into devel 2018-09-09 23:58:51 +09:00
Hide_D f9ffc1c1f3 oauth 인증중 token_valid_until만 table column으로 분리 2018-09-09 23:57:26 +09:00
Hide_D 05085ad504 5일이 지난후 로그인 토큰을 미리 초기화 가능하도록 수정 2018-09-09 23:18:23 +09:00
Hide_D 64aecaf28b 메인 페이지에 '비밀번호 초기화' 추가 2018-09-09 21:53:00 +09:00
Hide_D 7b3ef45300 카카오 로그인 작업 개선 2018-09-09 21:16:44 +09:00
Hide_D bd25de930b 카카오 로그인용 디버깅 코드 제거 2018-09-09 20:22:34 +09:00
Hide_D 15d43c9653 카카오 로그인 초기 구현 2018-09-09 20:19:00 +09:00
Hide_D 5b7eba61cc 반계에 '동그라미' 오타 제거 2018-09-09 15:54:17 +09:00
Hide_D 2445c79805 성벽 상대로 '혼란' 계략을 사용하지 않는 버그 수정 2018-09-08 12:33:41 +09:00
Hide_D 63be2dee47 운영자 찬스 수정 2018-09-07 02:06:13 +09:00
Hide_D 5bfef1be32 운영자 찬스2 2018-09-07 02:04:50 +09:00
Hide_D 8253526f23 운영자 찬스 2018-09-07 02:03:37 +09:00
Hide_D db19548e2c 불가능한 커맨드일 때 '불가' 표기 추가 2018-09-07 00:45:38 +09:00
Hide_D 10af31f042 customCSS를 조금 더 안전하게 적용 2018-09-06 23:38:47 +09:00
Hide_D e7c6e17590 왕조 일람의 '현재'에 대한 자세히 보기를 삭제 2018-09-05 23:39:16 +09:00
Hide_D a3d0ceb6a5 내정턴 준비 2018-09-05 01:28:58 +09:00
Hide_D a277ac182b 통합 안되는 버그 수정 2018-09-04 15:48:18 +09:00
Hide_D 0eee613a95 외교 커맨드 수정 2018-09-04 01:39:58 +09:00
Hide_D b76fa38e09 외교 커맨드 수식 오류 수정 2018-09-04 01:33:21 +09:00
Hide_D 7679c11b5b 외교 커맨드 수식 오류 수정 2018-09-04 01:30:06 +09:00
Hide_D e7ae2ab441 내특을 int에서 string으로 변경 2018-09-03 02:07:41 +09:00
Hide_D c0f5c8a358 내 정보에서 수비, 토너먼트가 즉시 반영되지 않는 버그 수정 2018-09-03 01:09:03 +09:00
Hide_D dd5feb0e2c 내 정보에서 수비, 토너먼트가 즉시 반영되지 않는 버그 수정 2018-09-03 01:08:42 +09:00
Hide_D b95d05c134 내특을 iActionTrigger로 구현 2018-09-03 01:03:51 +09:00
Hide_D 87bdd0016e onCalcDomesticTurnScore 구조 변경 2018-09-02 23:11:07 +09:00
Hide_D b9befa4e63 국가 성향 증가/감소 기본 구현 완료 2018-09-02 23:02:12 +09:00
Hide_D d9ed00ddee 치안, 수성, 민심까지 반영 완료 2018-09-02 22:50:25 +09:00
Hide_D 4c2b484c2b 계략 확률, 전략턴, 기술 반영 2018-09-02 22:19:38 +09:00
Hide_D ff31e41fec 금수입, 살수입 반영 2018-09-02 22:04:08 +09:00
Hide_D 34204f6183 onCalcDomesticTurnScore 변경 TriggerNationType에서 숫자 id 제거 2018-09-02 21:57:44 +09:00
Hide_D 6fc8763895 국가 성향 converter를 TriggerNationType으로 통합 2018-09-02 21:37:23 +09:00
Hide_D 71dd82afe8 메인 페이지 width 일부 수정 2018-09-02 21:00:05 +09:00
Hide_D ea5425a528 commandlist 가로로 짤리는 몇몇 유저용 수정 2018-09-02 20:55:47 +09:00
Hide_D 1a0914196f getNationTypeList 변경 2018-09-02 20:54:32 +09:00
Hide_D 9dd1adacd2 nation type을 char로 변경하고 해당하는 iActionTrigger 추가 2018-09-02 19:52:04 +09:00
Hide_D 93c5268fbc ActionTrigger 초안 추가 2018-09-02 19:51:48 +09:00
Hide_D 98edc89fa0 LazyVarUpdater를 활용하는 General 클래스 추가 2018-09-02 19:51:17 +09:00
Hide_D 3aad412102 명성에 따른 보정치 함수 추가 2018-09-02 19:50:50 +09:00
Hide_D a2ee9524fb updateVar 정리 2018-09-02 19:50:31 +09:00
Hide_D 78955a1540 범용성을 목적으로 LazyVarUpdater를 분리 2018-09-02 17:25:04 +09:00
Hide_D f412b7e734 구버전 전투 코드 삭제 2018-09-02 17:18:05 +09:00
Hide_D b13f3004e2 잘못된 rate->trust 변경 복구 2018-09-02 16:05:44 +09:00
Hide_D a093b0f8e8 도시의 민심을 int에서 float으로 변경하고 명칭을 rate에서 trust로 변경 2018-09-02 16:03:04 +09:00
Hide_D d4ba13eee3 부대 탈퇴시 확인 창이 정상적으로 뜨지 않는 버그 수정 2018-09-02 14:19:17 +09:00
Hide_D 34a84c6548 contraint 일괄 체크 함수 추가 2018-09-02 14:18:59 +09:00
Hide_D 6c52c1177b 부대 탈퇴시 확인 창이 정상적으로 뜨지 않는 버그 수정 2018-09-02 14:18:44 +09:00
Hide_D f9bc312f91 도시명 표기시 ==== 기호 제거 2018-09-02 14:15:24 +09:00
Hide_D 7283153f44 contraint 추가 2018-09-02 13:46:57 +09:00
Hide_D df6b2bd0e8 초기 constraint 지정 2018-09-02 13:17:26 +09:00
Hide_D 16831880dd 이전 시간대에 대해 리셋 가능하지 않도록 변경 2018-08-31 20:36:59 +09:00
Hide_D f79fc98ba6 customCSS 추가
장수 아이콘에 generalIcon 클래스 추가
2018-08-31 20:25:10 +09:00
Hide_D 0483c75dd7 전투 시뮬레이터에서 대미지 범위 표기 2018-08-31 19:32:56 +09:00
Hide_D 3a4dcacd56 글꼴 크기 범위 추가 2018-08-30 22:06:37 +09:00
Hide_D 5f6f09674e Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2018-08-30 22:02:58 +09:00
Hide_D c785027c5c 에디터 변경 2018-08-30 22:02:51 +09:00
Hide_D d2659cea5f 원조시 특정 경우에 쌀 소모를 줄일 수 있는 버그 수정 2018-08-30 11:51:02 +09:00
Hide_D a9b966b159 증축 시 쌀 2000이 아닌 0 기준으로 계산하는 버그 수정 2018-08-30 11:49:37 +09:00
Hide_D f2c23e21c5 천도 시 쌀이 2000 미만이어도 가능한 버그 수정 2018-08-30 11:49:06 +09:00
Hide_D 53b973e2d3 장수 일람 연동 코드 버그 수정 2018-08-30 09:08:19 +09:00
Hide_D b7a570cba2 폰트 크기 변경에 대해서 즉시 반영이 되지 않는 버그 수정 2018-08-30 03:04:05 +09:00
Hide_D c77b79f0d2 글꼴 크기 커스터마이징 완료 2018-08-30 02:41:58 +09:00
Hide_D ef6678d8b0 에디터 글꼴 크기 커스터마이징 2018-08-30 02:12:48 +09:00
Hide_D 21609fa9c4 GUI 에디터 추가 옵션 2018-08-30 01:56:47 +09:00
Hide_D accc083702 gui 에디터 추가 2018-08-30 01:25:45 +09:00
Hide_D 9e677f3871 스탯 분류 방식 변경 2018-08-29 20:36:43 +09:00
Hide_D 55290eac30 네임스페이스 버그 해결 2018-08-29 15:04:44 +09:00
Hide_D d480502d33 NPC 네임스페이스 버그 해결 2018-08-29 15:03:43 +09:00
Hide_D c1cda16be0 성벽 공격 로그 수정 2018-08-28 21:56:33 +09:00
Hide_D 8ca9df9f34 '성인이 되어 등장' 시 전콘이 안뜨는 문제 해결 2018-08-28 20:36:46 +09:00
Hide_D 406b67b081 애니 집결 시나리오 변경 2018-08-28 20:29:42 +09:00
Hide_D 2c9fecf3ef 의병 고용, 인재 탐색시 기본 변종에 0 코드가 없는 경우 수정 2018-08-28 20:17:43 +09:00
Hide_D 6bc78b67bd 튜토리얼 버튼을 전투 시뮬레이터로 변경 2018-08-28 20:13:54 +09:00
Hide_D 5bbc46e070 구버전 시뮬레이터 삭제 2018-08-28 13:22:17 +09:00
Hide_D 6a9ceda361 국가에는 escape가 되어있으므로 메시지 템플릿에 2중 escape는 필요하지 않음 2018-08-28 01:49:25 +09:00
Hide_D ab2d5fd58f 이미지 출력시 주소에 빈칸이 있는 경우 안보이는 문제 해결 2018-08-27 23:39:58 +09:00
Hide_DandGogs 7018413777 Merge branch 'devel' of cappu/core into devel 2018-08-27 23:31:51 +09:00
cappu 77385616a4 테스트 겸 스탯업데이트 2018-08-27 23:17:31 +09:00
Hide_D c809f27bf5 전투 시뮬레이터를 포함한 코드 적용 2018-08-27 21:11:05 +09:00
Hide_D 493e778124 계략수비 시 전특 징병의 통솔이 반영되지 않는 버그 수정 2018-08-27 17:46:43 +09:00
Hide_D 7373af50b9 계략시 '징병' 전특의 통솔 상승을 받지 못하는 버그 수정 2018-08-27 17:43:53 +09:00
Hide_D 309f053510 화계시 도시 내정이 반영 안되는 버그 수정 2018-08-27 17:39:05 +09:00
Hide_D d976cf8a27 화계시 도시 내정이 반영 안되는 버그 수정 2018-08-27 17:38:08 +09:00
Hide_D 5d60a62a38 단어 수정 2018-08-27 13:53:07 +09:00
Hide_D a3f7dbccea 시뮬레이터 UI 일부 수정 2018-08-27 13:52:51 +09:00
Hide_D 0c4cce3339 시뮬레이터 숙련도 반영 안되는 버그 수정 2018-08-27 13:47:51 +09:00
Hide_D 58ccbc4d3d 불러오기시 json을 확장자로 지정 2018-08-27 03:13:34 +09:00
Hide_D c6cabc2087 전투 시뮬레이터 모두 저장/모두 불러오기 구현 2018-08-27 03:08:35 +09:00
Hide_D ef1f2722fc 전투 시뮬레이터 기본 기능 구현 완료 2018-08-27 02:21:45 +09:00
Hide_D 6b4a7ee03b 전투 시뮬레이션 구현 (동작) 2018-08-27 01:23:45 +09:00
Hide_D 7745a2051d 수비시 국가 성향이 공격국으로 지정되는 버그 수정 2018-08-27 00:18:50 +09:00
Hide_D eabd5e9acc 전투 시뮬레이터 구현 2018-08-27 00:18:19 +09:00
Hide_D d7dcbf98ff 전투 순서 버그 수정 2018-08-26 23:29:15 +09:00
Hide_D ff4c73f3d3 전투 종료시 로그 순서 변경 2018-08-26 23:25:47 +09:00
Hide_D dbf044b418 Revert "전투 종료 시 뜨는 로그 순서 변경"
This reverts commit 568e1b2923.
2018-08-26 23:23:06 +09:00
Hide_D 7a514e2492 쌀 소모에 '명성 버프/디버프' 성격이 적용되는 기존 버그 수정 2018-08-26 23:19:21 +09:00
Hide_D a73e533287 전투 종료 시 뜨는 로그 순서 변경 2018-08-26 23:19:09 +09:00
Hide_D 0f175ac4c6 수비 순서대로 정렬 버튼 활성화 2018-08-26 23:16:42 +09:00
Hide_D be15f1c698 쌀 소모에 '명성 버프/디버프' 성격이 적용되는 기존 버그 수정 2018-08-26 23:11:19 +09:00
Hide_D a315da6041 전투 종료 시 뜨는 로그 순서 변경 2018-08-26 22:59:14 +09:00
Hide_D 3f43f218ac 시뮬레이터 전투 준비 2018-08-26 22:32:37 +09:00
Hide_D 5c8ad646af ajax 쿼리 validation 종료 2018-08-26 22:31:14 +09:00
Hide_D 77f5fddd90 계략 실패 계수가 거꾸로 적용되는 버그 수정 2018-08-26 20:29:59 +09:00
Hide_D eab8b1ede5 전투 시뮬레이터 구현 중 2018-08-26 20:29:42 +09:00
Hide_D 2ab0896523 계략 실패 계수가 거꾸로 적용되는 버그 수정 2018-08-26 20:29:32 +09:00
Hide_D 639fe920df 전투 시뮬레이터 추가 구현 2018-08-26 20:01:08 +09:00
Hide_D 7577c84eca 국가 성향 버그 수정 2018-08-26 18:25:14 +09:00
Hide_D 22c4ec2d4a 국가 성향 출력 버그 수정 2018-08-26 18:24:35 +09:00
Hide_D 8ac85881a9 국가 성향이 제대로 등록되지 않는 버그 수정. 시뮬레이터 구현 2018-08-26 18:19:27 +09:00
Hide_D 724804efc6 전투 시뮬레이터 로컬 기능 구현 2018-08-26 17:20:47 +09:00
Hide_D ca57ef17fc 전투 시뮬레이터 추가 구현 2018-08-26 04:54:43 +09:00
Hide_D 480f015fb0 전투 시뮬레이터 구현 중 2018-08-25 11:27:29 +09:00
Hide_D d90e087f20 전투 시뮬레이터 추가 구현 2018-08-25 11:25:34 +09:00
Hide_D 3916cc0562 전투 시뮬레이터 UI 추가 구현 2018-08-25 11:15:33 +09:00
Hide_D cb54e56417 전투 시뮬레이터 작업 중 2018-08-24 03:46:21 +09:00
Hide_D 6aa606f2fa 전투 시뮬레이터 틀 작성 중 2018-08-24 01:09:17 +09:00
Hide_D 53d13a11ce 장수 생성시 능력치 덧셈이 이상한 버그 수정 2018-08-23 20:26:23 +09:00
Hide_D 9ba2b4142d 계략 시 수비 장수를 무시하는 버그 수정 2018-08-23 19:26:15 +09:00
Hide_D f5161a5b99 Merge branch 'devel' into battle_simulator 2018-08-23 18:45:32 +09:00
Hide_D f9d5d190d5 유니크 훈련,사기 템에서 훈련, 사기가 영구적으로 오르는 버그 수정 2018-08-23 16:21:18 +09:00
Hide_D eead9639a2 도시 점령시, 승수, 사기가 추가로 오르는 버그 수정 2018-08-23 16:10:49 +09:00
Hide_D 5044d5d3b4 파일 준비 2018-08-23 16:07:11 +09:00
Hide_D 44eed2c1df 탈취 확률 버그 수정 2018-08-23 01:53:00 +09:00
Hide_D e83b182e4d NPC가 기본 병종만 뽑는 버그 수정 2018-08-23 01:46:45 +09:00
Hide_D 888a76eda0 장수 생성 시 종능 부족하면 경고창 띄움 2018-08-23 01:07:25 +09:00
Hide_D 668364e583 수뇌이면 감찰부 상세 로그 표기 2018-08-22 15:27:44 +09:00
Hide_D 35c7a2d1b6 계략 로그에서 장수 부상 수치도 강조 2018-08-22 15:23:46 +09:00
Hide_D 79803178cd 민심 깎이는 로그에 반올림 적용 2018-08-22 15:22:20 +09:00
Hide_D 419ee8d8ff 전투 계략 실패 색상 버그 수정 2018-08-22 15:12:08 +09:00
Hide_D 328b3c9409 계략에 로그 추가 2018-08-22 15:11:29 +09:00
Hide_D f097508e87 탈취 버그 수정 2018-08-22 14:52:09 +09:00
Hide_D e6791ee8ec 탈취 성공시 일부는 장수가 소유 2018-08-22 14:49:15 +09:00
Hide_D cfbeba3de1 계략이 항상 성공하는 버그 수정 2018-08-22 14:43:01 +09:00
Hide_D bbc7f5a734 탈취 버그 수정 2018-08-22 14:37:48 +09:00
Hide_D e8726f03f3 탈취 버그 수정 2018-08-22 14:36:52 +09:00
Hide_D de95c6d698 계략 버그 수정 2018-08-22 14:31:37 +09:00
Hide_D 86b57447d8 계략시 소모성 아이템이 소모되지 않는 버그 수정 2018-08-22 14:29:27 +09:00
Hide_D c9d1efc6e7 계략 버그 수정 2018-08-22 14:21:53 +09:00
Hide_D dd1eeaddfa 계략 버그 수정 2018-08-22 14:20:49 +09:00
Hide_D 7f098db3de 계략 버그 수정 2018-08-22 14:18:30 +09:00
Hide_D 6468cbbfbd 계략 시전 버그 수정 2018-08-22 14:16:56 +09:00
Hide_D a30d61e842 계략 커맨드 리팩터링 2018-08-22 14:09:24 +09:00
Hide_D e0029fdc87 전투 중 사기 증가가 제대로 반영되지 않는 버그 수정 2018-08-22 02:44:59 +09:00
Hide_D 712e2c32a0 병력의 소집해제가 0분 0초가 아닌 '본인의 턴 실행 직전'에 실행되도록 변경 2018-08-22 02:18:55 +09:00
Hide_D f28e15b567 보급 끊긴 곳에 대한 계략 동작 변경 2018-08-22 02:05:24 +09:00
Hide_D 128e33661f 무한 발동 가능한 사령턴 커맨드의 명성,계급치 증가 삭제 2018-08-22 01:51:11 +09:00
sars 3916561c62 Revert "Revert "사스 권한 테스트겸, camelCase 적용""
This reverts commit 415791dddd.
2018-08-21 18:07:56 +09:00
sars 00638d074a Revert "사스 권한 테스트겸, camelCase 적용"
This reverts commit a5be15e453.
2018-08-21 18:07:05 +09:00
sars ca51b2d83a 사스 권한 테스트겸, camelCase 적용 2018-08-21 18:03:55 +09:00
Hide_D 1a879f97a2 기술 제한이 항상 걸리는 버그 수정 2018-08-21 18:02:02 +09:00
Hide_D 89d18cb7c5 성벽 전투시 떨어지는 내정 수치 수정 2018-08-21 16:41:31 +09:00
Hide_D 4e14249707 성벽 공격시 떨어지는 내정수치 수정 2018-08-21 16:35:37 +09:00
Hide_D 41f2c08da8 올바르지 않은 성격일 경우 기본 값 설정 2018-08-21 15:43:59 +09:00
Hide_D 4fca7bcfcf 저지 증가 숙련 변경 2018-08-21 14:59:58 +09:00
Hide_D 232725329a 툴팁 변경. 저지시 숙련 추가 2018-08-21 14:58:48 +09:00
Hide_D 88247851f4 징병 전특은 순수 통솔에서 15% 보정 2018-08-21 12:23:19 +09:00
Hide_D 6efaec6642 보병 상대 회피율 변경 2018-08-21 11:54:01 +09:00
Hide_D b9e31e39e2 보병은 상대의 회피를 5%p 감소 2018-08-21 11:51:09 +09:00
Hide_D e2cd8ed391 견고시 계략 성공 확률 변경 2018-08-21 11:07:28 +09:00
Hide_D 8a1641fbfa 견고 방식 변경 2018-08-21 11:04:27 +09:00
Hide_D 936f069ac3 수극 사용시 부상 정도 약화 2018-08-21 10:47:47 +09:00
Hide_D 89faad730e 전투 로그 중 회피에 오타 수정 2018-08-21 09:29:28 +09:00
Hide_D 798ab3e183 암행부 병종 표기 버그 수정 2018-08-21 02:24:58 +09:00
Hide_D 5508aa4533 전투 엔진 버그 4차 수정 2018-08-21 02:22:29 +09:00
Hide_D 81b7ebbab6 전투 엔진 버그 3차 수정 2018-08-21 02:01:56 +09:00
Hide_D 2d06e33e10 운영자가 '지도'에서 도시를 클릭할 수 있도록 변경 2018-08-21 01:32:00 +09:00
Hide_D d8cc820572 전투 엔진 버그 2차 수정 2018-08-21 01:22:18 +09:00
Hide_D d0ca46cfde 전투 엔진 버그 1차 수정 2018-08-21 00:53:00 +09:00
Hide_D 513124161e 전투 종료 코드 구현(마무리?) 2018-08-20 23:57:36 +09:00
Hide_D 7cfd8c7f79 전투 종료 코드 구현(마무리?) 2018-08-20 22:26:34 +09:00
Hide_D c32ce5e795 전투 종료 코드 구현 2018-08-20 22:20:59 +09:00
Hide_D d9c1530651 일부 게임 유틸리티 함수 간소화 2018-08-20 20:21:26 +09:00
Hide_D 305eb071a9 전투 종료 코드 구현 2018-08-20 17:24:16 +09:00
Hide_D 10dab69c63 전투 구현 반영 2018-08-20 03:48:54 +09:00
Hide_D 60ed594996 전투 구현 반영 2018-08-20 03:46:59 +09:00
Hide_D e60ddb3ee1 전투 구현 반영 2018-08-20 03:14:56 +09:00
Hide_D 26b0992285 전투 구현 반영 2018-08-19 03:47:28 +09:00
Hide_D 63f3ac807c 전투 구현 반영 2018-08-19 03:45:43 +09:00
Hide_D ed1c33eac0 전투 구현 반영 2018-08-19 03:30:47 +09:00
Hide_D e7b7fd0bcc 치료가 '필살', '회피'와 중복 가능. 전특과 의술 아이템의 치료 효과 증폭 2018-08-19 03:00:08 +09:00
Hide_D 79d2b04721 전투 구현 반영 2018-08-19 02:57:25 +09:00
Hide_D 5a8ab2d29c 전투 구현 반영 2018-08-19 02:33:42 +09:00
Hide_D ed527ac394 전투 코드 반영 2018-08-18 23:18:40 +09:00
Hide_D bf09f48196 전투 구현 반영 2018-08-18 22:21:25 +09:00
Hide_D 2a5af15aef 전투 코드 반영 2018-08-18 21:24:02 +09:00
Hide_D 1f8fe35e25 성벽 전투시 깎이는 성벽이 기존 대비 1/2 2018-08-18 20:46:30 +09:00
Hide_D 5979273a64 코드 중간 반영 2018-08-18 20:45:59 +09:00
Hide_D ef8c9e3968 전투 엔진 중간 반영 2018-08-18 19:04:13 +09:00
Hide_D baa9fdb660 유틸리티 함수 추가 2018-08-18 16:59:34 +09:00
Hide_D 35a860bb38 충차 성벽 보정 버그 수정 2018-08-18 15:18:40 +09:00
Hide_D 286939dc2c CriticalScore2, getCrew 이동 2018-08-18 14:02:53 +09:00
Hide_D dd5b1dbdd8 전투 추가 구현 2018-08-18 10:53:04 +09:00
Hide_D fb8d3a038d 새 전투 엔진 중간 반영 2018-08-18 02:26:27 +09:00
Hide_D ea5a25a671 전투 파일 추가 작성중
전투 코드 추가 준비

추가 구현
2018-08-14 23:11:03 +09:00
Hide_D d21fc4ab1d 새 전투 엔진 준비 2018-08-12 22:23:53 +09:00
Hide_D 3ae3974866 수극 사용 로그 버그 수정 2018-08-12 13:25:24 +09:00
Hide_D 71ffc3087e 전투 공식 핫픽스 2018-08-11 08:49:23 +09:00
Hide_D 8f406489d4 전콘 용량을 30KB로 증가 2018-08-10 19:58:31 +09:00
Hide_D a08d270968 루드라사움 지도 업데이트 2018-08-10 02:22:31 +09:00
Hide_D 48f13e4b82 루드라사움 스탯 수정 2018-08-08 03:47:04 +09:00
Hide_D 51060f0e4b 루드라사움 지도 업데이트 2018-08-08 03:36:00 +09:00
Hide_D c583109046 루드라사움 패치 2018-08-08 03:21:42 +09:00
Hide_D cf05b693f1 엑셀 파일에 빙의 불가 장수 목록 개념 추가 2018-08-08 02:48:17 +09:00
Hide_D d248c1ab0d 빙의가 불가능한 general_neutral 항목 추가 2018-08-08 02:45:41 +09:00
Hide_D 34623fca94 이민족 코드를 5에서 9로 이동. 그에따른 추가 코드 변경 2018-08-08 02:31:49 +09:00
Hide_D 975bdd5897 토너먼트 중복 참가 방지. 자동 참가시 돈을 받지 않음 2018-08-08 01:54:57 +09:00
Hide_D 1b3380c2ca 성벽을 때렸을 때 차숙이 오르지 않는 버그 해결 2018-08-07 04:00:31 +09:00
Hide_D bb707b4a03 명성 / 계급 계산식을 for loop 없앰 2018-08-06 01:23:39 +09:00
Hide_D acb3b6ac85 물자 조달로 올라가는 명성, 계급의 양을 다른 내정과 비슷하게 변경 2018-08-06 00:46:22 +09:00
Hide_D 80f6985f5f 지도 툴팁 line break 없앰 2018-07-30 03:23:01 +09:00
Hide_D 5e3a9c0579 지도 툴팁 너비 수정 2018-07-30 02:13:46 +09:00
Hide_D b30d62d483 루도라사움 지도 위치 수정 2018-07-30 02:11:51 +09:00
Hide_D 0ea1fdbd19 지도 출력 변경 2018-07-30 02:07:02 +09:00
Hide_D f068586f74 지도를 변경 가능하도록 업데이트 2018-07-30 02:00:53 +09:00
Hide_D 463f462e24 j_map_history에서 year가 0인 경우 2018-07-30 01:47:33 +09:00
Hide_D e0c4e3c58e 장수 생성시 기본 타입 2018-07-30 01:42:42 +09:00
Hide_D 5aa3ef38ba 연감용 루드라사움 지도 추가 2018-07-30 01:34:39 +09:00
Hide_D 827277f6a3 버그 수정 2018-07-30 01:26:12 +09:00
Hide_D 46389341db 루드라사움을 위한 시스템 보정 2018-07-30 00:37:39 +09:00
Hide_D a58f05a295 에러메시지를 VSCode에서 바로 이동하기 쉽도록 변경 2018-07-29 23:43:36 +09:00
Hide_D c0b0a0fe92 루드라사움 지도 연결 수정 2018-07-29 23:41:35 +09:00
Hide_D e9f471dd6f Neo 루드라사움 준비 2018-07-29 23:26:19 +09:00
Hide_D 7917c5dddb 부대편성 버그 수정 2018-07-29 16:20:43 +09:00
Hide_D de4541a3d9 부대 편성 일부 수정 2018-07-29 13:57:10 +09:00
Hide_D 77a496baa7 암행부 추가 확장 2018-07-28 02:38:19 +09:00
Hide_D 86e863de09 암행부 너비 추가 수정 2018-07-28 02:33:42 +09:00
Hide_D c2cfd217c2 암행부 턴 표기 수정 2018-07-28 02:02:50 +09:00
Hide_D f2366a61b0 IE11 모병창 UI 버그 수정 2018-07-28 01:58:35 +09:00
Hide_D 9959393dee IE 메인페이지 깨짐 일부 수정 2018-07-28 01:38:53 +09:00
Hide_D 16facf98f1 submit_btn 버그 수정 2018-07-28 01:32:00 +09:00
Hide_D bc8ce8832a 모/징병 페이지 변경 2018-07-28 01:24:23 +09:00
Hide_D 20bcf960ef 로그인 페이지를 모바일에서도 조금 더 잘보이게 변경 2018-07-27 18:56:01 +09:00
Hide_D 5cecd3e995 로그인 페이지가 약관 등에 가리지 않도록 변경 2018-07-27 18:47:48 +09:00
Hide_D d7ead25ea4 1턴에 어쩌다 휴식턴이 입력되는 버그 수정 2018-07-27 18:14:16 +09:00
Hide_D 75c0c375d1 장수 호칭 변경 2018-07-27 03:03:25 +09:00
Hide_D 5db4913292 세력일람 장수 표기순 변경 2018-07-27 02:39:26 +09:00
Hide_D a6a53b1d0d Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2018-07-27 02:34:02 +09:00
Hide_D 81a0c0e120 세력일람 업데이트 2018-07-27 02:33:56 +09:00
Hide_D 0dae71a644 회피 디버그 수정 2018-07-26 17:13:27 +09:00
Hide_D f8eedaa3ea 전투 디버그 2018-07-26 15:40:46 +09:00
Hide_D ce2d97a7e7 전투 회피 코드 디버깅 적용 2018-07-26 15:39:34 +09:00
Hide_D 2cb570eaca foreach reference loop 버그 2018-07-26 00:12:12 +09:00
Hide_D c8c4352957 기존 도시/암행부 스크립트 통합. 2018-07-25 23:58:58 +09:00
Hide_D a311db4555 서버 관리 창에 에러 로그 보기 버튼 추가 2018-07-23 23:44:48 +09:00
Hide_D 05c515b2da j_map_history에서 fallback arg 제거 2018-07-23 23:30:53 +09:00
Hide_D c1acf2b0fe Trace의 모든 내용이 나오도록 수정 2018-07-23 23:26:32 +09:00
Hide_D 803a2407eb 에러 로그 보기 기능 추가 2018-07-23 23:19:39 +09:00
Hide_D a87945d1fb 에러 로그 업데이트 2018-07-23 22:54:06 +09:00
Hide_D 30793e68df 에러 로그용 클래스 설정 2018-07-23 22:50:22 +09:00
Hide_D 9c666bf7a9 FileDB 클래스 추가 2018-07-23 22:37:30 +09:00
Hide_D eff1dd7c34 라이브러리 업데이트 catfan/medoo 추가 2018-07-23 21:27:26 +09:00
Hide_D e79a33ebb0 NPC 군주의 호전성 추가(?) 2018-07-23 02:56:33 +09:00
Hide_D cb0adfdeaf npc attackable 보완 2018-07-23 02:50:58 +09:00
Hide_D 6b135c343c NPC의 선포 대상을 '국력'이 낮은 국가에 더 잘 하도록 변경 2018-07-23 01:49:43 +09:00
Hide_D 6c92db524b 선포 코드를 조금더 직관적으로 수정 2018-07-23 01:28:34 +09:00
Hide_D b8dfd1c041 징,모병시 민심이 떨어지지 않는 버그 수정 2018-07-22 15:39:53 +09:00
Hide_D 54d6347c1d 사령부 휴식 커맨드가 제대로 안보이는 문제 해결 2018-07-22 15:10:37 +09:00
Hide_D 4ea6e90600 연감에 serverID가 잘못된 경우 해결 2018-07-22 03:37:14 +09:00
Hide_D 4c7628a247 부대편성의 '집합' 확인 코드가 하드코딩인 부분 수정 2018-07-22 03:28:10 +09:00
revofpla 6c7334155a 필살확률 무조건 최소 50%인 버그 픽스 2018-07-21 13:49:15 +09:00
revofpla 480e3ea974 체섭 버그로 인한 핫픽스 1차
- 징병 숙련 100배 문제
 - 모병 비용 2배로 계산 안되는 문제
2018-07-21 13:12:52 +09:00
Hide_D 1f639a5bc6 애니집결 시나리오 번호 변경 2018-07-20 19:53:21 +09:00
Hide_D ccf3b07c3a 애니집결 업데이트 2018-07-20 19:51:11 +09:00
Hide_D d8508f2b72 충차가 1등급 되기만 하면 쓸 수 있던 버그 수정 2018-07-20 10:44:14 +09:00
Hide_D 5e13961ec8 protected인 자료에 접근해서 발생하는 문제 수정 2018-07-20 10:05:08 +09:00
Hide_D 80b1139371 버튼 너비 수정 2018-07-20 09:12:37 +09:00
Hide_D 635b41765c 계정 관리 창 살짝 넓힘 2018-07-20 09:08:04 +09:00
Hide_D 4b03686aa2 숙련 단련 버그 수정 2018-07-20 09:01:50 +09:00
Hide_D bfb0d8d639 message 템플릿 버그 수정 2018-07-20 00:06:03 +09:00
Hide_D 93d4a0211d 등용장의 경우에도 누를수 없는 경우 수정 2018-07-19 23:59:27 +09:00
Hide_D cd31bc69ef 추방 버그 수정 2018-07-19 23:13:05 +09:00
Hide_D 4a7b84d6de 외교 서신 레벨 지정 2018-07-19 22:19:26 +09:00
Hide_D 3142714c11 리셋 첫 해에는 추방해도 제약 없음 2018-07-19 21:25:00 +09:00
Hide_D 7ea10416a9 임관 권유 메시지 창 2018-07-19 21:03:42 +09:00
Hide_D 3e427db0f1 relativeYear에 음수 불가 2018-07-19 20:53:46 +09:00
Hide_D 9f7b18d294 시작 시 develcost가 0인 버그 해결 2018-07-19 20:50:29 +09:00
Hide_D 9af0e351b8 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2018-07-19 20:06:51 +09:00
Hide_D 5c6aa2340d 공백지 시나리오에 특기 연령 문제 해결 2018-07-19 20:06:39 +09:00
Hide_D 4424ec48cf 전투시 병종 명 버그 수정 2018-07-19 10:59:01 +09:00
Hide_D 61be34581e 반복 버튼 키움 2018-07-19 02:33:59 +09:00
Hide_D 731978356d Credit 양식 추가 2018-07-19 02:29:03 +09:00
Hide_D d5223ad1ab 리셋 시 사령부 Command encode가 제대로 이뤄지지 않았던 버그 수정 2018-07-19 01:42:16 +09:00
Hide_D 7cfdfab198 연감에서도 비교적 빠르게 동작하도록 설정 2018-07-19 01:31:13 +09:00
Hide_D eb70e51ac1 실시간 맵은 캐싱하도록 처리 2018-07-19 01:21:00 +09:00
Hide_D 1d48e7c7ae 영웅 난무 220 제목 변경 2018-07-19 00:51:47 +09:00
Hide_D d6fc9fc8c3 지도가 들어간 곳에 부트스트랩 추가 2018-07-19 00:46:15 +09:00
Hide_D 8ada0976fe 연감에 부트스트랩 없는 문제 해결 2018-07-19 00:44:01 +09:00
Hide_D 389ff5e9a4 지도에 도시명 켬끔 추가 2018-07-19 00:39:05 +09:00
Hide_D 5179e0228c 최대 스탯 표기 변경 2018-07-18 23:44:41 +09:00
Hide_D 2268526314 내 정보 페이지 툴팁 안나오는 문제 2018-07-18 23:14:52 +09:00
Hide_D db4bc0eafe 도시 좌표 업데이트 2018-07-18 23:11:02 +09:00
Hide_D 6edaf79df1 출력 병종 에러 2018-07-18 22:26:15 +09:00
Hide_D 79cead3b59 도시 css contain 2018-07-18 22:24:22 +09:00
Hide_D db1b12b85c 훈련에서 사기 하락 문구 삭제 2018-07-18 16:54:25 +09:00
Hide_D 9360b7675a 천인 강림 극 소형맵 2018-07-18 14:23:12 +09:00
Hide_D 9c82fd17fe 훈련시 사기 감소하지 않음 2018-07-18 11:18:33 +09:00
Hide_D 3a4665e473 맵 업데이트 2018-07-18 10:46:33 +09:00
Hide_D b34f4648ee 호로->사수, 몇몇 소성들 다시 진,수로 롤백 2018-07-18 10:41:06 +09:00
Hide_D 0de786d2ea 쿼리 받아오는 것 수정 2018-07-18 09:28:53 +09:00
Hide_D ec7aafa1ff history 받아오는 버그 수정 2018-07-18 09:28:10 +09:00
Hide_D 30c219716d 오타 수정 2018-07-18 09:08:20 +09:00
Hide_D 5dd47cb89b 오타수정 2018-07-18 09:05:36 +09:00
Hide_D abe856bd3f 버그 수정. 오타 수정 2018-07-18 08:24:09 +09:00
Hide_D 6ecb009466 오타 수정 2018-07-18 04:51:19 +09:00
Hide_D 3b4b2383a8 $me 버그 2018-07-18 04:50:17 +09:00
Hide_D 4ddd46c4a2 모병코드 2018-07-18 04:49:30 +09:00
Hide_D 69ec2469b4 쌀 검사 코드 2018-07-18 04:47:28 +09:00
Hide_D 5789af801a 징모병창 코스트 2018-07-18 04:44:12 +09:00
Hide_D 7171b6302b formattext 2018-07-18 04:41:08 +09:00
Hide_D 51d4818b1e gameStor 값 버그 2018-07-18 04:40:18 +09:00
Hide_D 1c2875e7fc 모병창 수정 2018-07-18 04:37:00 +09:00
Hide_D 5048a88310 징병창 우선 부활 2018-07-18 04:30:54 +09:00
Hide_D aef37f4362 징모병창 변수명 에러 2018-07-18 04:18:15 +09:00
Hide_D d04641041b 아이템 return 값 수정 2018-07-18 04:15:28 +09:00
Hide_D 67b2ccea86 급한대로 도시명 띄움 2018-07-18 04:10:07 +09:00
Hide_D 5ff9ca3c99 miniche가 최신 버전이 아닌 버그 수정 2018-07-18 03:44:32 +09:00
Hide_D fe55df8b2f 버그 체크 2018-07-18 03:41:45 +09:00
Hide_D 457f605898 버그 수정 2018-07-18 03:32:47 +09:00
Hide_D 0f2625133f 미니체 basemap 2018-07-18 03:05:36 +09:00
Hide_D fa34dbdf6f 초기 버그 수정 2018-07-18 03:04:59 +09:00
Hide_D 050913b0b4 영난 1c 2018-07-18 02:58:56 +09:00
Hide_D a47e47d42c 도시 정보 업데이트 2018-07-18 02:57:08 +09:00
Hide_D 43d994b59a credit 링크 추가 2018-07-18 02:31:15 +09:00
Hide_D e8204d46ce 커스텀 맵 준비 2018-07-18 00:25:51 +09:00
Hide_D fece659cfb 변수명 통일 2018-07-16 02:56:52 +09:00
Hide_D 695265b299 병종 코드를 GameUnitConst, GameUnitDetail에 기반하도록 변경 2018-07-16 02:54:47 +09:00
Hide_D b652ed0b33 병종 테이블에 상성 값 확장 2018-07-16 01:43:11 +09:00
Hide_D 9a641552e4 전투 코드 반영 중 2018-07-15 01:46:29 +09:00
Hide_D 3d18aeb5bc 징병, 모병 form 수정 2018-07-15 01:01:36 +09:00
Hide_D b545afce50 모병, 징병 코드 재 구현. 능력치 상승/감소 코드 재구현 2018-07-14 22:41:10 +09:00
Hide_D 8fca98c0c9 ActionLogger rollback 추가 2018-07-14 18:23:31 +09:00
Hide_D 0a98c71dfe 현재까지 작업물 보강, 모.징병 페이지 개선 중 2018-07-14 18:17:37 +09:00
Hide_D ed75f39094 ActionLogger 보강 2018-07-14 18:17:18 +09:00
Hide_D 456245f23a ActionLogger 추가 2018-07-14 17:53:08 +09:00
Hide_D b4529c9338 병종값 변경 2018-07-13 00:41:56 +09:00
Hide_D 0ca7a8ab8a 병종 테이블에 '병종 타입' 지정, 턴 커맨드를 json array로 변경 2018-07-13 00:12:12 +09:00
Hide_D 02f2209e8f GameConst에 mapName과 unitSet추가 2018-07-12 01:59:32 +09:00
Hide_D fb72d02912 d_setting 디렉도리 보관 방식 변경 2018-07-12 01:56:46 +09:00
Hide_D 665fb25fc1 기본 파일 추가 2018-07-12 01:02:28 +09:00
Hide_D 742c3c7156 맵 규격 재 정의 2018-07-12 01:00:24 +09:00
Hide_D 637dbbba0d 새 지도 준비를 위해 커밋 2018-07-12 00:20:43 +09:00
Hide_D f2a3bc4626 메시지함 높이 고정을 최소 높이로 변경 2018-07-11 23:49:57 +09:00
Hide_D e8ffa44544 메시지함 사라지는 버그 수정? 2018-07-11 23:04:38 +09:00
Hide_D bc09287666 도움 주신 분 임시 삭제. 나중에 Credit으로 되살리기로 2018-07-11 22:37:36 +09:00
Hide_D 392d9055fe td tr 되돌려놓음 2018-07-11 22:18:08 +09:00
Hide_D 0ee833d7ae list 일부 수정. tfoot 안에 tr td없는거 수정 2018-07-11 22:17:03 +09:00
Hide_D 3074bc00d7 지도 표기에서 box 표기 문제로 일부 수정 2018-07-11 22:04:20 +09:00
Hide_D cb6fb590c4 귀병, 환술 설명 수정 2018-07-11 21:53:13 +09:00
Hide_D a7270b2cd2 장수 성격, 아이템 설명 툴팁 추가 2018-07-11 21:50:01 +09:00
Hide_D 0d925af065 tooltip html trim 추가 2018-07-11 20:52:46 +09:00
Hide_D 7c7991e8ae 특기 없을 때 텍스트 수정 2018-07-11 20:51:13 +09:00
Hide_D 54461b6ea4 특기가 없는 경우에도 tooltip 띄우도록 2018-07-11 17:03:47 +09:00
Hide_D 6a17497fbd 빙의 시에도 전특 표기 2018-07-11 03:27:27 +09:00
Hide_D 84f18aa4b6 특기 전 페이지에 반영 2018-07-11 03:03:52 +09:00
Hide_D 73ab38563f 특기 마우스 오버 1차 적용 2018-07-11 02:47:31 +09:00
Hide_D 1f2b40e4d4 message form box sizing 변경. 메인 페이지에 bootstrap css 적용 2018-07-11 01:31:59 +09:00
Hide_D 1d920c5935 darkly 적용 2018-07-11 01:19:24 +09:00
Hide_D 037a1e9c0c 툴팁 준비 2018-07-11 01:15:22 +09:00
Hide_D 87e324d4d9 bootstrap 최신 버전으로 2018-07-11 01:15:02 +09:00
Hide_D d1e9b489e3 공성 전특 버그 수정. 전특 설명을 위한 텍스트 추가 2018-07-11 00:53:10 +09:00
Hide_D 34f1d538d1 세력도시에서 n장, m장 임명이 불가능한 버그 수정 2018-07-07 05:13:22 +09:00
Hide_D fb8d2a2e01 구버전 첩보 마이그레이션시 지도 표기 버그 수정 2018-07-07 04:58:19 +09:00
Hide_D 837db5183e 첩보를 join '|' 에서 json dict로 변경 2018-07-07 04:39:44 +09:00
Hide_D a556877a17 현재 진행중인 깃수인 경우 장수가 안 죽었으면 안나타나는 문제 해결 2018-07-05 00:24:03 +09:00
Hide_D bcbd6dc4db 왕조일람 버그 수정 2018-07-05 00:12:34 +09:00
Hide_D 41f7ad8d75 왕조 일람에 아무것도 없을 때 '현재'가 안보이는 문제 해결 2018-07-05 00:10:33 +09:00
Hide_D 258d4b28da 왕조 일람에 현재 국가 표시 2018-07-05 00:05:48 +09:00
Hide_D 31e900c422 메시지 버그 수정 2018-07-03 22:09:07 +09:00
Hide_D 7b1a76871a parseJsonPost 기반 동작 포기 2018-07-03 21:35:17 +09:00
Hide_D c6f3e7672f 국가 정보 빈칸 2018-07-03 20:48:34 +09:00
Hide_D 540c31903c 월마다 최대 국력, 최대 병력, 최대 도시 수를 계산하는 코드 추가. ng_old_nations에도 반영 2018-07-03 20:43:14 +09:00
Hide_D 3e5262d7a3 nation 테이블에 aux 추가 2018-07-03 20:09:36 +09:00
Hide_D 2b36ffef45 왕조일람 임시 갱신 2018-07-03 06:59:27 +09:00
Hide_D 4c25d2275c 버튼 대체 css 추가. form 일부 제거 2018-07-03 02:55:45 +09:00
Hide_D 6c66fcdfc3 명예의 전당 시나리오명 제대로 표기 안되는 문제 해결 2018-07-02 19:45:41 +09:00
Hide_D aaa972d767 명예의 전당 배경색 오류 수정 2018-07-02 19:15:43 +09:00
Hide_D 45c8538426 빙의 해제시 닉네임 초기화 2018-07-02 03:23:20 +09:00
Hide_D 95702724a9 베팅수익률 오타 2018-07-01 15:34:20 +09:00
Hide_D 98c4d3853c 명장 일람 레퍼런스 값 미표기 문제 해결 2018-07-01 15:30:15 +09:00
Hide_D 7c91143f39 명장일람에서 제약 조건 수정 2018-07-01 15:27:41 +09:00
Hide_D 56e6f57568 회원 가입시 링크 변경 2018-07-01 03:58:47 +09:00
Hide_D ccab456679 세력도시 스크립트 동작 안하는 문제 해결 2018-07-01 01:35:47 +09:00
Hide_D 5af000ca43 html 5 비표준 스크립트 제거 2018-07-01 01:28:35 +09:00
Hide_D 354c8f04ae IE=edge 대소문자 주의 2018-06-30 01:52:07 +09:00
Hide_D 3fbd336b45 Revert "컬러 프로필 적용"
This reverts commit 4f279c49c8.
2018-06-30 01:32:46 +09:00
Hide_D 3c0b86a322 컬러 프로필 적용 2018-06-30 01:26:23 +09:00
Hide_D fca4b69d5a 범장 -> 만능장 2018-06-30 01:18:52 +09:00
Hide_D ce62072761 확장 스크립트를 위해 태그 일부 정리 2018-06-30 00:28:45 +09:00
Hide_D 93dd7a8478 extractMissingPostToGlobals 호환을 위해 server_id 인자명 변경 2018-06-29 16:23:48 +09:00
Hide_D 02fb84a312 font boosting 약화 2018-06-29 14:46:06 +09:00
Hide_D f3e68989e5 뷰포트 추가 지정 2018-06-29 14:41:09 +09:00
Hide_D 468050a9ce 뷰포트 크기 변경 2018-06-29 14:37:30 +09:00
Hide_D f37a602da3 모든 웹 페이지에 viewport 지정 2018-06-29 14:32:59 +09:00
Hide_D 2979691d7e 기본 폰트 크기 지정 2018-06-29 14:20:20 +09:00
Hide_D 72920a0432 unset대신 []로 초기화 2018-06-29 09:35:24 +09:00
Hide_D e81075ef04 history 함수 인자 제한 완화 2018-06-29 09:28:58 +09:00
Hide_D df1a99d877 기본 폰트 지정 2018-06-29 09:16:40 +09:00
Hide_D 10e825dc9f 예약 테이블 점검. 스키마 수정 2018-06-29 01:50:28 +09:00
Hide_D 07ba7933fb 토너먼트 inf 버그 수정 2018-06-29 01:25:43 +09:00
Hide_D 3059eac0fd jquery 버전 업데이트 2018-06-29 01:22:03 +09:00
Hide_D aa33aa6d4f Json 에러시 에러 표기하도록 2018-06-29 00:30:05 +09:00
Hide_D 0a1cdeeaa3 세력일람 코드 변경 2018-06-28 14:16:38 +09:00
Hide_D e4bef47b7e 세력일람 연동 2018-06-28 14:14:56 +09:00
Hide_D f551f994b5 세력도시 코드 일단 통합 2018-06-28 13:57:21 +09:00
Hide_D 4b7a3af691 IE에서 카카오 2018-06-28 13:39:58 +09:00
Hide_D 6f88a80118 randBool이 아니라 randF 써서 생기는 버그 수정 2018-06-28 01:57:41 +09:00
Hide_D e03715ee46 천통 안되는 버그 수정 2018-06-28 00:28:00 +09:00
Hide_D aafe6d8863 천통시 저장되는 데이터 변경 2018-06-27 03:43:01 +09:00
Hide_D 47005483cd 버그 수정 2018-06-27 03:05:39 +09:00
Hide_D 378075955a 서버 오픈시 천통국 체크가 이상한 버그 수정 2018-06-27 03:04:54 +09:00
Hide_D 2059797904 사망, 천통시 장수를 ng_old_generals에 보관 2018-06-27 02:53:58 +09:00
Hide_D 8c711242a9 왕조 일람에 연감을 볼 수 있도록 통합 2018-06-27 02:12:59 +09:00
Hide_D 481894c89b 모든 국가 멸망 케이스에 ng_old_nations 백업 추가 2018-06-27 01:55:28 +09:00
Hide_D ba53275322 천통시 깃수 자동 표기 2018-06-27 01:49:46 +09:00
Hide_D cfe2b4c1bd 사소한 코드 수정 2018-06-27 01:34:11 +09:00
Hide_D 60e83f8324 오타 수정 2018-06-27 01:26:02 +09:00
Hide_D ceac040d82 명전에 0 이하는 안받도록 변경 2018-06-27 01:25:50 +09:00
Hide_D 89d400c81a 연감 월 표기 버그 수정 2018-06-27 01:22:16 +09:00
Hide_D 4cf7bca399 왕조 일람에서 서버 정보와 국가 정보를 보관하도록 변경 2018-06-27 01:14:34 +09:00
Hide_D 761441622e 왕조일람 '전체보기' 기능 살림 2018-06-26 23:05:04 +09:00
Hide_D 1b814abf0b 천통 시 왕조 일람용 테이블에 server_id 기록. 연감에 server_id로 이전 연감 조회기능 추가 2018-06-26 23:01:43 +09:00
Hide_D 62a2147e33 천통국 정상 추가 2018-06-26 22:45:47 +09:00
Hide_D 246dff9c87 명장일람 버그? 2018-06-26 16:27:51 +09:00
Hide_D 50494beb27 명장 일람 보정 시도 2018-06-26 16:21:47 +09:00
Hide_D ce3b3ebfd8 명장 일람, 설전 승률 % 표기 오류 2018-06-26 16:18:58 +09:00
Hide_D 213090c32e 오타 수정 2018-06-26 09:45:15 +09:00
Hide_D adb8668197 크롬과 파이어폭스에 최적화 2018-06-26 09:44:26 +09:00
Hide_D 0023677003 임관 권유문 길이 제한 2018-06-26 04:13:41 +09:00
Hide_D 0b19a37ad4 초반 3년 수뇌 임명 방식 변경 2018-06-26 03:52:17 +09:00
Hide_D 9f34ae5d28 천통시 재야 장수도 저장 2018-06-26 03:33:56 +09:00
Hide_D 6f07b5cf08 ng_games에 시나리오명 남도록 수정 2018-06-26 03:20:57 +09:00
Hide_D 0f39431157 chmod 재설정 2018-06-26 03:19:47 +09:00
Hide_D bc1a470e64 디렉토리 권한 문제 해결 2018-06-26 03:15:38 +09:00
Hide_D 09e24f5684 ng_games 누락분 추가 2018-06-26 03:10:50 +09:00
Hide_D 2f27ea4c8a schema 값 꼬이는 문제 해결 2018-06-26 03:06:34 +09:00
Hide_D d09aba70b7 천통시에도 ng_old_nations에 데이터가 저장되도록 변경 2018-06-26 03:00:02 +09:00
Hide_D 69b0a80684 명장 일람, 명예의 전당 최종 개선 2018-06-26 02:36:20 +09:00
Hide_D 48f0c56a9e 국가 멸망시 국가 정보 백업 2018-06-26 00:47:54 +09:00
Hide_D 83833a3693 등용장 및 메시지 일괄 전송 TODO 해결 2018-06-26 00:45:31 +09:00
Hide_D 18429d52d4 명장 일람, 명예의 전당 코드 재구현. 연감 등에 이전 국가 기록 남기도록 설정 2018-06-26 00:32:43 +09:00
Hide_D 58cc90083b 서버 별명에 연월일 추가 2018-06-25 16:08:19 +09:00
Hide_D 2772161144 왕조 일람 테이블 구조 변경. 2018-06-25 01:53:16 +09:00
Hide_D 0e95259b14 게임 오픈 시 logs에 서브 디렉토리를 사용하도록 변경 2018-06-25 01:45:23 +09:00
Hide_D 3d9f38f1e3 건국 등 문자열 입력 변경 2018-06-25 00:46:07 +09:00
Hide_D ba3accd834 스페이스 바 등 몇몇 문자열 가능하게 처리 & 문자열 보정 2018-06-24 04:44:34 +09:00
Hide_D 0786e40ebd 국방 표기 변경 2018-06-24 04:18:54 +09:00
Hide_D 8a56393159 임관 권유 메시지를 템플릿으로 이동 2018-06-24 04:12:19 +09:00
Hide_D 5ca8a6ecfa purifier 1차 적용 2018-06-24 03:47:44 +09:00
Hide_D 5c82edc4be html purifier 보강 2018-06-24 02:56:38 +09:00
Hide_D 093c04bc24 포상 계수 조절 2018-06-23 23:49:22 +09:00
Hide_D 131dd46a38 무지장의 경우에는 쌀 적게 주도록 수정 2018-06-23 22:58:11 +09:00
Hide_D 6b1b4fdfbb 베팅 표기 오류 변경 2018-06-23 22:55:59 +09:00
Hide_D e4ad779b37 npc 발령 로직 변경. 유저 무지장 포상 로직 변경 2018-06-23 22:52:43 +09:00
Hide_D 65d817624e 인사부 조건 검사 순서 변경 2018-06-23 14:36:05 +09:00
Hide_D 66501189c4 적극적 금쌀 교환 2018-06-23 14:22:41 +09:00
Hide_D 4303898bb8 금쌀 계수 조정 2018-06-23 14:10:52 +09:00
Hide_D 7d76a9d3ed 인사부 임명 해제 불가 버그 수정 2018-06-23 13:28:36 +09:00
Hide_D 1cc42f341b 내정, 전투 기준 일부 변경 2018-06-23 13:08:16 +09:00
Hide_D 0b41ee0a29 내정 발령시 내정 찬곳으로는 안함 2018-06-23 12:57:11 +09:00
Hide_D 66b6c4d04f query 간소화 2018-06-23 05:37:34 +09:00
Hide_D 6502843d6c 포상 전략 변경 2018-06-23 05:22:49 +09:00
Hide_D 5ecfe72e19 발령 전략 변경 2018-06-23 05:06:10 +09:00
Hide_D f28cdefffe npc 발령 전략 변경 2018-06-23 05:00:57 +09:00
Hide_D 40494f2cf1 전방 설정을 5개월 내로 변경 2018-06-23 04:51:07 +09:00
Hide_D f2664c112b NPC 사령턴 로직 새로 작성 2018-06-23 04:45:27 +09:00
Hide_D 41d91df355 상인 거래시 110% 가 잘 적용되도록 변경. 삭제된 거상 문구 수정 2018-06-23 02:23:06 +09:00
Hide_D 965671dd93 key,value pair를 보존한 섞기 추가 2018-06-23 02:22:49 +09:00
Hide_D c8d08e4b2c 저격 특기, 활 유니크, 수극 확률이 각각 적용되도록 수정 2018-06-23 02:22:32 +09:00
Hide_D 2897a9b484 환상향 시나리오 전콘 방식 재 적용 2018-06-21 20:16:01 +09:00
Hide_D d190e59d83 장수 등록시 최저 스탯이 10으로 표시되는 버그 수정 2018-06-21 02:55:52 +09:00
Hide_D 0bb25e8773 천인 강림 개선 2018-06-21 02:47:29 +09:00
Hide_D 37e1903cb1 HTML Purifier 추가 2018-06-21 02:27:02 +09:00
Hide_D b402846d43 PHP 7.2 버전용으로 올림! 2018-06-21 02:17:31 +09:00
Hide_D c1a6dd385a 설문 제목이 제대로 표시되지 않는 버그 수정 2018-06-19 02:42:55 +09:00
Hide_D ccbef236d3 업데이트 기능 추가 2018-06-19 02:11:17 +09:00
Hide_D d7b9e8b2e0 투표 동작 방식 변경 2018-06-19 01:49:16 +09:00
Hide_D deaf77d3d0 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2018-06-19 01:42:46 +09:00
Hide_D 5c738f97ed 투표 권한 추가 2018-06-19 01:42:40 +09:00
Hide_D c9f7f7ab08 공지 수정 불가능한 버그 수정 2018-06-18 10:11:56 +09:00
Hide_D 746977d5d0 서버 열단, 리셋 부분 권한 추가 2018-06-18 03:21:52 +09:00
Hide_D acb09bfe71 시나리오 생성시 잘못된 도시를 입력한 경우에도 정상 빌드되도록 수정 2018-06-18 02:23:30 +09:00
Hide_D e2a1203b43 시나리오 두개 수정 2018-06-18 02:01:45 +09:00
Hide_D 124036cea6 npc 생성시 전콘이 있는지 확인하는 코드 추가. 걸그룹 대전 변경 2018-06-16 11:01:12 +09:00
Hide_D 2ac1d82826 buildScoutMessage에서 null 반환 가능하던 문제 수정 2018-06-16 00:42:48 +09:00
Hide_D fa4e0c1948 이미지 주소 기반 자동 NPC 전콘 설정 기능 추가. 루드라사움 추가 2018-06-15 03:32:37 +09:00
Hide_D 735427ead0 기본 iconPath 설정 2018-06-15 02:18:44 +09:00
Hide_D 4fa99a7e1b 변환 코드를 v3에 맞게 변경 2018-06-15 02:17:07 +09:00
Hide_D 2f963a205a 등용장 안 받아지는 버그 수정 2018-06-14 02:41:36 +09:00
Hide_D 1f03f7e7c3 빙의 모드에서 장수 칸 여유있게 2018-06-14 02:00:09 +09:00
Hide_D 31689fb6ba processCommand에 affinity 없는 버그 수정, 등용장 못받는 버그 수정 2018-06-14 01:57:28 +09:00
Hide_D cf7ebbd314 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2018-06-14 01:49:22 +09:00
Hide_D 40a953aed5 storage의 isunited 변수 문제 2018-06-14 01:49:15 +09:00
revofpla c4d999ada7 가상시나리오 16(애니집결) 추가 2018-06-13 17:46:34 +09:00
Hide_D fff6b4e155 개전시 조사 버그 2018-06-13 10:20:48 +09:00
Hide_D 380e08d89f 랜임시 장수수를 셀 때 유저장, 빙의장, n장만 카운트하도록 변경 2018-06-13 04:17:18 +09:00
Hide_D 96c8199092 거병 확률 최종 수정 2018-06-13 03:50:51 +09:00
Hide_D 54870cf067 거병 확률 재 수정 2018-06-13 03:29:09 +09:00
Hide_D 8654447aac 추방 기준을 3년 이내로 재 변경 2018-06-13 03:28:11 +09:00
Hide_D 28a690cbba 추방 후 임관 확률 재 조정 2018-06-13 03:27:08 +09:00
Hide_D 52d1a48c0b 거병 확률 변경. NPC 임관 확률 추가 변경 2018-06-13 03:21:55 +09:00
Hide_D f45333db5e 임관 속도 조정 2018-06-13 03:06:30 +09:00
Hide_D c920e45934 임관 시도 확률 변경, NPC 랜임시 부상 패널티 약화 2018-06-13 02:51:39 +09:00
Hide_D dd86ef4591 걸그룹 시나리오 수정, NPC 임관 확률 대폭 감소 2018-06-13 02:45:00 +09:00
Hide_D b9fb00f042 npc 거병 확률 수정 2018-06-13 02:29:37 +09:00
Hide_D 355d9fd995 거병 확률 계수 변경 2018-06-13 02:24:52 +09:00
Hide_D b68c13c4f2 임관시 $general['nations'] 를 Json Array로 변경 2018-06-13 02:21:31 +09:00
Hide_D f2803291ab 일부 브라우저에서 명령창 줄 넘어감 방지 2018-06-13 00:53:31 +09:00
Hide_D 54df034c77 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2018-06-12 22:28:10 +09:00
Hide_D 7317b8bc18 JosaUtil 응급 대응 2018-06-12 13:05:22 +09:00
Hide_D 2f030a6dd6 NPC 임관 로직 변경 2018-06-12 02:47:33 +09:00
Hide_D ef0dec32ee 임관 제한을 하드코딩 10에서 Const로 전환 2018-06-12 01:32:34 +09:00
Hide_D e7f5850c31 Session 클래스 구조 살짝 수정. 호출 구조 살짝 수정.
환상향 시나리오 전콘 반영(임시)
2018-06-11 22:55:32 +09:00
Hide_D d1d81e03d1 makenation 텍스트에 null이 들어가는경우(??)에도 우회 동작.
변환 스크립트에서 숫자 장수명 대응
2018-06-11 20:27:55 +09:00
Hide_D c65d6565df checkSupply를 검출하기 쉬도록 변경 2018-06-11 03:20:18 +09:00
Hide_D a2d40ecf4a 재야가 아닌 NPC 시나리오 생성시 버그 수정 2018-06-11 03:19:47 +09:00
Hide_D 7291c828c0 isGameLoggedIn 추가 2018-06-11 02:16:07 +09:00
revofpla 01caa625bd 환상향 시나리오 및 소울소드(8글자 신규) 업데이트 2018-06-10 16:55:34 +09:00
Hide_D 6cad6f45fe 전투 로그 숫자를 최악의 조건에도 표현 가능하도록 수정 2018-06-04 03:05:30 +09:00
Hide_D a6936ac8d7 연감 표기 수정 2018-06-04 02:28:33 +09:00
Hide_D eb9ae00d24 명예의 전당 글자수 반영 2018-06-04 01:52:33 +09:00
Hide_D b8c8321757 명장일람 글자 반영 2018-06-04 01:51:10 +09:00
Hide_D 41235bed5d 닉네임 길이 9자 2018-06-04 01:11:02 +09:00
Hide_D 7367eb1c45 메시지 시스템에 9자 닉네임 적용 2018-06-04 01:03:05 +09:00
Hide_D f9d90c38ef 전투 로그 길이 축소 2018-06-01 03:11:46 +09:00
Hide_D 275d9b1c25 한자 케이스 우회 2018-06-01 03:01:06 +09:00
Hide_D 663c24b31f 나머지 조사 변경 2018-06-01 02:49:21 +09:00
Hide_D beb501354d (이)가 조사 적용 2018-06-01 02:37:32 +09:00
Hide_D ba165239c3 (으)로 조사 반영 2018-06-01 01:59:19 +09:00
Hide_D e64ef5de84 (을)를 에 조사 적용 2018-06-01 01:43:40 +09:00
Hide_D c6bbbe081d 조사 유틸 한자 포함 2018-06-01 00:34:33 +09:00
Hide_D 66dcefc844 JosaUtil 버그 수정. 알파벳+숫자 형태 수정 2018-05-31 23:58:49 +09:00
Hide_D 93d580e74e 조사 처리 클래스 추가 2018-05-31 02:50:58 +09:00
Hide_D 9eb35b55c6 설문조사 너비 반영 2018-05-31 02:49:48 +09:00
Hide_D d2e052dfa3 회의실, 기밀실 너비 수정 2018-05-31 01:20:26 +09:00
Hide_D ddd889c42c 중원정보 너비 수정 2018-05-31 00:59:27 +09:00
Hide_D 70da3909a9 cacheValue 버그 수정 2018-05-31 00:52:43 +09:00
Hide_D c398b55f3c 턴 밀림 버그 수정 2018-05-31 00:46:40 +09:00
Hide_D 317c42b384 장수명을 9글자까지 반영할 수 있도록 수정하고. 레이아웃 틀어지지 않도록 수정 진행중 2018-05-30 02:47:33 +09:00
revofpla a95903ceff 소울소드 시나리오(가상14번) 추가 2018-05-29 14:40:49 +09:00
Hide_D 98c386622a 버그 수정 2018-05-29 01:50:50 +09:00
Hide_D 398f54cced 군주가 지정되지 않더라도 안전하게 동작 2018-05-29 01:49:06 +09:00
Hide_D c337ff2f67 변환 스크립트 동작 변경, 환상향 시나리오 적용 2018-05-29 01:28:03 +09:00
Hide_D d9f6f7956e 시나리오 json 파일에서 받아오는 규격 확장
국가를 'string'으로 표기 가능하도록 변경
전콘 번호를 'string'으로 표기 가능하도록 변경
2018-05-28 23:08:59 +09:00
revofpla 30e2432fc3 걸그룹대전 스텟 변경 2018-05-28 18:50:02 +09:00
Hide_D 8238f27dfa 환상향 스탯 2018-05-26 22:32:46 +09:00
Hide_D b00d8f2ebd 하드리셋 버그 수정 2018-05-26 17:51:46 +09:00
Hide_D 98168c61b3 서버 2개 추가. 냐. 퍄. 2018-05-26 17:47:54 +09:00
Hide_D 6627797cc6 Merge branch 'devel' of https://storage.hided.net/gogs/devsam/core into devel 2018-05-26 17:36:36 +09:00
Hide_D 30e54c3d0e 34번 시나리오 중복 장수 제거 2018-05-25 23:12:33 +09:00
Hide_D ee3764f5f5 걸그룹 시나리오 추가 2018-05-25 22:50:59 +09:00
Hide_D a86e4cf64b 전콘 사이즈 확장 2018-05-25 00:51:03 +09:00
Hide_D 78ea405e40 영웅난무 스탯 변경 2018-05-24 23:41:38 +09:00
Hide_D f99583dc99 시나리오 능력치 수정. 영웅난무2 수정 2018-05-24 23:39:42 +09:00
Hide_D b9e5ddce94 c_myBossInfo 수정. RegNPC nullable 변경 2018-05-24 23:33:07 +09:00
Hide_D 1d28f22577 도시 정보, 장수 목록 2018-05-22 02:36:00 +09:00
Hide_D 90235660db 세력 도시 너비 조절 2018-05-22 02:25:53 +09:00
Hide_D 8e12aea3ff 오타 수정 2018-05-22 01:51:19 +09:00
Hide_D 280ff18526 세력 일람에서 장수명 너비 확보 2018-05-22 01:50:47 +09:00
Hide_D 9e88b03438 autoreset 버그 수정 2018-05-21 23:52:13 +09:00
Hide_D 14213ea3cd 토너먼트 인자 실수 체크 2018-05-21 23:22:49 +09:00
Hide_D 5352a507b2 삼11 시나리오 유저 스탯캡 조절 2018-05-21 22:54:25 +09:00
Hide_D 3b382199fc 리셋 시 최대 스탯 보여주도록 변경 2018-05-21 22:51:03 +09:00
Hide_D 67dea49a9b 삼국지11 시나리오 스탯 재 변경 2018-05-21 22:33:06 +09:00
Hide_D 8bdca87bf9 확장 장수 안되는 버그 해결. 환상향 시나리오 추가 2018-05-21 16:17:33 +09:00
Hide_D 8085e96fdd gameStor 대소문자 마저 수정 2018-05-21 16:05:17 +09:00
Hide_D 86b40695e6 외교 서신 안 받아지는 버그 수정. 의병, m장 스탯 버그 해결 2018-05-21 12:16:02 +09:00
Hide_D 676f98659a storage 테이블 생성 문제 해결 2018-05-21 05:38:43 +09:00
Hide_D 2fbf8bc2e2 누락된 GameCustomConst 추가 2018-05-21 05:30:38 +09:00
Hide_D bf233f7552 시나리오마다 별도로 스탯 제한치를 설정 가능하도록 변경 2018-05-21 05:10:44 +09:00
Hide_D 2c3e577c4e 설문조사 수정 2018-05-21 03:54:43 +09:00
Hide_D 7270de6775 Merge branch 'devel' into kvstorage_game 2018-05-21 03:54:16 +09:00
Hide_D e45f3a7d03 턴 지연 버그 수정. 설문조사 % 막대 2018-05-21 03:51:04 +09:00
Hide_D 742e2e8003 설문조사 offset 버그 2018-05-21 03:42:04 +09:00
Hide_D 4cdec6c393 투표 버그 수정 2018-05-21 03:39:42 +09:00
Hide_D a2d273bdc9 설문조사 보이도록 2018-05-21 03:37:59 +09:00
Hide_D a163fbef7f 설문조사 동작 2018-05-21 03:35:53 +09:00
Hide_D ec226ede65 스탯 31 생몰년 2018-05-21 03:20:15 +09:00
Hide_D 771fcbec6a 장수 생성 버그 수정 2018-05-21 03:16:06 +09:00
Hide_D ae62669fe8 KBO 중복 장수 제거, 삼국지 11 스탯 시나리오 추가 2018-05-21 03:11:26 +09:00
Hide_D 4823795c50 토너먼트 '투입' 버그 수정 2018-05-21 01:47:36 +09:00
Hide_D a80442399d KVStorage를 무조건 소문자만 받도록 설정 2018-05-21 01:32:30 +09:00
Hide_D 913b308892 $game_env -> $admin 2018-05-21 01:05:59 +09:00
Hide_D 21837d0869 getDBValues 쓴 부분 수정 2018-05-21 00:58:28 +09:00
Hide_D 5706fcfb7d DateInterval namespace버그 수정 2018-05-21 00:51:38 +09:00
Hide_D 5bc3b55400 turnterm 대소문자 버그 수정 2018-05-21 00:49:24 +09:00
Hide_D ffbe2844e4 npcmode 대소문자 버그 수정 2018-05-21 00:47:42 +09:00
Hide_D 7776b35cab kvstorage 버그 수정 2018-05-21 00:23:50 +09:00
Hide_D c39794c086 scneraio_frame을 올바르게 서술 2018-05-20 23:04:22 +09:00
Hide_D 6aaa50364b 인사부에 스탯, 삭턴 보이도록 2018-05-20 22:37:18 +09:00
Hide_D d0778550ab Merge branch 'devel' into kvstorage_game 2018-05-20 22:20:03 +09:00
Hide_D 8cba6ac16a 커스텀 종능 대비 json 변경 2018-05-20 22:19:23 +09:00
Hide_D 0516007130 game 테이블을 모두 gameStor로 변환 2018-05-20 03:43:02 +09:00
Hide_D af9df325f0 현재까지 작업 분량 반영 2018-05-20 02:23:44 +09:00
Hide_D 4dd69db652 장수 도시를 제대로 못 받는 버그 수정 2018-05-15 22:42:14 +09:00
Hide_D 316d466795 방랑군 시나리오를 제대로 시작할 수 없는 버그 수정 2018-05-15 22:38:05 +09:00
Hide_D 3fb5b99af3 시나리오 8번 버그 수정, printJS, printCSS 버그 수정 2018-05-15 22:10:33 +09:00
Hide_D 1764504ea3 23번 시나리오 변경 2018-05-14 23:05:45 +09:00
Hide_D fab0495a39 game table 이전 2018-05-13 01:31:28 +09:00
Hide_D 166eafe4ee game 테이블을 KVStorage로 일부 대체 2018-05-13 01:26:44 +09:00
Hide_D 9d6181ede1 game table을 KVStorage로 일부 대체 2018-05-13 00:52:16 +09:00
Hide_D 67ecd514a4 KVStorage의 game namespace를 game_env로 '편의를 위해' 변경 2018-05-12 22:21:53 +09:00
Hide_D 52f4b79fdf KVStorage로 game 테이블 대체 준비 2018-05-12 22:05:44 +09:00
Hide_D 5e74a34d3e 관리자 도구 css 파일명 이상 수정 2018-05-12 16:12:45 +09:00
Hide_D 288be33eac js, css 캐시 문제로 printJS, printCSS 함수를 이용하도록 변경 2018-05-12 16:09:32 +09:00
Hide_D 451a759cca common.css 버전 올림 2018-05-12 13:01:39 +09:00
Hide_D a9052705a8 바 막대 100% 넘을때 문제 해결, 분쟁현황 막대 수정 2018-05-12 13:00:28 +09:00
Hide_D 5490e74f04 부운영자도 회원 관리 가능하도록 변경 2018-05-12 06:30:45 +09:00
Hide_D ab5768998b admin_server.js에 버전명 지정 2018-05-12 06:12:21 +09:00
Hide_D b71ae96d66 부운영자가 hwe 서버(base server)를 업데이트 할 수 없는 버그 해결 2018-05-12 06:11:31 +09:00
Hide_D e3528ac82f 부운영자도 기존의 git tree-ish 경로로 업데이트 할 수 있도록 변경 2018-05-12 06:08:48 +09:00
Hide_D bad5a3c0ef 가장 마지막에 업데이트한 git tree-ish path를 저장하는 기능 추가 2018-05-12 06:04:06 +09:00
Hide_D bb49e6dec7 KVStorage 버그 수정 2018-05-12 06:03:29 +09:00
Hide_D 2d24ba659f KVStorage에 unset 추가 2018-05-12 05:46:43 +09:00
Hide_D 29ce47251a KVStorage가 사용할 db를 직접 선택할 수 있도록 변경.
KVStorage를 전역으로 이동
2018-05-12 05:40:15 +09:00
Hide_D d02a84e87e kvstorage를 schema에 추가 2018-05-12 05:36:25 +09:00
Hide_D c5d008ec47 KVStorage에 reset추가 2018-05-12 05:32:18 +09:00
Hide_D 798be5fd5c 이용 약관, 개인정보처리 방침 이동 2018-05-12 05:07:55 +09:00
Hide_D ab6bb54eae KVStorage 추가 2018-05-12 04:59:44 +09:00
Hide_D ae24d18adb isClose의 함수이름을 isNeighbor로 변경 2018-05-12 02:04:21 +09:00
Hide_D dcfb49d927 firefox groove에 color 적용 안되는 문제 해결 2018-05-11 03:46:50 +09:00
Hide_D d82ab51d58 모병, 징병창 가운데 정렬 2018-05-11 03:30:57 +09:00
Hide_D 5166001956 턴 명령 창 가운데 정렬 2018-05-11 03:21:10 +09:00
Hide_D aa46fc9668 html5 비호환 border=1, border=0 제거. bar 태그를 div로 변경 2018-05-11 03:16:24 +09:00
Hide_D beea13ff4b checkSupply()에서 국가 select 쿼리 직접하도록 변경 2018-05-09 01:44:22 +09:00
Hide_D 766d0b3ad5 빙의 탈출 기능 임시 제한 2018-05-08 23:40:35 +09:00
Hide_D 64e279d859 빙의시 로그가 잘못 남는 버그 수정 2018-05-08 23:39:48 +09:00
Hide_D a3f6a8e8ab symfony/lock 추가 2018-05-08 00:38:29 +09:00
Hide_D 330853c98d 30번 시나리오 2018-05-07 19:34:56 +09:00
Hide_D 776e16b58b 빙의 선택 대기 시간 변경 2018-05-07 12:39:03 +09:00
Hide_D 70b1f23a49 빙의 해제용 삭턴 세팅.
- 10분 미만은 30분
- 10분 이하는 60분 대기 필요
2018-05-05 23:25:21 +09:00
Hide_D 5e4493b49a 빙의 목록을 종능 순으로 정렬해서 표현 2018-05-05 23:03:10 +09:00
Hide_D dec24e09cf 빙의시 장수명 빼먹는 버그 수정 2018-05-05 22:52:53 +09:00
Hide_D 95445d8f8a 빙의창에서 만료 후 다른 장수 보기 시 안보이는 문제 해결 2018-05-05 22:46:56 +09:00
Hide_D 683a844a08 빙의 코드 개선
- 유효 기간 관련 늘림.
- 유효 기간 가까워지면 색으로 표시. 만료 표기도 추가
- 다른 장수 보기를 남은 초 기준으로 수정
2018-05-05 22:39:21 +09:00
Hide_D a75eb5b74e 장수 선택 테이블을 schema에 추가 2018-05-05 21:44:15 +09:00
Hide_D 5dfb844c7e 빙의 재선택 시간을 빠르게 2018-05-05 21:40:59 +09:00
Hide_D 20f991a205 빙의시 오래된 데이터 삭제 2018-05-05 21:22:38 +09:00
Hide_D 3c1c339498 장수 빙의 코드 변경 2018-05-05 21:20:15 +09:00
Hide_D 5974028c4d 빙의 장수 기능 추가(선택은 미완) 2018-05-05 19:51:56 +09:00
Hide_D a534b8f812 시나리오 30번 수정 2018-05-05 19:49:22 +09:00
Hide_D cb2fbf1a32 common.js에 iconpath 연산 코드 추가 2018-05-05 19:49:07 +09:00
Hide_D a1392652ae config.css에서 div, button에 적용되던 전역 style 제거
모바일 화면에서 입구 햄버거 버튼 동작
2018-05-05 19:48:38 +09:00
Hide_D 69af23b60a Session에서 requireLogin 인자 이름을 직관적으로 변경 2018-05-05 19:45:10 +09:00
Hide_D 063b3d37a6 exception이 trace 수정하도록 임시 수정 2018-05-05 19:44:22 +09:00
Hide_D ebf9b4b75d 가상 상성인 경우 새 장수는 재야임. 2018-04-30 00:15:43 +09:00
Hide_D 45fd06c195 성인으로 등장시 월이 제대로 로그로 남지 않는 버그 수정 2018-04-30 00:01:11 +09:00
Hide_D 7db3675e71 성인 등장이 꼭 1월이 아니어도 되도록 변경 2018-04-29 23:31:21 +09:00
Hide_D a19661199e Date의 비교 대상 lhs, rhs가 바뀐 버그 수정 2018-04-29 23:13:49 +09:00
Hide_D 953196ec78 예약 오픈 시 데이터를 바로 날리진 않도록 설정 2018-04-29 12:55:16 +09:00
Hide_D d5be6e3e08 내 정보에서 숙련도를 수치로 표기 2018-04-29 04:29:46 +09:00
Hide_D 551b79d8c2 관리자 패널 접속 허용, 접속 제한 쿼리 버그 수정 2018-04-29 04:02:23 +09:00
Hide_DandGogs 95a22f228c Merge branch 'devel' of devsam/core into master 2018-04-29 03:17:12 +09:00
Hide_D a242b9a20e 주요 메뉴에 상단 바 추가 2018-04-29 03:08:30 +09:00
Hide_D 19e91b2de0 입구 코드 추가 2018-04-29 02:44:09 +09:00
Hide_DandGogs eac92293fc Merge branch 'devel' of devsam/core into master 2018-04-29 02:01:54 +09:00
Hide_D a1397e41aa 트래픽 버그 수정 2018-04-29 01:58:59 +09:00
Hide_D 13fccb998e 년도 계산 공식 재 수정. 시나리오 시작시 남은 개월 수를 계산. 반동탁연합 시나리오 외교 추가 2018-04-29 01:47:48 +09:00
Hide_D 1e54220230 연, 월 계산 방식 변경 2018-04-29 01:19:31 +09:00
Hide_D 6b2000bb39 올스타전 내특/전특 2018-04-29 00:53:49 +09:00
Hide_D 5f3fbdb089 KBO 올스타전 리뉴얼 2018-04-29 00:45:12 +09:00
Hide_D 63e888c9b1 특성에 '랜덤', '랜덤전특', '랜점내특' 가능. 0으로 지정 가능 2018-04-29 00:28:06 +09:00
Hide_D e97e702c2e 가상 모드 대응. 랜덤 특성 세팅 추가 2018-04-28 23:55:22 +09:00
Hide_D 657c35f876 git tree 지정이 안되는 업데이트 유저는 기존에 업데이트된 값을 이용하도록 변경 2018-04-28 23:36:35 +09:00
Hide_D bc79250f96 Merge branch 'master' of ssh://storage.hided.net:2525/devsam/core into devel 2018-04-28 22:42:01 +09:00
Hide_D dd7846e995 설정 저장용 key_value storage 추가. ROW_FORMAT=DYNAMIC 삭제 2018-04-28 22:01:58 +09:00
Hide_D 8a5483d508 연감 벌점 감소 2018-04-28 21:52:14 +09:00
Hide_D 805053e921 NPC 포상 잘 안주는 문제 우회 시도 2018-04-28 21:04:55 +09:00
Hide_D 170a32a1bd 등용장 메시지 송신이 이상한 문제 해결.
인사부 '공석' 지정 가능
2018-04-28 20:49:38 +09:00
Hide_D 5262d424b4 방랑의 제한 조건 추가 2018-04-28 20:38:19 +09:00
Hide_D 9c3c1045ac 줄간격 문제 해결(inline에 line-height 적용해제) 2018-04-28 20:29:33 +09:00
Hide_D 2d1a3f5da9 많은 버그 수정
커맨드 실행 중 로그아웃 된 경우 버그 수정
국기 변경에 에러 있던 점 수정
등용장 수락시 송신자 명성 안 늘어나는 버그 수정
2018-04-28 20:10:33 +09:00
Hide_D 088260bbc6 npc 재야일때 e_notice 에러 수정 2018-04-28 19:13:18 +09:00
Hide_D 18ebbbc555 oauth_kakao autoload 빼먹은거 수정 2018-04-28 19:10:03 +09:00
Hide_D 80b70a8765 국가 명 너비를 살짝 더 늘림 2018-04-28 18:48:58 +09:00
Hide_D d3d4cce8b5 서버 설명 2018-04-28 18:09:55 +09:00
Hide_D 76bfcd4fa8 베팅 버그 수정 2018-04-28 02:37:47 +09:00
Hide_D 7cbe383a8a 토너먼트 문자열 버그 수정 2018-04-28 02:36:59 +09:00
Hide_D 0488ebf071 무지장 유저장 포상 기준 변경 2018-04-28 02:25:08 +09:00
Hide_D 1cfab53472 문자열 자르기 버그 수정 2018-04-28 01:26:32 +09:00
Hide_D 084c7a2626 선포시 양국 모두 뜨도록 2018-04-28 01:16:00 +09:00
Hide_D 161836a233 상성 가상인 경우 상성이 리셋되지 않는 버그 해결 2018-04-28 01:08:54 +09:00
Hide_D c86ac7d20f 가입 일자 표기, 개인정보 제3자 제공 동의 버튼 추가. 철회 버튼도 추가 2018-04-28 00:23:51 +09:00
Hide_D 20cceec090 IE11에서 javascript 기본 argument 안되는 것 수정 2018-04-28 00:00:46 +09:00
Hide_D 62c6ba362d 개인정보처리방침 & 이용약관 링크 추가 2018-04-27 23:51:57 +09:00
Hide_D 5ed31881e6 PrintElapsedTime 제거 2018-04-27 23:40:50 +09:00
Hide_D 647c51fe0f 외교 서신, 등용장 수락시 올바르지 않을 경우 alert
건국 시 장수 이름과 같아도 건국 가능하도록 변경
2018-04-27 23:08:55 +09:00
Hide_D a2d3ac9e70 시나리오 생성시 장수의 NPC 메시지가 입력되지 않는 버그 해결 2018-04-27 22:51:39 +09:00
Hide_D 20f74f6645 각 페이지에 서버 이름 표기 2018-04-27 22:36:29 +09:00
Hide_D 0bb1ed6f18 서버 리셋 시 서버 이름을 받아오도록 설정 2018-04-27 22:28:16 +09:00
Hide_D 2102a852cb 가상, 사실 거꾸로 표기한 점 수정 2018-04-27 22:21:43 +09:00
Hide_D 0cfb80b7bf 카카오 로그인 버튼을 직관적으로 변경 2018-04-27 22:09:57 +09:00
Hide_D 4297ea9e40 로그인 & 가입 버튼 추가 2018-04-27 21:37:37 +09:00
Hide_D 0ce36e93bd 예약 오픈 테이블은 리셋에도 유지하도록 변경 2018-04-25 21:31:39 +09:00
Hide_D 18bd5f4246 NPC 대사 제대로 안하는 버그 수정 2018-04-25 21:25:04 +09:00
Hide_D 2e7bcd9038 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2018-04-25 21:04:50 +09:00
Hide_D bfef0c28bc 리셋 시 폐쇄를 외부에서 하면 예약 리셋이 안되던 버그 수정 2018-04-25 21:04:41 +09:00
Hide_D b447065651 scenario 30번 수정 2018-04-25 18:12:08 +09:00
Hide_D f540f87e77 KBO 올스타전 시나리오 추가 2018-04-25 18:04:01 +09:00
Hide_D 6ebe3454af 예약 안내 조건 버그 수정 2018-04-25 08:15:55 +09:00
Hide_D 7e00500870 예약 리셋시 초기화 에러 표기 가능하도록 변경 2018-04-25 03:10:09 +09:00
Hide_D bc37dd1df7 '폐쇄 여부'를 server_basic_info에서 판단하도록 설정 2018-04-25 03:07:02 +09:00
Hide_D 77aca09f53 상성 여부로 메시지 변경 2018-04-25 03:02:31 +09:00
Hide_D 23fb1194ee 서버 예약 오픈을 UI에 통합 2018-04-25 02:56:11 +09:00
Hide_D 6253b757ec 기본 예약 리셋 동작 2018-04-25 02:13:40 +09:00
Hide_D 9122342fb9 FIXME: 리셋 헬퍼 꼴보기 싫으니 분리할 것 2018-04-25 00:44:33 +09:00
Hide_D fb42a32089 리셋 코드를 별도 코드로 분리 2018-04-25 00:43:09 +09:00
Hide_D 5c7f4c43ae 리셋 시 토너먼트 개최 여부도 같이 설정 2018-04-25 00:28:26 +09:00
Hide_D 3da256cc29 토너먼트 타이틀 정보 약간 개선 2018-04-25 00:05:08 +09:00
Hide_D 717c576cba n장 끼리 포상 제대로 안하는 버그 수정 2018-04-24 02:16:50 +09:00
Hide_D ddb4011b5d 몰수 조건 강화 2018-04-24 02:12:04 +09:00
Hide_D 48207b9300 포상 조건 재 수정. 무지장이라도 금쌀이 너무 적으면 주긴 함 2018-04-24 01:58:07 +09:00
Hide_D 388afe6fb4 CityHelper에서 getAllNationCities가 올바르게 동작하지 않던 버그 해결 2018-04-24 01:15:05 +09:00
Hide_D 99b459766a 무지장 헌납 로직 추가
포상 로직에서 무지장. 사망 예정장은 제외
2018-04-24 00:53:26 +09:00
Hide_D 230fc5ba53 훼섭은 닫히던 문제 마저 수정 2018-04-23 23:51:47 +09:00
Hide_D 9c266b7b1c 불가침 수락 년도 제대로 안보이는 버그 수정 2018-04-23 23:51:02 +09:00
Hide_D 603599d666 업데이트 후 서버를 닫지 않도록 변경 2018-04-23 23:48:59 +09:00
Hide_D b3cd29ac95 명전 테이블에 unique index가 안걸려있던 버그 수정 2018-04-23 01:21:05 +09:00
Hide_D a4beab86c2 도시 정보 턴 시간값을 +1 2018-04-22 12:24:42 +09:00
Hide_D 3a84e0d064 run_daemon 고도화. 1분에 4번 부름 2018-04-22 02:35:21 +09:00
Hide_D 31f1eb2d28 턴 실행 데몬 2018-04-22 02:18:51 +09:00
Hide_D d73c0c6f0c 남귀병이 기술 1등급 병종이었다니! 2018-04-22 01:32:25 +09:00
Hide_D 36409cf066 game, nation, city, general을 myisam으로 변경 2018-04-21 23:47:02 +09:00
Hide_D 556e1059f9 인사부 버그 수정
메인 페이지에서 재야 인사 에러 안나게 수정
2018-04-21 23:19:29 +09:00
Hide_D 131a6cb6c3 건국 버그 수정 2018-04-21 23:08:51 +09:00
Hide_D 598943eb1b 방랑군 상태에서 세력 도시 클릭 불가. 인사부 가능.
설치시 운영자 삭턴
시나리오 29 재 디자인
지도에서 로그인 유저 검사
2018-04-21 22:43:46 +09:00
Hide_D bf746393b8 천인강림 시나리오 리 밸런싱 2018-04-21 21:52:17 +09:00
Hide_D 70b6997436 연감에서 장수 로그 컬럼 길이 연장 2018-04-21 21:10:03 +09:00
Hide_D b26c6a04c0 삭턴 버그로 생긴 버그 수정 2018-04-21 17:27:45 +09:00
Hide_D 4f262a03e4 command_Single 동작 변경 2018-04-21 16:18:07 +09:00
Hide_D a0ca3dc3f6 TODO 추가 2018-04-21 15:59:05 +09:00
Hide_D f58736277f 삭턴 버그 수정 2018-04-21 15:58:41 +09:00
Hide_D 473cae169e 퀘섭 빙의시 계정이름이 아니라 닉네임으로 기록하도록 변경 2018-04-21 14:14:41 +09:00
Hide_D 4b956385bd 메시지 전송을 위해 일괄 2018-04-21 13:16:50 +09:00
Hide_D 481494a885 전체 메시지 안 보내지던 것 수정
10초마다 메시지
2018-04-21 13:06:10 +09:00
Hide_D 243604d6c1 30초마다 메시지 폴링! 2018-04-21 12:28:32 +09:00
Hide_D dc97c71e0b 1월을 놓치면 태어나지 않으므로 Date 기준을 ==에서 >=로 변경 2018-04-21 12:20:55 +09:00
Hide_D e6b4832b5d index.php에 level 없는 버그 2018-04-21 11:49:55 +09:00
Hide_D 00ac67e8ac 시나리오 시작 년도 수정 2018-04-21 11:11:25 +09:00
Hide_D 953b609b32 임관, 장수 선택시 설명 색 변경 2018-04-21 10:54:07 +09:00
Hide_D a5875be39b 쿼리 인덱스 2018-04-21 10:48:55 +09:00
Hide_D 0f45de8384 부상 코드 2018-04-21 10:47:09 +09:00
Hide_D d119200287 서버 업데이트 순서 틀림 2018-04-21 10:43:21 +09:00
Hide_D b9fa0bea6e mkdir 권한 변경 2018-04-21 10:42:30 +09:00
Hide_D 3a28180700 도시 정보 주석 제거 2018-04-21 10:17:24 +09:00
Hide_D 5b6f456d5c 도시 정보 업데이트 2018-04-21 10:15:04 +09:00
Hide_D fb1ae6ea88 투표율 안보이는 버그 수정 2018-04-21 08:56:54 +09:00
Hide_D 50582a0e8b 내무부에 textarea 적용 2018-04-21 07:57:41 +09:00
Hide_D 8fe3d0258a 건국되지 않았을 때 버튼 처리 변경 2018-04-21 07:57:26 +09:00
Hide_D f2537b20de allButton 예제 2018-04-20 02:19:42 +09:00
Hide_D 31d6850e6e 게시판 리스트 변경 2018-04-20 02:17:38 +09:00
Hide_D 31468d5425 전력전 비율을 50% -> 40%로 내림 2018-04-19 22:55:11 +09:00
Hide_D 688b839315 지도 배경 그림이 올바르지 않은 버그 수정 2018-04-19 22:50:40 +09:00
Hide_D fa4c9046fc Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2018-04-19 20:08:31 +09:00
Hide_D c7560f9113 체섭에서 세션 시간 가져옮 2018-04-19 20:08:05 +09:00
Hide_D f7e3966310 부운영자 계정 권한 지정 2018-04-19 10:35:49 +09:00
Hide_D 7359237da4 항복 권고시 divide 0 나올 수 있는 문제 우회 2018-04-19 02:56:55 +09:00
Hide_D d617203c05 reply 추가 2018-04-19 02:55:35 +09:00
Hide_D 910526ba44 oauth 버그 2018-04-19 02:50:00 +09:00
Hide_D c1842703d7 Session ID 변경 2018-04-19 02:43:10 +09:00
Hide_D 2f9d2e2bc2 추방시 color 필요하던 점 2018-04-19 02:36:11 +09:00
Hide_D 20d7e005a0 도움말 에러 2018-04-19 02:34:44 +09:00
Hide_D 0ce5a88e49 NPC 추방시 warning 2018-04-19 02:34:38 +09:00
Hide_D 4af10fb485 유니크 아이템 warning 2018-04-19 02:34:28 +09:00
Hide_D f872113e99 토너먼트 warning 제거 2018-04-19 01:55:31 +09:00
Hide_D f33fefd188 도시에서 턴이 4개만 보이는 버그 수정 2018-04-19 01:53:02 +09:00
Hide_D 8c2f4f9dc9 Message 마지막 인자가 없엇 ㅓ터지는 버그 수정 2018-04-19 01:51:27 +09:00
Hide_D 3b6e7c5c28 몰수 시 NPC 반항 에러 2018-04-19 01:50:01 +09:00
Hide_D 595c11a9a7 NPC 사령턴이 '미설정'일때 2018-04-19 01:45:35 +09:00
Hide_D 1ab7b57885 숙련 단련 로그 버그 수정 2018-04-19 01:40:20 +09:00
Hide_D 07130e6022 선포 옵션 변경 2018-04-19 01:38:28 +09:00
Hide_D 2cc2f7eb23 NPC 몰수를 더 잘하도록 설정 2018-04-19 01:30:31 +09:00
Hide_D c798ac49b9 선포 메시지 버그 2018-04-19 01:21:28 +09:00
Hide_D a8796edbd3 체크 방식 유형 변경 2018-04-19 01:16:38 +09:00
Hide_D a4ead74cb2 등용장 로그 이상하게 뜨는것 수정 2018-04-19 00:27:35 +09:00
Hide_D 0beb00c5e5 등용장 탈때 삭턴 NULL되는 버그 수정 2018-04-19 00:26:09 +09:00
Hide_D 3d43690303 훈사 80 못 고치는 버그 수정 2018-04-19 00:22:26 +09:00
Hide_D 938c819e9a 베팅장 INF 수정 2018-04-19 00:19:56 +09:00
Hide_D 889ced68ed 베팅장 warning 우회 2018-04-19 00:18:31 +09:00
Hide_D de97384424 베팅창 warning 수정 2018-04-19 00:17:30 +09:00
Hide_D f6ffc20a23 등용장 장수열전 기록 안되는 버그 수정 2018-04-19 00:10:19 +09:00
Hide_D c0ec82051f $cities 변수 없음 수정 2018-04-19 00:04:30 +09:00
Hide_D 91273522c0 오탈자 수정 2018-04-19 00:03:46 +09:00
Hide_D 20a475466d 등용장 '등용장 안 타지는' 버그 수정 2018-04-18 23:54:48 +09:00
Hide_D 10b6a4ff6e 등용장 버그 고침(송신자에게도 감) 2018-04-18 23:48:47 +09:00
Hide_D 2a4e59d6e2 등용장 버그 수정(임관 국가) 2018-04-18 23:44:49 +09:00
Hide_D c016ea7c52 등용장 버그 수정 2018-04-18 23:44:17 +09:00
Hide_D 00bece9c9c 임관금지 거꾸로된것 수정 2018-04-18 23:42:27 +09:00
Hide_D 44ed61c14e touchmode 삭제 다른 방안을 찾아보는걸로 2018-04-18 23:24:33 +09:00
Hide_D 002b7ae534 등용장 버그 수정 2018-04-18 23:20:47 +09:00
Hide_D 63000bdd22 등용장 버그 수정 2018-04-18 23:18:55 +09:00
Hide_D 20fd52b32d 등용장 버그 수정 2018-04-18 23:17:55 +09:00
Hide_D 7a3064d37b 첩보시 병종 메시지 수정 2018-04-18 23:16:05 +09:00
Hide_D 7fea0a41c6 지도 수준을 없앰 2018-04-18 22:57:38 +09:00
Hide_D e701540d7f 외교 서신 (이)가 2018-04-18 22:37:00 +09:00
Hide_D 5187ebbf52 추방 몰수 선포 등 상황에서 메시지 안 나타나는 버그 수정 2018-04-18 22:34:13 +09:00
Hide_D df26c511b5 금쌀 2500단위도 추가 2018-04-18 22:18:39 +09:00
Hide_D 0e650da34a 메시지창 정렬.
몰/포 1200, 1500 추가
2018-04-18 22:16:59 +09:00
Hide_D 2c382da773 부대가 없더라도 부대 가입 버튼이 뜨는 버그 해결 2018-04-18 22:05:58 +09:00
Hide_D e709ee5db8 불필요한 array_get 삭제. 모병 칸 버튼을 징병->모병 2018-04-18 22:03:01 +09:00
Hide_D d550415b65 세션 설정시 오타 수정 2018-04-18 22:00:11 +09:00
Hide_D 9ec144e8f6 사령부 인덱스 버그 2018-04-18 21:58:01 +09:00
Hide_D 9458307612 사령부 표기 수정 2018-04-18 21:55:22 +09:00
Hide_D 915c5fcd8e npc 몰포 버그 수정 2018-04-18 21:51:44 +09:00
Hide_D 0df1293139 체결 메시지에도 년도 뜨도록 수정 2018-04-18 21:46:26 +09:00
Hide_D 9bcd18c42e 모,징병시 특성 병종이 2000 만 넘어도 뜨는 문제 해결 2018-04-18 21:42:09 +09:00
Hide_D 1c853107b7 불가침 제의 서신 수정 2018-04-18 21:38:56 +09:00
Hide_D 3f21e28ef7 유저에게 포상량이 확실히 더 많아짐 2018-04-18 21:24:00 +09:00
Hide_D 61244fcef9 추가한 커밋에서 불필요한 npc 코드 제거 2018-04-18 21:17:39 +09:00
Hide_D 03c930ce7d npc가 유저에게 포상, 몰수하는 기준을 더 후하게 잡음 2018-04-18 21:16:49 +09:00
Hide_D f57c4967f2 NPC 삼/팜 버그 마저 수정 2018-04-18 13:56:36 +09:00
Hide_D 49f40d56b0 회피 잘못 적용되는 버그 수정 2018-04-18 10:13:32 +09:00
Hide_D 190fcabbac NPC 삼팜 버그 2018-04-18 09:43:58 +09:00
Hide_D 8bccf449ad NPC 감찰부에서 장수 행동 2018-04-18 09:38:32 +09:00
Hide_D f7dc1a588b 능력치 받아올 때 general이 NULL인 경우도 대응 2018-04-18 09:24:10 +09:00
Hide_D 0eb91c6301 버튼들 '뒤로 가기' 가능하도록 직접 링크로 변경 2018-04-18 00:08:12 +09:00
Hide_D 0fa4d88ea9 lock 파일 경로 체크 2018-04-18 00:01:40 +09:00
Hide_D 18e355b701 bool 변수 받는 문제 해결. 전콘 안 고를 수 있도록 선택 2018-04-17 23:39:36 +09:00
Hide_D 1cb877503d 불가침 합의 시 년 표기가 이상한 문제 2018-04-17 23:30:48 +09:00
Hide_D b65e691255 벌점 안 쌓이는 버그 수정 2018-04-17 23:17:16 +09:00
Hide_D a4ee43f12b 세력도 아래 안보이는 것 해결 2018-04-17 23:04:37 +09:00
Hide_D f71c61a55b 특수 권한 유저 추가 2018-04-17 22:57:10 +09:00
Hide_D 418130f4cd bool 변환에서 false 조건 하나 더 추가 2018-04-17 22:44:39 +09:00
Hide_D 1566aa0243 국가색 새로 2018-04-17 22:15:11 +09:00
Hide_D ab546f66f0 국가간 갠메 2018-04-17 22:13:36 +09:00
Hide_D fc021dae54 등용장 살림 2018-04-17 22:03:23 +09:00
Hide_D 58a7b3afe1 등용장 잠시 살림 2018-04-17 22:03:08 +09:00
Hide_D 72f41df5d2 사령부 warning 2018-04-17 21:59:48 +09:00
Hide_D 8fd6b91cf7 아이템 습득시 warning 해결 2018-04-17 21:57:03 +09:00
Hide_D cf2ace32d1 로그아웃 버튼 삭제 2018-04-17 21:39:08 +09:00
Hide_D 05c4f721f2 메시지창 모바일에서 안보이는 것 해결 2018-04-17 21:37:59 +09:00
Hide_D b2096cc274 불가침 서신 개월수 안보이는 문제 해결, 개월수 년으로 보이는 문제 해결 2018-04-17 21:35:13 +09:00
Hide_D 067df49914 29번 능력치 변경 2018-04-17 20:59:16 +09:00
Hide_D 6961298e53 이미지 못 불러오는 문제 해결 2018-04-17 20:48:49 +09:00
Hide_D 3e6523002c 이벤트 메시지 변경 2018-04-17 20:43:18 +09:00
Hide_D c26add7b04 29번 시나리오 급조 2018-04-17 20:40:56 +09:00
Hide_D 12d50fec03 장수 등록 시 scenario 값과 show_img_level 값 2018-04-17 20:16:04 +09:00
Hide_D a43bbc9f23 proc.php 2018-04-17 20:09:35 +09:00
Hide_D 2bec3b253c proc readonly 2018-04-17 20:09:11 +09:00
Hide_D a69f256168 약관 추가 2018-04-17 20:08:15 +09:00
Hide_D d7fb88eed6 TimeZone 세팅 2018-04-17 19:23:05 +09:00
Hide_D bfd79f479e 파일 경로를 절대 경로로 변경 2018-04-17 19:21:30 +09:00
Hide_D 7ec3fcc78e 대문자 GAME 수정 2018-04-17 19:11:09 +09:00
Hide_DandGogs 858a09b429 Merge branch 'devel' of devsam/core into master 2018-04-17 04:33:14 +09:00
Hide_D da7fcafb27 사령부 NPC 색상 2018-04-17 03:45:57 +09:00
Hide_D 7f7d8b2099 명장일람 표기 오류 수정 2018-04-17 03:43:22 +09:00
Hide_D b5fb2e9cf4 중원 정보 분쟁 현황을 제대로 보여줌 2018-04-17 03:39:17 +09:00
Hide_D d9ffdf9df8 외교 서신 밀리는 버그 수정 2018-04-17 03:23:02 +09:00
Hide_D f919187b91 불가침 메시지 수정 2018-04-17 03:22:53 +09:00
Hide_D d5ead5b74f 재야일때 secretlimit 경고 뜨는거 해결 2018-04-17 03:11:00 +09:00
Hide_D ec1be2c887 합병 항복 안되는 버그 수정 2018-04-17 03:10:38 +09:00
Hide_D af0c470923 부대 가입 안되는 버그 수정 2018-04-17 03:10:25 +09:00
Hide_D 78ce7d20e3 거래장 에러로그 수정 2018-04-17 03:10:18 +09:00
Hide_D 932ce9bf51 도시 정보 배경 안보이는 ㅓㄱ수정 2018-04-17 03:06:55 +09:00
Hide_D 3d602b49bf 메시지 표기 프레임 변경 2018-04-17 02:14:58 +09:00
Hide_D 33b7d228f9 긴급 천도 버그 수정 2018-04-17 02:14:48 +09:00
Hide_D 95a8fd5495 토너먼트 표기 2018-04-17 02:14:38 +09:00
Hide_D 87bc416fc7 인사부 표기 버그 수정 2018-04-17 02:14:31 +09:00
Hide_D 8c21eec168 메시지 관련 버그 우회 2018-04-17 01:55:12 +09:00
Hide_D 7ef3f0d5c5 임시로 외교 서신 받는 기능 추가 2018-04-17 01:54:57 +09:00
Hide_D e90e508005 빙의 후 페이지 이동 2018-04-17 01:54:42 +09:00
Hide_D 816daed570 warning 방지 2018-04-17 01:54:03 +09:00
Hide_D 3626266763 시작 년도가 없는 경우 설정 2018-04-17 01:53:55 +09:00
Hide_D 6c117a628c 가운데에 버튼 세트 추가 2018-04-17 01:53:45 +09:00
Hide_D d3225dfb41 버그 수정 2018-04-17 01:53:32 +09:00
Hide_D bd7e7540d8 사령부 출력 오동작 수정 2018-04-17 01:53:23 +09:00
Hide_D 48088748df schema 버그 수정. DB에서 Exception 제대로 안 던지는 버그 해결 2018-04-17 00:18:38 +09:00
Hide_D 7a5eecc3e1 갠메를 보냈을 때 알림 표시 2018-04-17 00:03:40 +09:00
Hide_D 51d7dede55 nation table에서 외교 서신 보관용 column 삭제 2018-04-16 23:58:36 +09:00
Hide_D bcad77ec06 사령턴 외교 서신 재구현 2018-04-16 23:53:54 +09:00
Hide_D 9b79d12521 재야에서는 국메가 안보내지던 버그 수정
일반장이 국메를 보낼 수 없던 버그 수정
외교 서신 클래스 에러 수정
2018-04-16 23:29:17 +09:00
Hide_D 4b33461c70 _admin2의 query를 수정.
- 메시지 전송을 새로 만든 구현을 사용함.
- 테이블 두개 (MEMBER, SYSTEM)을 소문자로 변경
2018-04-16 22:31:54 +09:00
Hide_D bc3a8fefd8 최근 메시지만 전송 받도록 수정. 2018-04-16 08:18:40 +09:00
Hide_D db97400b43 기본 갠메, 국메, 전메 동작 2018-04-16 02:20:05 +09:00
Hide_D 3ad4032239 메시지 입력 버그 수정 중 2018-04-16 02:06:05 +09:00
Hide_D 1d0fb7151d lib.php의 글로벌 변수를 GameConst로 이동
- 계략의 게임 내 영단어를 trick에서 sabotage로 변경
2018-04-16 02:05:46 +09:00
Hide_D 0c9099c868 메시지 첫 동작 2018-04-16 01:09:43 +09:00
Hide_D c87cbaa0a6 등용장 생성시 버그 수정 2018-04-16 00:03:48 +09:00
Hide_D 5a94bf434a css style에서 단위(px)가 설정되지 않은 것들 수정 2018-04-15 23:57:22 +09:00
Hide_D d567f3218a 재야를 따로 다루던 코드 제거 2018-04-15 23:51:46 +09:00
Hide_D 5d97c4ebea mailbox 리스트에서 '재야'를 내부 코드로 처리 2018-04-15 23:48:39 +09:00
Hide_D c3be464774 메시지 시스템 외부로 연결중. 2018-04-15 23:42:59 +09:00
Hide_D 0d1e10a2ce 소소한 수정 switch 무서워라.. 2018-04-15 23:42:47 +09:00
Hide_D 723a7bbfba 장수 생성 시 오류 나던 문제 해결
- Validation 문제
2018-04-15 23:42:30 +09:00
Hide_D 6a100ed2c1 국가 정보 반환시 0인 경우에 한해 재야도 반환.
- 재야의 색을 #000000 으로 설정
2018-04-15 23:41:36 +09:00
Hide_D 5a6cd7fb46 서버에서 아이콘 주소를 바로 돌려주는 기능 추가 2018-04-15 23:39:41 +09:00
Hide_D 871c99a67a 외교 서신 메시지 파트 구현 완료
- 메시지 전송시 수신자에게만 전송 가능한 옵션 추가
- 메시지 추가 옵션으로 delete 옵션 제시.
2018-04-15 21:40:21 +09:00
Hide_D 7bdde2ac8a 외교 서신 상세 내용 추가
- 등용장의 로그 부분은 메시지로 뺌
2018-04-15 21:01:42 +09:00
Hide_D 3564282acb 라이선스 추가 2018-04-15 16:35:38 +09:00
Hide_D 13e24dbcb4 이미지 다운로드도 추가 2018-04-15 16:22:57 +09:00
Hide_D 0026e9cb15 이미지 다운로드도 추가 2018-04-15 16:22:45 +09:00
Hide_D 156795d7e9 readme 추가 2018-04-15 16:17:32 +09:00
Hide_D e41d73b5bd Diplomacy 생성자에서 두 국가르 받도록 변경
인접국 판단 로직을 두경우로 나눔
Diplomacy 클래스 구현중...
2018-04-15 04:07:59 +09:00
Hide_D 655cd1700c DiplomaticMessage 작성중
ScoutMessage 버그 개선
2018-04-15 02:41:00 +09:00
Hide_D 9fb455d38a 등용장 거절시 함수명 버그 수정 2018-04-14 23:46:02 +09:00
Hide_D 879a1e1c61 등용장 내부 로직 처리를 분리 2018-04-14 23:10:46 +09:00
Hide_D e614092690 MessageTarget의 부모 클래스 Target 추가 2018-04-14 22:12:40 +09:00
Hide_D 4ebe51d978 \DateTime 오타 수정 2018-04-14 15:44:47 +09:00
Hide_D 10a29e584f 상수 경고 추가 2018-04-14 15:40:08 +09:00
Hide_D a88982940b 등용장 구현을 위한 ScoutMessage 클래스 완성 2018-04-14 15:37:52 +09:00
Hide_D b92a95cc07 이미지 빠진부분 마저 반영 2018-04-14 03:51:43 +09:00
Hide_D bffca5e163 새 병종 이미지 적용
- 64px 이미지 태그들을 width="64px"가 아니라 width="64"로 변경
2018-04-14 03:27:36 +09:00
Hide_D b56919a343 팝업 차단에 막히는 문제 해결... 2018-04-14 02:52:03 +09:00
Hide_D b797bab7e0 누락된 getReq 추가. 버그 수정 2018-04-14 02:42:58 +09:00
Hide_D a03d2cee63 lib.php에서 강제로 $_POST 추출을 시행하던 부분을 세부 파일로 이동. 2018-04-14 00:28:24 +09:00
Hide_D 67fef4b73d 전콘 적용 버그 수정
갱신정보 제대로 안보이는 문제 수정
분쟁 정보 제대로 안보이는 문제 수정
2018-04-14 00:15:54 +09:00
Hide_D 253a953dfe SQL Injection 대응을 위해 파일 상단에 Util::getReq 사용 2018-04-14 00:15:25 +09:00
Hide_D be7154284e 등용장 수락 코드 작성중 2018-04-13 15:48:47 +09:00
Hide_D 02f90842fe TM 서버 밸런스 패치 이식 2018-04-13 03:41:39 +09:00
Hide_D 0b17a289c8 내정 수치를 tm과 일치 2018-04-13 02:42:10 +09:00
Hide_DandGogs c2298efaf0 Merge branch 'devel' of devsam/core into master 2018-04-13 02:27:07 +09:00
Hide_D e858ad0c33 깜빡한 문구 수정 2018-04-13 02:17:22 +09:00
Hide_D fb1acfa09c 명전 초기값이 없어서 등록할 수 없는 버그 수정 2018-04-13 02:16:15 +09:00
Hide_D 033466edcc 공백지 점령용 예비 코드에 '수도'가 지정되지 않은 문제 해결
천통 가능
2018-04-13 01:52:27 +09:00
Hide_D 3a472506cf 버그 수정... 2018-04-13 01:35:47 +09:00
Hide_D cea015bd4d 전특, 내특 검색을 위한 별도 클래스 제작 2018-04-13 01:01:32 +09:00
Hide_D 8aaf161fd0 세력도 안보이는 문제 해결 2018-04-13 00:54:02 +09:00
Hide_D 1529ab6469 분리한 긴천 함수 호출 버그 2018-04-13 00:38:37 +09:00
Hide_D 1a3b456f39 긴천 함수 분리.
멸망시 등용장이 동작하지 않으므로 일단 끔
2018-04-13 00:26:21 +09:00
Hide_D ac3672a87e 긴천 위치가 엉뚱하게 되는 버그 수정.
getGenSpecial을 마구잡이로 부르는 함수로 인하여 우회
2018-04-13 00:06:32 +09:00
Hide_D a866cb63a4 getConquerNation 버그 수정 2018-04-12 21:32:04 +09:00
Hide_D 943251c56f 에러 코드 출력 방식 변경 2018-04-12 21:31:45 +09:00
Hide_D 4d2b10b979 에러 표기 방식 변경.
- DB 에러도 throw exception을 수행
- exception handler 추가.
- error 발생시 콜 스택을 json 형태로 보관
2018-04-12 21:24:28 +09:00
Hide_D c87614ab2d 연감 지도가 json 기반으로 바뀌었으므로 j 붙임 2018-04-12 20:53:19 +09:00
Hide_D 67dee551b6 분쟁현황 표기 버그 일부 추가 수정 2018-04-12 05:22:20 +09:00
Hide_D 2ee20ce92c 분쟁 코드를 json기반으로 변경 2018-04-12 05:17:32 +09:00
Hide_D cd8ec0687f 성벽 공격시 '국가'를 구해오는 과정에서 공백지를 고려하지 않은 부분 수정 2018-04-12 04:16:02 +09:00
Hide_D 6881b531d7 post type 빠진 것 추가 2018-04-12 04:00:29 +09:00
Hide_D 2eae9b2062 긴천 시 도시 참조하는 부분에 Undefined offset 문제 발생하는 것 해결 2018-04-12 03:34:09 +09:00
Hide_D b055baa7d3 출병시 인접 도시 체크 룰을 DB가 아니라 CityConst에 기반하도록 변경 2018-04-12 03:26:32 +09:00
Hide_D fc0ad32335 사령부 출력 에러 우회. 2018-04-12 03:08:36 +09:00
Hide_D 42cd2fafdd Json에 PASS_THROUGH 옵션 추가 2018-04-12 02:59:44 +09:00
Hide_D 6220d030dc $_POST, $_GET 남은 부분 제거. 연감 지도 받아오는 부분 재 작성 2018-04-12 02:57:53 +09:00
Hide_D 8961dd60a2 $_POST btn 빼먹은거 추가 2018-04-12 02:47:28 +09:00
Hide_D 2726bc13c4 b_myGenInfo 관직 제대로 표기 안된 문제 해결 2018-04-12 02:42:40 +09:00
Hide_D 967c14a972 $sel 변수를 이용한 잘못된 selected 출력 문제를 우회 2018-04-12 02:37:05 +09:00
Hide_D 74d86b7897 POST에 type, btn, gen 빠진것 보정 2018-04-12 02:31:30 +09:00
Hide_D 5a176568e9 b_tournament 진행중에 그래프 그리는 문제 해결 2018-04-12 02:21:11 +09:00
Hide_D 279478c15b 등용장 발부시 국가명 빼먹은 것 수정 2018-04-12 02:18:35 +09:00
Hide_D f5f7c81c20 헌납에서 방랑군일때는 헌납이 가능하게 했던 흔적 수정 2018-04-12 02:11:55 +09:00
Hide_D 3c2499580c checkStatistic() 함수 index 빈 것 해결 2018-04-12 02:08:54 +09:00
Hide_D 45a104f9c0 padString에 문자열 너비가 원하는 길이보다 길때 버그 수정
명장 일람 데이터가 비었을 때 발생하는 버그 수정.
2018-04-12 01:48:16 +09:00
Hide_D a5b0c7f99f 배신한 장수는 유니크를 못먹게 하려는 코드의 흔적을 제거(동작하지 않았음) 2018-04-12 01:40:22 +09:00
Hide_D 643a2822a0 퇴각시 $oppose를 해제하여 마지막 페이즈 쌀 소모하는 문제 해결. 2018-04-12 01:27:29 +09:00
Hide_D be8e22309f _traffic.txt 제대로 작성 못하는 버그 수정.
쌀 소모량 못 받아오는 버그 수정.
getAtt, getDef에서 $game이 더이상 필요없으므로 삭제
2018-04-12 01:16:37 +09:00
Hide_D 8273c3f231 optionsForCities array_map 빼먹은거 수정 2018-04-11 20:57:12 +09:00
Hide_D e9ceb0bdd6 Citys 함수명 변경 2018-04-11 20:49:26 +09:00
Hide_D c204f36aa7 강행 실해하던 것 해결 2018-04-11 20:19:42 +09:00
Hide_D 869ee4b233 레벨이 300이 되면 전투엔진이 터지는 문제 수정 2018-04-11 19:54:25 +09:00
Hide_D f0c6243964 연감 장수 동향 안뜨는 문제도 해결 2018-04-11 03:16:50 +09:00
Hide_D b46a197a5c 연감 지도 엔진 변경 2018-04-11 03:09:49 +09:00
Hide_D d39c04da76 '유기체' 삭제 관리자 명(Hide_D)와 서버명 HiDCHe 로 변경. 2018-04-11 02:20:23 +09:00
Hide_D 22f1f3c227 페이지 리다이렉트 방식 변경
<script>location.replace</script>에서 PHP redirect header를 직접 이용하는 방식으로.
2018-04-11 02:14:03 +09:00
Hide_D 2b3efd0924 전투 수식에 TM서버 내용 반영 2018-04-11 01:50:29 +09:00
Hide_D 3004b20c87 버그 패치
- 메인 페이지에서 턴 실행으로 세션락이 걸리지 않도록.
- 토너먼트에서 매 라운드마다 텍스트가 초기화 되지 않던 문제 해결
- 전투 로그 표기에서  불필요한 빈칸 제거
2018-04-11 01:08:12 +09:00
Hide_D 5c8194b36d 로그 출력 거꾸로 된 것 보정 2018-04-10 22:44:12 +09:00
Hide_D e487846c56 전투 로그 바꾼것 제대로 안나오는 것을 수정 2018-04-10 22:44:00 +09:00
Hide_D 0437d45997 벌점 기준을 현실화 2018-04-10 22:43:45 +09:00
Hide_D 8dd5154de3 searchDistance에서 거리 계산 종료 조건 버그 수정 2018-04-10 21:32:27 +09:00
Hide_D bc519284fb 도시 병종 체크 버그 수정 2018-04-10 21:28:10 +09:00
Hide_D 19e06cc12e 메인 페이지 새 버튼 추가 준비 2018-04-10 21:21:58 +09:00
Hide_D 16e5601651 checkLimit 함수에 입력값이 없어도 자동으로 수행하도록 변경 2018-04-10 21:20:57 +09:00
Hide_D 8f9077dff8 명장 일람 아이템 표기 버그 수정, 사령부 턴 정상 리다이렉트, 개인 기록 역순 표기 문제 해결 2018-04-10 21:20:35 +09:00
Hide_D 9831685bb9 병종 가격 계산 버그, 접경 계산 버그, 긴급 천도 버그 수정 2018-04-10 21:11:56 +09:00
Hide_D 1412834b60 턴 갱신, 당기기, 밀기 코드 재 작성 2018-04-10 21:11:12 +09:00
Hide_D b8636763c1 Message::send 반환값 정리 2018-04-10 02:53:35 +09:00
Hide_D fe4823bb8d sendToSender() 반환값 2018-04-10 02:52:18 +09:00
Hide_D 7ef9a2fdca msg send 반환 방식 변경 2018-04-10 02:51:13 +09:00
Hide_D 9f627ca2f8 함수 이름 변경 2018-04-10 02:46:01 +09:00
Hide_D 2404ab2047 메시지 클래스 새로 작성 2018-04-10 02:38:36 +09:00
Hide_D 50d1c4cd34 dateFormat에 포맷 추가. error 페이지 표기 수정 2018-04-09 03:21:11 +09:00
Hide_D 269a40ca9d stylesheet 잘못 불러오는 문제 해결.
jquery.redirect 추가.
global 변수 extract 우회가 제대로 동작하지 않던 문제 해결
2018-04-09 02:56:45 +09:00
Hide_D 2a814dbbf9 하드리셋 시 UniqueConst가 없어져 세션에서 generalID, generalName을 확인할 수 없는 문제 수정 2018-04-09 01:56:12 +09:00
Hide_D 59243bc34d FIXME를 달아두었던 RootDB::getServerBasepath 삭제! 2018-04-09 01:37:08 +09:00
Hide_D da89d81ef9 정적 분석 결과 반영 2018-04-09 01:29:29 +09:00
Hide_D 27d313c594 정적 분석기 결과 반영 2018-04-08 23:39:02 +09:00
Hide_D eeaae898ae 정적 분석 결과 반영. 2018-04-08 23:18:24 +09:00
Hide_D 9673ecfaa1 정적 분석 결과 반영. MYDB_close 삭제 2018-04-08 22:04:16 +09:00
Hide_D 4e22cf3515 round(something, 0); 을 Util::round(somehing); 으로 변경. 2018-04-08 21:52:14 +09:00
Hide_D 5b926ae5c5 정적 분석기 결과 반영. 빠진 POST 인자 입력 등 2018-04-08 20:51:40 +09:00
Hide_D b78fe22633 정적 분석 결과 반영. 베팅 코드는 새로 작성 2018-04-08 20:18:18 +09:00
Hide_D ba4ff29e4a floor를 intdiv로 변경 2018-04-08 19:46:26 +09:00
Hide_D f060716a3c phpuri 추가. root, shredIcon, gameIage 경로 계산 코드를 추가 2018-04-08 18:38:01 +09:00
Hide_D 9108ce3f19 js, html에서 참조하는 이미지 경로 수정 2018-04-08 17:59:39 +09:00
Hide_D e36a50889b 지도 데이터 이동. 기본 이미지 경로 수정 2018-04-08 17:24:11 +09:00
Hide_D ee2bcb5329 d_shared/common.css를 참조하도록 추가 2018-04-08 17:17:49 +09:00
Hide_D bc7efae08c 아이콘, 게임 이미지 경로를 일괄 지정 가능하도록 변경 2018-04-08 16:56:26 +09:00
Hide_D fe53fb9359 (기분상의 이유로) <?=$value;?>를 <?=$value?> 로 수정 2018-04-08 13:14:28 +09:00
Hide_D 463994df42 정적 분석 결과 반영. global 변수 몇몇 삭제 2018-04-08 12:56:56 +09:00
Hide_D 48a560cb4c 접속 가중치 개념 삭제. 2018-04-08 12:38:46 +09:00
Hide_D 493b3c7d97 normgeneral 삭제 2018-04-08 12:31:42 +09:00
Hide_D 7875e6885f 혹시 모를 foreach reference 제거 2018-04-08 11:59:42 +09:00
Hide_D f36df49ed8 Validator rul 함수 수정 2018-04-07 20:31:03 +09:00
Hide_D 1c1fb247b1 phpinfo.php 삭제. gitignore 추가 2018-04-07 20:06:24 +09:00
Hide_D cff76c9db9 array_merge 대신 + 기호로 충분한 경우(dictionary) +로 변경함. 2018-04-07 18:30:23 +09:00
Hide_D 3d06a13e72 & 연산기호 점검 겸. & -? &amp; 변경 2018-04-07 17:46:59 +09:00
Hide_D 85e6faf92c cutStringForWidth, subStringForWidth 재 구현 2018-04-07 16:57:21 +09:00
Hide_D f5494a69a2 불필요한 StringUtil 함수 제거 2018-04-07 16:28:16 +09:00
Hide_D 7afa36a2b8 StringUtil에 splitString, padString 추가 2018-04-07 16:27:58 +09:00
Hide_D 0cc7ba368a Util::array_get($_POST 류를 Util::getReq로 통합.
array_merge를 이상하게 처리하는 부분 수정
2018-04-07 15:16:46 +09:00
Hide_D 183efd073b getReq에 ifNull param 추가 2018-04-07 14:31:26 +09:00
Hide_D d6e2a84a36 Util::getReq phpdoc 수정 2018-04-07 14:25:10 +09:00
Hide_D 3e069d14f2 Util::getReq 함수 추가. 정적 분석 버그를 우회하기 위한 Validator::rule 함수 추가. 2018-04-07 14:24:20 +09:00
Hide_D 6140da5783 정적 분석 결과 반영. 익명 함수로 전환. POST 변수명. 2018-04-07 13:45:17 +09:00
Hide_D 28aa4c004b 정적 분석을 쉽게 하기 위해 일부분 손댐 2018-04-07 13:44:41 +09:00
Hide_D 61857ce56d phan 다시 등록 2018-04-07 12:45:09 +09:00
Hide_D 15d1c2829a PHAN 설정. sizeof 대신 count 사용 2018-04-07 00:07:18 +09:00
Hide_D a5bb9ba062 install.php 정적 분석 수정 2018-04-06 23:39:59 +09:00
Hide_D cfb2a2dbd5 정적 분석 결과 반영 2018-04-06 23:18:42 +09:00
Hide_D 0639fc3b83 정적 분석기 결과 반영 2018-04-06 22:10:05 +09:00
Hide_D d0e7358f68 정적 분석 결과 수정. 배열 선언 문제. 2018-04-06 20:32:57 +09:00
Hide_D ffc0fc0c6f 정적 분석기 결과 반영. 주로 배열 초기화. 변수 이름 실수 수정. 2018-04-06 20:06:28 +09:00
Hide_D 2bce82c73e PSR에 맞게 수정 2018-04-06 19:03:35 +09:00
Hide_D 37339b91b0 phan func 모두 추가 2018-04-06 18:34:31 +09:00
Hide_D 95c8d7ec0f index.php 정적 분석 2018-04-06 18:16:09 +09:00
Hide_D a1a34c30b3 phan 수정 2018-04-06 18:15:41 +09:00
Hide_D 5189a50b9d phan 정적분석기 준비 2018-04-06 18:07:34 +09:00
Hide_D 2d477d630c $session->userID 보다는 버그 확률이 낮은 Session::getUserID로 전환.
- 함수에서 $session->userID는 $session = Session::getInstance() 가 필요
2018-04-06 17:30:26 +09:00
Hide_D ceccb43f82 Session::Instance()를 명명법에 맞게 Session::getInstance() 로 변경 2018-04-06 16:47:24 +09:00
Hide_D 18101d9e90 myNation이 지정되었을 때 첩보 도시가 없을 때 도시가 뜨지 않는 문제 해결 2018-04-06 03:32:20 +09:00
Hide_D 56e6692817 지도에 필요한 데이터를 얻어오는 과정의 버그 수정 2018-04-06 03:30:44 +09:00
Hide_D 11a9985543 커맨드 버튼 재 구성.
$session 접근하는 변수에 Instance 지정
2018-04-06 03:27:17 +09:00
Hide_D 35e8fa952a Session의 login시 실패하는 위치값이 잘못된 것을 수전
Session의 requireGameLogin 조건 완화
index.php에서 로그인이 실패하더라도 턴 수행은 가능하도록 변경
2018-04-06 02:24:23 +09:00
Hide_D 0e82005a26 LogText 수정 2018-04-06 02:10:57 +09:00
Hide_D 1024f1c4dd 혹시 모를 utf-8 외의 환경 방지 2018-04-06 02:05:16 +09:00
Hide_D 7a6472d49d 의심 가는 취약점 구역 차단 2018-04-06 01:47:39 +09:00
Hide_D a0a2e2097c StringUtil 소소한 변경, Json 클래스에서 버려진 함수 제거 2018-04-06 01:04:03 +09:00
Hide_D 76543892bc Session 클래스 재정리 2018-04-05 03:14:50 +09:00
Hide_D 9c445e02b9 $connect를 $db=DB::db();$connect=$db->get(); 으로 변경하고 함수의 $connect를 모두 제거 2018-04-05 02:55:14 +09:00
Hide_D aebae6f485 argument extract 부분 일부 수정. (디버깅용 ㅜㅜ) 2018-04-05 02:28:37 +09:00
Hide_D 0c0ef213f9 dbConn 삭제. 2018-04-05 02:24:46 +09:00
Hide_D 51316abd42 $_SESSION 으로 직접 접근하는 코드들을 모두 Session 클래스로 통합 2018-04-05 02:04:43 +09:00
Hide_D b3e621fbfd increaseRefresh 수정
파일마다 Session 받아오는 코드가 잘못 된 경우 수정
2018-04-05 01:34:56 +09:00
Hide_D fae86dbff8 CheckLoginWithGeneralID()
를 직접 Session 클래스를 접근하는 방식으로 변경.
2018-04-05 00:55:22 +09:00
Hide_D 65171b4413 npc 선택에 validator 추가 2018-04-05 00:46:17 +09:00
Hide_D 90a81c91c4 장수 등록 / 빙의 코드 수정 (Validator, query), TM서버 추가 능력치 코드 이전
random 코드 버그 수정
일부 코드의 Session 참조 방식을 새롭게 추가한 방식으로 변경
2018-04-05 00:34:40 +09:00
Hide_D 3161ace557 Session::requireGameLogin 버그 수정 2018-04-04 03:13:35 +09:00
Hide_D d8b87f1e70 Session::requireGameLogin 버그 수정 2018-04-04 03:12:58 +09:00
Hide_D b507d3c844 index.php에서 checkTurn 위치 조정 2018-04-04 03:06:23 +09:00
Hide_D 36dd7fef19 Session::requireGameLogin() 추가. 앞으로 다양히 활용 가능.
getGeneralID(), getGeneralName(), isSigned() 제거
2018-04-04 03:02:35 +09:00
Hide_D 0405bf9fab d_setting을 classMap으로 보냈으므로 PSR4에서 제거 2018-04-04 02:53:04 +09:00
Hide_D fcbd801dc7 게임 코드에도 Composer의 ClassLoader를 이용하는 코드로 변경
입구 코드에서 WebUtil::setHeaderNoCache(); 수동 지정
에러 페이지 변경
2018-04-04 02:51:14 +09:00
Hide_D e1c97b1ca0 composer.phar 추가 2018-04-03 21:28:40 +09:00
Hide_D 6a62f5af0d toInt를 더 튼튼하게 개선. ROOT가 지정되었으므로 강제 지정하는 코드 해제 2018-04-03 21:22:52 +09:00
Hide_D 0c64087c0f _common.php 대신 composer로 대체 2018-04-03 21:15:12 +09:00
Hide_D e0cbf34d43 CheckLogin을 다시 구현.
- ajax 함수에서는 사용해선 안됨.
- 이외에선 index에서만 제대로 장수삭제처리를 하므로 문제 없을 것.
2018-04-03 03:05:26 +09:00
Hide_D cb56620728 부대 창 DB 함수를 변경 2018-04-03 02:59:08 +09:00
Hide_D 63f14f0009 '이동' 명령 바꿔봄 2018-04-03 02:44:51 +09:00
Hide_D 789714ee44 isClose함수 재설계 2018-04-03 02:19:03 +09:00
Hide_D c2d7e44400 기본 배경 : 검정, 기본 폰트색 : 흰색 설정.
isClose 함수 참조 문제 해결
2018-04-02 02:42:38 +09:00
Hide_D 3c49925999 NPC 사망시 사망 년도를 <에서 <= 로 수정 2018-04-02 02:32:53 +09:00
Hide_D 3e3f156359 history가 없는데 참조해서 발생하는 버그 수정 2018-04-02 02:31:17 +09:00
Hide_D 427532f0a5 supply에서 reference로 참조해야하는 것을 value로 참조한 문제 해결 2018-04-02 02:05:50 +09:00
Hide_D 6e876d3b9c 기존 Queue를 SplQueue로 대체하였으므로 삭제 2018-04-02 01:51:49 +09:00
Hide_D 86ecf37da6 거리 측정 함수 새로 작성
- 이용하는 함수도 수정
2018-04-02 01:50:51 +09:00
Hide_D c0e2ed7013 * generalID, generalName 동작 안하는 문제 해결
* Event 관련 클래스 표기 실수 해결
2018-04-02 01:50:21 +09:00
Hide_D 0cac139f65 Namespace 실수 해결.
수동 Event 등록시 Date가 아니라 date로 입력했던 문제 해결
2018-04-01 23:44:52 +09:00
Hide_D a70bf667a4 history 타입들을 text에서 mediumtext로 변경
시나리오 생성 시 장수수 처리 수정
2018-04-01 23:31:37 +09:00
Hide_D e1f646daa5 install시 자동 폐쇄 추가. 2018-04-01 22:59:22 +09:00
Hide_D 117643f592 방랑군이라 도시가 0일때 발생하는 문제 해결 2018-04-01 22:48:22 +09:00
Hide_D 4fab99b946 - history, log 관련 함수들을 일괄 변경
- 접속 장소(conmsg) 장소 제거
2018-04-01 22:43:14 +09:00
Hide_D 97c6904918 Setting에 closerServer, openServer를 통합. 서버 업데이트시 자동 폐쇄 상태로 2018-04-01 20:31:20 +09:00
Hide_D 4f113f210e 루트 서버 업데이트도 서버명 반환 2018-04-01 20:13:47 +09:00
Hide_D 77ff1d9e9a 업데이트 서버 코드 추가
- VersionGit 양식 변경
- 서버 입구 버전 표기
- FileTail 추가
Vscode에서 che, kwe, pwe, twe 무시
2018-04-01 20:12:22 +09:00
Hide_D 6ee8066c80 PublicRecord 함수 수정, json_encode, json_deocde를 Json로 통합 2018-04-01 19:16:00 +09:00
Hide_D 1f5f7e3591 GeneralPublicRecord 추가 2018-04-01 18:51:26 +09:00
Hide_D 5860a14dae php-tail 추가 2018-04-01 18:44:45 +09:00
Hide_D 74390602d8 pushHistory를 DB기반으로 변경 2018-04-01 05:18:17 +09:00
Hide_D d062fac671 지도 뻗는 문제 해결. commandlist 일부 문제 해결 2018-04-01 04:36:22 +09:00
Hide_D 6edabd5bcb generalID 부분 많이 수정.
index.php 로딩 에러 수정
2018-04-01 04:31:56 +09:00
Hide_D 762e7f72c3 버전 코드 통합 2018-04-01 04:12:03 +09:00
Hide_D 3eb0f22439 서버 버전 추가 2018-04-01 03:55:28 +09:00
Hide_D dbc877023b updateServer에 '마지막 서버'인 경우에는 git pull을 하도록 설정 2018-04-01 03:31:03 +09:00
Hide_D 543fc15553 updateServer 삭제 2018-04-01 03:22:05 +09:00
Hide_D 1804b72638 git fetch && archive로 동작 변경. 2018-04-01 03:21:51 +09:00
Hide_D 9c19e4e92b validator에 errorStr 함수로 묶어서 보여주는 기능 추가 2018-04-01 02:59:54 +09:00
Hide_D b732b9bf40 gitignore에 세부 서버를 ignore 2018-04-01 01:36:40 +09:00
Hide_D 25ec9a2579 파일 위치를 twe에서 hwe로 옮김. 2018-04-01 01:23:44 +09:00
Hide_D 1ddd26c8a1 NPC 생성시 버그 수정
서버 리셋되었을 때 세션 값 안정을 위해 serverID 개념을 추가.
2018-04-01 01:20:35 +09:00
Hide_D 0f97ae8da9 DB 로그인을 utf8이 아니라 utf8mb4로 변경 2018-04-01 00:35:35 +09:00
Hide_D 3ea95da4a6 세션 시작 방식을 Session 클래스를 이용하도록 변경 2018-04-01 00:28:55 +09:00
Hide_D 0b584c7b0d game의 row를 1개로 강제 2018-03-31 23:45:00 +09:00
Hide_D 3875a345c9 game table을 대상으로 하는 update, select에서 no=1 과 관련된 부분을 limit 1 로 변경 2018-03-31 23:21:46 +09:00
Hide_D f78bdc6c6c requireLogin의 동작 방식을 변경, path에 null이 지정되면 json 반환 2018-03-31 22:42:50 +09:00
Hide_D 117f820eaa 서버 리셋에서 디렉토리 초기화 추가
- 서버 선택 창 일부 변경
2018-03-31 20:17:28 +09:00
Hide_D 87c6130d17 Scenario 초기화 버그 수정
리셋 시 로그 초기화
2018-03-31 19:42:16 +09:00
Hide_D 8713bac296 조기 namespace\class 도입으로 new_lib.php 삭제 2018-03-31 19:17:36 +09:00
Hide_D c649e50f42 install_db.php로 대체된 reset.php 삭제 2018-03-31 19:15:40 +09:00
Hide_D 61af601075 테스트용으로 추가했던 코드를 삭제하고, gitignore에 추가 2018-03-31 18:52:42 +09:00
Hide_D 29a21c41ab getTypename 삭제. GameUnitDetail::byID(), ::all()로 대체가능 2018-03-31 18:52:12 +09:00
Hide_D 8dc7f3bad5 scenario 이름은 build시에 db에 넣을 수 있으므로, getScenario() 삭제 2018-03-31 18:33:53 +09:00
Hide_D d09c71c729 CityConst에서 참고 가능한 자료들은 CityConst를 이용하도록 수정
Scenario에서 __construct에서 꼭 다 할 필요는 없는 코드들을 뒤로 미룸.
2018-03-31 18:25:56 +09:00
Hide_D 6fe744f2c1 meekroDB 버그로 우회 2018-03-31 18:01:14 +09:00
Hide_D 6a4c8e236a multi_query warning 나는 문제 해결 2018-03-31 17:18:35 +09:00
Hide_D 17a889ae13 SetNationFront 버그 수정 2018-03-31 16:18:28 +09:00
Hide_D 31d9bac59c Scenario 세팅 과정에 문제 해결
SetNationFront 함수도 수정
2018-03-31 16:06:24 +09:00
Hide_D 71f5311b1d var_dump가 남아있던 버그 수정 2018-03-31 14:32:23 +09:00
Hide_D 8a1ba431e5 cutTurn, cutDay 오동작하는 문제 해결 2018-03-31 14:31:50 +09:00
Hide_D f19707989b 공백지 생성은 가능. 추가 버그 확인 중 2018-03-31 14:13:19 +09:00
Hide_D 8abe3bf638 불필요한 func_install.php 제거 2018-03-31 13:53:21 +09:00
Hide_D 4550754208 db 스키마 기본 문자셋을 utfmb4로 수정
install 시 운영자 셍성
2018-03-31 13:49:53 +09:00
Hide_D 81a439439b cutDay가 변경된 월을 반환하도록 수정
설치 도구를 구현.
2018-03-31 05:44:16 +09:00
Hide_D d9e5d5b2cd 전투 공식을 새로 ㅈ가성한 GameUnitConst와 GameUnitDetail을 따르도록 수정 2018-03-31 05:28:19 +09:00
Hide_D 1ab65c7ac5 관리자 페이지에서 병종 정보, 리셋 데이터 제거 2018-03-31 05:27:59 +09:00
Hide_D 6775c06d3e 병종에 정보 텍스트 포함.
징병, 모병 페이지 내용을 GameUnitConst, GameUnitDetail에 기반하도록 변경
- 추가로 금,쌀을 소수점을  포함하도록 변경
2018-03-31 05:21:47 +09:00
Hide_D c976e55d72 병종 기본 설정 추가 수정 2018-03-31 04:45:12 +09:00
Hide_D a1d37e5697 도시와 병종에 대한 초기 값 클래스 추가
- 도시의 경우 DB 초기화를 위한 build() 함수 포함
2018-03-31 03:57:16 +09:00
Hide_D 63aa31cb92 sql 일괄 동작 재 수정 2018-03-31 00:33:39 +09:00
Hide_D 91232a83eb sql 파일 을 불러오는 동작을 잘못 수행하는 점 해결리 2018-03-31 00:24:06 +09:00
Hide_D 48db8454c9 Validator 추가 2018-03-31 00:23:48 +09:00
Hide_D efb3cab370 valitron 한국어 지원 추가
https://github.com/vlucas/valitron/pull/244
2018-03-30 22:46:50 +09:00
Hide_D ad4ba85f50 Valitron을 composer에 추가 2018-03-30 22:07:41 +09:00
Hide_D e87fff35ee 스킨 기능 삭제 2018-03-29 22:32:23 +09:00
Hide_D 3082a3f0d9 인스톨러 구현 중 2018-03-29 22:19:11 +09:00
Hide_D 8345201cd0 turnterm을 0~7이 아니라 분 단위로 돌도록 개선
- addTurn, cutTurn 함수들을 재 구현
2018-03-29 22:15:35 +09:00
Hide_D 3b8c764544 install_db 과정에서 리셋 버그 수정 2018-03-29 02:38:04 +09:00
Hide_D 622ba5945a 세부 서버 install_db 구현 2018-03-29 02:24:20 +09:00
Hide_D 93e5082fdf Scenario build 마무리 2018-03-29 02:10:01 +09:00
Hide_D 0d4f4d06f3 sql 파일 정리 2018-03-29 01:43:03 +09:00
Hide_D 9719995f94 install_db 작성 준비 2018-03-29 01:37:58 +09:00
Hide_D fd0f5edfe3 build 전까진 실제 장수를 알 수 없는 점 보완 2018-03-29 01:23:58 +09:00
Hide_D 7f01e90573 구 이벤트 삭제 2018-03-29 00:59:52 +09:00
Hide_D 9d9af08ab6 성인 연령 빼먹은거 수정 2018-03-29 00:57:37 +09:00
Hide_D 79d74b1ed1 성인 연령(14세??)를 GameConst로 정의 2018-03-29 00:57:10 +09:00
Hide_D 9392d6f043 old 폴더 내용물 삭제 2018-03-29 00:53:44 +09:00
Hide_D bf81851ce2 시나리오 파일 삭제! 2018-03-29 00:52:54 +09:00
Hide_D a146cb69d0 j_load_scenario.php 에서 볼 수 있는 요약 형태본 추가
- 소소한 버그 수정
2018-03-29 00:50:35 +09:00
Hide_D 39f6056e94 Scenario에서 event를 추가할때 json_encode를 빼먹은 점 수정 2018-03-29 00:38:55 +09:00
Hide_D e56a2fa6fa 게임 내부에 이벤트 핸들러 통합 2018-03-29 00:36:50 +09:00
Hide_D d9de5a39e0 Scenario build 1차 완료
- NPC 생성 로직 수정
- 생성 안된 장수는 event로 넘김
- 완료된 event 삭제하는 action 추가
2018-03-29 00:27:42 +09:00
Hide_D 78260ecf30 game 테이블의 img를 show_img_level로 변경 2018-03-29 00:27:03 +09:00
Hide_D 38986b65f8 시나리오 국가 설정 코드 2018-03-28 20:39:30 +09:00
Hide_D 4326530dec colset을 can_change_flag로 변경. 2018-03-28 20:39:12 +09:00
Hide_D e8e18c059f CityHelper에 '국가명' 한정으론 오작동할 수 있으므로, fallback 추가 2018-03-28 19:16:34 +09:00
Hide_D 907ba0b26e CityHelper 추가 2018-03-28 19:14:11 +09:00
Hide_D 78a1ca3651 "-" 대신 명시적인 null 선언 2018-03-28 19:10:04 +09:00
Hide_D e4c1ca7f34 npcmatch -> affinity 2018-03-28 18:15:52 +09:00
Hide_D b7237140c8 Scenario\Nation 클래스 초기화
- 버그 수정
2018-03-28 17:48:05 +09:00
Hide_D f442ae3b97 json에서 장수 등록시 국가 소속 장수를 셀 수 있으므로 genCnt 속성 삭제 2018-03-28 17:30:36 +09:00
Hide_D 9b139e54f4 install.php에 1차적으로 ChangeCity를 물림 2018-03-28 17:20:35 +09:00
Hide_D c1976b5b7a 사실 모드 시나리오들에 초기 내정치 부여 코드 추가 2018-03-28 17:07:30 +09:00
Hide_D 51783c1845 ChangeCity를 시나리오에서 처리할 수 있도록 '조건 방식' 추가 2018-03-28 16:53:59 +09:00
Hide_D 89c45421d8 오타 수정 2018-03-28 06:07:32 +09:00
Hide_D fad29e3faf 이민족 침입 일부 구현 2018-03-28 06:05:16 +09:00
Hide_D b2896d09ec ChangeCity 버그 수정.
RaiseInvader를 하나로 통합
2018-03-28 05:32:31 +09:00
Hide_D 6c84d184fe ChangeCity 추가 버그 수정 2018-03-28 05:07:43 +09:00
Hide_D 7e91b2534f ChangeCity 버그 수정 2018-03-28 05:06:38 +09:00
Hide_D 0675126b82 ChangeCity 액션 추가 2018-03-28 04:59:04 +09:00
Hide_D ee4518fc5c randF 등을 Util로 옮겼으므로 func.php에서 제거 2018-03-28 04:58:57 +09:00
Hide_D dc6596b5ab 자주 사용할 random, 수식 비교 함수 추가 2018-03-28 04:42:13 +09:00
Hide_D 327ea72214 로직 단축 명령 버그 수정 2018-03-28 03:20:12 +09:00
Hide_D 6913fe0313 Condition에 Date 추가.
Condition에 logic 단축 명령 추가
2018-03-28 03:19:05 +09:00
Hide_D e739b7a39f 시나리오에 기본값으로 initialEvents와 events추가 2018-03-28 02:55:42 +09:00
Hide_D a03eac6f2a 시나리오용 EventEngine.... 틀만 완성! 2018-03-28 02:45:44 +09:00
Hide_D 0ad8db5a63 리셋 시 시나리오 정보를 간단히 보여주는 기능 추가 2018-03-27 02:44:28 +09:00
Hide_D 492a7676c6 install.php, install_db.php 분리 2018-03-27 01:14:20 +09:00
Hide_D b9d21c29c0 gitignore에서 d_setting 폴더 관련 변경
- 기타 예전 python 코드에서 사용하던 gitignore 파트 삭제
- 누락되었던 파일 추가
2018-03-27 01:09:55 +09:00
Hide_D 2b9d47870b autoload 순서 변경 2018-03-27 00:42:33 +09:00
Hide_D 88e007ac00 서버 관리 폼 수정
부운영자, 운영자 권한 표기
2018-03-26 23:43:27 +09:00
Hide_D a2100f503f 새 리셋 툴 준비 2018-03-26 00:27:51 +09:00
Hide_D bc2c480986 입구 사소한 버그 수정
- 관리자 페이지가 html여도 되므로 html로 변경
2018-03-25 22:53:15 +09:00
Hide_D 5e29443256 js, css파일 위치 이동 2018-03-25 22:41:30 +09:00
Hide_D bd975e4f79 오래된 유저 삭제 버그 수정 2018-03-25 22:12:00 +09:00
Hide_D 5c415e4f61 샘플 코드 제거 2018-03-25 21:56:56 +09:00
Hide_D 83d619835f 새 회원 관리창 1차 구현 완료. 2018-03-25 21:46:03 +09:00
Hide_D 7a34cc4089 Setting 클래스 변경. 해당 클래스에서 한국어명 등을 모두 관리.
- 해당 클래스를 참조하는 코드들 수정
2018-03-25 17:56:07 +09:00
Hide_D b7c03e5554 로그아웃 관련 __set 버그 해결 2018-03-25 17:28:35 +09:00
Hide_D 503ad43a9e 로그인, 로그아웃시 member_log에 기록 남김 2018-03-25 17:19:07 +09:00
Hide_D 13ee593548 GameConst 클래스의 항목들을 public static으로 변경. 2018-03-25 01:19:37 +09:00
Hide_D bcea562636 js 파일 이동.
md5-min.js 제거
func.php 이동
2018-03-25 01:09:44 +09:00
Hide_D b1bea8dbc2 app.css, config.css를 css디렉토리로 이동 2018-03-25 01:07:29 +09:00
Hide_D 3df5de5eb5 관리자도 로그인할 수 없는 문제 해결 2018-03-25 00:48:44 +09:00
Hide_D c3cb100947 일부 코드 수정
- index.php에서 javascript string 이어붙이기 문제
- RestAPIHelper 클래스
- 세부 서버 Autoload 수정
2018-03-25 00:45:23 +09:00
Hide_D 3fbf1d4b0c class_exists 다시 수정 2018-03-25 00:33:31 +09:00
Hide_D 51d62b54d4 test.php 수정 2018-03-25 00:32:17 +09:00
Hide_D 8c03d1fa31 class_exists에 namespace가 지정되지 않은 문제 해결 2018-03-25 00:30:44 +09:00
Hide_D cab0401dfa 불필요한 autoload 제거
namespace 누락한 파일 수정
2018-03-25 00:24:12 +09:00
Hide_D d777ca97c6 f_config/DB.php 제거
class_exists('RootDB')로 대체 가능
2018-03-25 00:21:06 +09:00
Hide_D 9e1aadf486 getDB(), getRootDB()를 autoload 클래스로 변경
- 각각 DB::db(), RootDB::db()임.
2018-03-25 00:07:37 +09:00
Hide_D bb1a496835 composer autoload 위치 변경
gitignore에 해당 위치의 파일 추가
2018-03-24 23:31:43 +09:00
Hide_D 2cf6d0f01a f_config/app.php 삭제, AppConf 클래스로 통합 2018-03-24 22:50:46 +09:00
Hide_D e97bb32fba autoload 경로에 deny용 .htaccess 추가 2018-03-24 22:14:20 +09:00
Hide_D 0d4c3db333 skin을 삭제하므로, unfont()도 삭제 2018-03-24 22:05:15 +09:00
Hide_D 157ecdbf2a 많은 유틸리티 함수를 Util, FileUtil, WebUtil로 이동 2018-03-24 22:03:54 +09:00
Hide_D b5cba27df9 util 클래스 명을 PSR1에 맞게 Util로 재 명명 2018-03-24 21:31:31 +09:00
Hide_D 002f9ba6cf _Setting, _String, _Time 클래스 재 명명
- autoload로 변환
2018-03-24 21:28:12 +09:00
Hide_D a3f83d1e95 Session 클래스 수정.
- Session클래스 내에서 global setter, getter 재정의
- Session클래스에서 static 함수로 getUserID, getUserGrade 재정의
- 내부 서버에서 getUserID, getUserGrade를 쓰던 것 Session 클래스로 통일
- SESSION.php가 requireLogin 기능을 수행하던것을 Session의 static 함수로 통합
2018-03-24 20:04:55 +09:00
Hide_D 4bcdf8b208 Session을 autoload에 포함 2018-03-24 19:01:13 +09:00
Hide_D 037a29ad02 autoload 경로 재 변경
kakao를 별도의 namespace로 분리
외부 class의 namespace 문제 해결
2018-03-24 18:46:37 +09:00
Hide_D dc507601f5 util 클래스 변경
게임 내부 파일에 대해서 autoloader 적용
2018-03-24 18:22:04 +09:00
Hide_D 462bafe806 autoloader 구성.
class 정의
2018-03-24 18:13:03 +09:00
Hide_D 3363b547d5 firephp 추가 2018-03-24 16:59:04 +09:00
Hide_D 6068e1d618 새 세부 서버 인스톨러 준비 2018-03-24 16:54:51 +09:00
Hide_D 6f186125e3 NULL -> null 2018-03-24 12:38:03 +09:00
Hide_D ec3d0c5f68 index.php 페이지 살짝 수정 2018-03-24 12:35:48 +09:00
Hide_D c307215a85 회원 가입시 닉네임 길이를 mb_strlen으로 해야하는 점 수정
아이디를 대소문자 다 받던 것 수정(소문자로 자동 변경)
2018-03-23 10:19:27 +09:00
Hide_D e4300fa5f6 회원 관리 class이름만 변경 2018-03-22 04:00:37 +09:00
Hide_D 1128f93fcd 회원 관리 페이지 초안 작성 2018-03-22 03:58:25 +09:00
Hide_D 8e6fb7e9cf returnJson 동작 방식 일부 수정 2018-03-22 03:23:15 +09:00
Hide_D ca3b72808a 사용하지 않는 구 클래스 삭제 2018-03-22 03:22:57 +09:00
Hide_D e6c02deacd jquery 구버전 삭제 2018-03-22 03:16:34 +09:00
Hide_D a5110fa1e8 j_login.php를 제외한 모든 기존 login 코드 폐기 2018-03-22 03:15:47 +09:00
Hide_D c699824cfc Lock클래스의 경로가 install 초기 상태에서는 permission이 보장되지 않으므로 수정 2018-03-22 03:13:44 +09:00
Hide_D cc98ed9040 입구 페이지에 session_write_close() 조기 호출 2018-03-22 02:59:24 +09:00
Hide_D f7b2f88910 파일명 변경2 2018-03-22 02:56:05 +09:00
Hide_D ef67f7ec4e 파일명 변경 2018-03-22 02:54:49 +09:00
Hide_D e5ff6b2218 입구 페이지 파일명 정리 2018-03-22 02:50:33 +09:00
Hide_D 23e0ecf17c 추후 업데이트 기능 추가 대비 2018-03-22 02:46:16 +09:00
Hide_D e9672c98ef 일부 미사용 변수 정리
대문 css 정리
2018-03-22 02:40:32 +09:00
Hide_D 683138457f 카카오로그인 버튼 반영.
비밀번호 찾기 위치는 고민중
2018-03-21 03:20:04 +09:00
Hide_D f7a9445954 탈퇴 프로세스 추가 2018-03-21 02:57:59 +09:00
Hide_D f3d7a6a1a7 내 정보 관리 새로 구현
- 비밀번호 수정,
- 전콘 제거, 전콘 변경 기능 추가
2018-03-20 02:59:40 +09:00
Hide_D b27562613e <!DOCTYPE html> 2018-03-19 23:23:05 +09:00
Hide_D 005a495fdb meta charset="UTF-8" 2018-03-19 23:16:57 +09:00
Hide_D 0518671816 유저 권한을 $SESSION을 이용하는 형태로 변경 2018-03-19 22:57:01 +09:00
Hide_D bf5bc5b948 불필요해진 app.js, config.js 제거 2018-03-19 22:27:10 +09:00
Hide_D 280e81250c 불필한 const varname -> string 대체 제거.
필요할 곳은 나중에 처리하는 것으로.
2018-03-19 22:26:07 +09:00
Hide_D c44b836e3e ajax 코드에서 끝부분 sleep 제거 2018-03-19 20:40:00 +09:00
Hide_D 3bdea57318 server action이 없을 경우 에러를 반환하도록 수정 2018-03-19 20:38:47 +09:00
Hide_D ff4addbf28 서버 post를 string으로. 2018-03-19 20:36:37 +09:00
Hide_D 1885c44610 git ignore 추가 2018-03-19 20:23:40 +09:00
Hide_D e483fe93a4 서버 관리 패널 일부 수정 2018-03-19 02:52:50 +09:00
Hide_D efa6cc2889 서버 운영자 페이지 수정 2018-03-19 00:31:04 +09:00
Hide_D 1c4709ea65 Setting 클래스들 접근 방법을 변경
-global 없이 사용가능
-isExist()를 isExists()로 변경
2018-03-19 00:30:52 +09:00
Hide_D 95021f0887 설치시 카카오 계정을 설치하라고 TODO로 넣어두기...만 함 2018-03-18 23:11:31 +09:00
Hide_D 102dff43f4 tmp_kakao를 경로 이동 2018-03-18 13:30:04 +09:00
Hide_D 1a96d55ed7 conf_kakao.orig.php 파일로 이동 2018-03-18 13:30:04 +09:00
Hide_D 4df53fbc7e gitignore에 conf*.php 추가 가능하도록 변경 2018-03-18 13:29:54 +09:00
Hide_D 1ad7d17bbe 메일 전송 기능 삭제. 나중에 필요하면 다시 추가하기로. 2018-03-18 05:48:56 +09:00
Hide_D 6130bd22cb 카카오로그인 연동 방식 변경
-oauth 테이블 삭제
-비밀번호 변경 기능 추가(카카오톡 나에게 보내기)
2018-03-18 05:44:20 +09:00
Hide_D bd26ee858c 설치시 서버의 기본 경로를 받도록 설정 2018-03-18 05:19:28 +09:00
Hide_D b52bd4e4e2 카카오로그인을 이용한 가입, 로그인 프로세스 보완 2018-03-18 04:12:37 +09:00
Hide_D be7df8adac 설치시 system를 누락하여 추가 2018-03-18 02:08:07 +09:00
Hide_D a573969897 서버 선택 창에서 '로그인 된 경우' 정상 작동하지 않는 문제 해결
- 추가로 이미지가 틀어져서 나오는 문제도 해결
2018-03-18 00:44:44 +09:00
Hide_D 2b85cd09bb 관리자 생성시 이전 session이 남아있던 문제 해결 2018-03-18 00:24:33 +09:00
Hide_D 3e44c861e2 인스톨시 권한을 5(부운영자)로 설정한 것을 6으로 변경 2018-03-18 00:21:37 +09:00
Hide_D 2ff8f51b01 기존 인스톨 코드 삭제 2018-03-18 00:16:55 +09:00
Hide_D ce169f356e common install 프로세스 완료. 2018-03-18 00:16:17 +09:00
Hide_D 5a0b358b60 common install에서 conf.php 생성까지 완료 2018-03-17 23:49:32 +09:00
Hide_D 6cb55a1d97 join_form에서 submit버튼 검사 추가 2018-03-17 23:49:17 +09:00
Hide_D cb133bbeaa comment 추가 2018-03-17 23:00:47 +09:00
Hide_D 63ab8bd6f7 공용 테이블 스키마 변경 2018-03-17 22:54:57 +09:00
Hide_D cb30074c54 common_schema.sql 파일을 이동 2018-03-17 22:34:24 +09:00
Hide_D 96e4c08ee9 generateFileUsingSimpleTemplate의 변환 규칙 변경 2018-03-17 22:08:34 +09:00
Hide_D 7f885f7a69 generateFileUsingSimpleTemplate() 함수 작성 2018-03-17 21:42:39 +09:00
Hide_D 065107033b 새로운 설치 코드 준비 2018-03-17 21:21:44 +09:00
Hide_D 7486ff3eec 기존의 삭제할 set.php 2018-03-17 20:03:17 +09:00
Hide_D b16c6c8d23 일부 회원 관리용 버튼 div id 변경 2018-03-17 14:42:57 +09:00
Hide_D 8caa086c38 새 서버 목록 class명 살짝 변경 2018-03-17 07:49:38 +09:00
Hide_D 135254402d 새 서버 선택 페이지 중 '장수 선택', '장수 생성', '입장' 레이아웃을 구현 2018-03-17 07:27:13 +09:00
Hide_D ac28032032 server_basic_info 문법 오류 수정 2018-03-17 06:20:50 +09:00
Hide_D fa56fc0318 서버 선택창 일부 수정.
서버 세부 정보를 받아올 수 있도록 수정 준비
2018-03-17 06:20:22 +09:00
Hide_D d93d5afdee 내부 서버 문법 오류 수정 2018-03-17 06:19:54 +09:00
Hide_D f557e1f241 서버 선택창 추가 변경.
- div absolute로 강제로 띄우는 것을 제거
- '폐쇄중' 까지 정상적으로 띄움
2018-03-17 05:55:55 +09:00
Hide_D cd1456caa7 서버 선택 리스트 재작성 2018-03-17 05:12:11 +09:00
Hide_D fc8dc09945 로그인 기능 임시 추가 2018-03-16 02:40:56 +09:00
Hide_D e2610d7e41 _Session 클래스 일부 변경 2018-03-16 02:40:49 +09:00
Hide_D 3fcaa153f9 회원 가입시 global_salt를 올바르게 사용하지 않는 문제 해결 2018-03-16 02:20:39 +09:00
Hide_D cdae15fd41 사용하지 않는 _Log, _Process 삭제 2018-03-16 01:56:38 +09:00
Hide_D 498ebd6589 사용하지 않는 class._JSON.php 제거 2018-03-16 00:49:04 +09:00
Hide_D 26b1a89688 join, login 위치 변경 2018-03-15 23:33:40 +09:00
Hide_D ee8281dd06 카카오 로그인 상수 GET,POST,DELETE 제거 2018-03-13 19:43:10 +09:00
Hide_D 94181ee3d7 로그인 대문 페이지 재작성 시작 2018-03-13 02:15:39 +09:00
Hide_D d4c75223a8 회원 가입 기록을 남기도록 설정 2018-03-10 04:53:24 +09:00
Hide_D 88c560405e 로그인 프레임 일부 수정 2018-03-10 04:48:25 +09:00
Hide_D 4b1e3e325e 카카오 로그인을 이용한 가입 테스트 2018-03-10 04:16:17 +09:00
Hide_D e00b763f43 bootstrap 추가
sha512 js 추가
2018-03-09 20:33:01 +09:00
Hide_D f3d5922340 PW 암호화에 사용할 globalSalt 개념 추가 2018-03-09 02:59:41 +09:00
Hide_D 704096358b 수정된 DB, SETING.php 동작 안하는 문제 해결 2018-03-09 02:18:59 +09:00
Hide_D 6ffee27f83 index, install 페이지 변경 준비 2018-03-08 00:00:19 +09:00
Hide_D fffd45b2e0 logger 추가 2018-03-07 23:21:06 +09:00
Hide_D 1b70485c9a banner, google_analysis 코드 제거 2018-03-07 21:33:19 +09:00
Hide_D bc3a6cf86e 통합 서버 관리자의 파일 경로 코드를 문자열로 변경. 2018-03-07 21:29:48 +09:00
Hide_D 7206826974 필요하지 않게된 ADODB 제거 2018-03-07 01:03:25 +09:00
Hide_D 0c9be5c53f 루트DB를 관리하는 방식을 통째로 변경
- DB 불러오는 방식을 기존의 set.php에서 conf.php의 getRootDB()를 이용하도록 변경
- ADODB 에 기반한 _DB 클래스 폐기
- DBS.php 폐기
- _Setting 클래스 용도 변경
- 서버 목록 정의 방식을 하나로 모음
- 로그인시 세션에 사용자 등급을 추가
- "참여"(donation) 관련 코드 전면 제거
- 서버 리셋시 부운영자 비밀번호 문제 수정
- 서버 오픈,닫힘 여부를 새 서버 목록 정의 방식에 따르도록 수정
- DBS.php가 폐기 되었으므로 서버 오픈시 기본 정보를 json으로 받아오도록 하기 위하여 기본 준비
-  기존에 남아있던 세부 서버 로그인 처리 파일을 제거(enterPost.php)
- DBS.php 삭제로 전콘 변경시에도 각 서버로 json 호출을 하도록 하는 방식으로 준비
- 전콘을 수동으로 서버에 올린뒤 처리할 수 있도록 하던 legacy 코드 제거
- general 테이블에서 userlevel 컬럼을 삭제하고, 세션에 기록된 userGrade를 이용하도록 변경
- 벌점 제한을 모든 유저 공통으로 하도록 수정
- 세부 서버 리셋을 json ajax로 처리하도록 준비
2018-03-07 00:59:31 +09:00
Hide_D e8a9f73611 개별 서버마다 getDB() 함수를 부를 수 있도록 수정 2018-03-05 02:03:31 +09:00
Hide_D c49dcf8152 레거시 dbConn 함수를 우선 getDB() 함수에 기반하도록 변경 2018-03-05 00:49:31 +09:00
Hide_D 77395dd90e 컬러 코드에 전부 # 추가.
image 파일에는 #이 없어야 하므로 이후 대응 필요
2018-03-04 23:44:20 +09:00
Hide_D 0ab656349e scenario를 json 형태로 추가 2018-03-04 23:30:00 +09:00
Hide_D 8ced95cc5f 이전 코드에 빠진 부분 수정 2018-03-04 23:23:53 +09:00
Hide_D 30e1b365fa 레거시 코드 정리
$a[count($a)] = ""; 의 형태로 된부분을 변경
RegGeneral 함수 계통 손보는 중
2018-03-04 23:21:26 +09:00
Hide_D 536ff0988d adodb를 composer로 불러오도록 2018-03-04 19:06:46 +09:00
Hide_D a8477aed99 func_process에서 인사 관련(거병,건국,선양,하야,등용,임관,인재탐색) 함수를 별도로 분리 2018-03-04 18:53:22 +09:00
Hide_D 7cc5558e33 구 Legacy SQL 명령을 사용하는 함수 수정
increateRefresh(), RegNation(), RegCity()

$connect 인자가 필요없는 함수 수정
push*Log() 류
2018-03-04 18:43:53 +09:00
Hide_D a3791fa6fd func.php, func_rpcoess.php를 용도에 따라 분리 2018-03-04 00:56:04 +09:00
Hide_D 98fd5b450b 전콘 이미지 조건 표기 텍스트 변경 2018-03-03 18:23:01 +09:00
Hide_D 9903f5b624 $_basegold, $_baserice를 GameConst로 변경 2018-03-03 18:22:48 +09:00
Hide_D d1026aae0f command 계열 함수 func_command.php 로 이전
baclButton(), CoreBackButton(), closeButton()을 echo에서 return string 타입으로
2018-03-03 17:46:23 +09:00
Hide_D f66238bb38 등용장 처리 코드 리팩토링 2018-03-02 02:55:29 +09:00
Hide_D bebc7580bd 코드 내의 불필요한 모든 history 제거 2018-03-02 02:02:16 +09:00
Hide_D ea638b8221 addHistory(), addNationHistory()에서 history를 덧붙이는 과정 개선 2018-03-02 00:46:23 +09:00
Hide_D c0dfd42791 pushHistory에 DB connect가 필요하지 않으므로 인자 제거 2018-03-02 00:05:37 +09:00
Hide_D ae2272b249 msgOption에 alert 옵션 추가 2018-03-01 22:50:18 +09:00
Hide_D c48cf824eb 갠메를 이용하는 레거시 코드 제거 2018-03-01 20:33:40 +09:00
Hide_D a72452454c 메시지 전송 과정에서 전송자에 id, nation_id만 필요하도록 변경 2018-03-01 20:18:54 +09:00
Hide_D de4c2e0678 새 메시지 시스템 통합 준비 완료 2018-03-01 18:36:29 +09:00
Hide_D 33cc00cced 새메시지, contact_list 코드를 func_message.php로 이동 2018-03-01 04:44:02 +09:00
Hide_D dcb2903578 로그인되지 않은 경우에는 리스트 출력 없음 2018-03-01 04:35:08 +09:00
Hide_D 7af3c6e91a 새메시지, contact_list 추가 2018-03-01 04:30:24 +09:00
Hide_D 9e7450f977 array_map의 보완을 위한 dict_map 추가. python의 map과 유사하게 동작 2018-03-01 04:17:15 +09:00
Hide_D 3e7fdf8e90 새메시지용 basic_info 코드 추가 2018-03-01 03:48:57 +09:00
Hide_D 32207277d5 j_map.php에서 generalID가 세션에 지정되지 않은 경우를 대비 2018-03-01 03:48:32 +09:00
Hide_D 1f33908063 basic_info에 이젠 필요없는 lastContact 삭제 2018-03-01 03:34:03 +09:00
Hide_D 4b0352d8f0 새메시지, refreshMailboxList() 가 여러번 불릴 것에 대비 2018-03-01 03:31:31 +09:00
Hide_D e79a12cbc6 새메시지, 즐겨찾기 대상을 동적으로 계산하도록 수정 2018-03-01 03:26:00 +09:00
Hide_D 401167ca31 새메시지 변수명 정리 2018-03-01 02:58:35 +09:00
Hide_D 7efc03813b 간단한 국가 정보를 가져오는 코드들을 일부 통합. 2018-02-26 01:46:13 +09:00
Hide_D 2cd7d525a4 단순 국가 정보를 받아올 때 query하지 않고 저장된 값을 쓰도록 변경 2018-02-24 17:41:04 +09:00
Hide_D b28603d16f refeshNationStaticInfo 함수 추가
getNationStaticInfo 함수에 level 추가
2018-02-24 02:47:50 +09:00
Hide_D e5d923643d general 테이블에서 갠메 파트 제거 2018-02-22 02:09:59 +09:00
Hide_D 34cd58d8f3 메시지 전송 시스템을 새 시스템에 맞게 수정
국가의 기본 정보를 중복 쿼리 없이 받아오는 함수 추가
  - 해당 함수를 위해 국가색, 건국 등의 국가 정보가 바뀌는 경우 refresh
새 메시지 시스템 적용을 위해 메인 페이지 틀 변경
2018-02-22 02:04:54 +09:00
Hide_D 2fb005ec6d 메시지의 valid 여부를 option에서 제거 2018-02-22 01:08:06 +09:00
Hide_D 7ac82d2293 sendMessage sendRawMessage에 $validUntil 추가 2018-02-21 22:47:07 +09:00
Hide_D 86e42bb986 message db schema에 valid_until 추가 2018-02-21 22:42:57 +09:00
Hide_D 1450715c56 새 메시지, 메시지 수락/거절 동작 방식 변경 2018-02-21 22:37:54 +09:00
Hide_D a0314dad47 CriticalRatioDomestic 버그 수정(TM) 2018-02-21 12:51:48 +09:00
Hide_D c6fa91d022 scssphp 추가 2018-02-21 10:41:15 +09:00
Hide_D ba0439ece2 tm서버에 적용된 패치 수정을 같이 적용 2018-02-20 01:34:44 +09:00
Hide_D 5c96329b33 계략시 적 장수도 제대로 반영하도록 2018-02-19 00:39:19 +09:00
Hide_D cd16f832e2 계략에서 상대 도시 장수의 능력치를 처리하지 않는 문제 수정 2018-02-19 00:11:42 +09:00
Hide_D 63b897b9ac 내정 성공 확률을 기존 서버와 동일하게 변경 2018-02-18 21:47:40 +09:00
Hide_D 3b636a8b46 전투시에도 무력/지력 1/4씩 반영하도록 수정 2018-02-18 03:33:53 +09:00
Hide_D 68ace3f1dd 내정 시 무력/지력 1/4씩 추가 보너스 반영
- getGeneralLeadership 함수 추가
- getGeneralPower 함수 추가
- getGeneralIntel 함수 추가
- CriticalRatio 함수를 CriticalRatioDomestic 함수로 리팩토링
- 내정에 한해 lbonus를 계산하는 setLeadershipBonus 함수 추가
- 계략시 부상 정도를 반영하도록 수정
2018-02-18 03:15:14 +09:00
Hide_D 868a572175 전콘 변경시 이전 파일명을 제대로 추적하도록 변경 2018-02-18 01:39:34 +09:00
Hide_D b3166e2f00 deletePost unlink시 Windows에서 오동작 수정 2018-02-18 01:06:40 +09:00
Hide_D 20bf949a17 전콘 파일명을 랜덤하게 변경 2018-02-18 00:58:39 +09:00
Hide_D 47bdb068d5 npc_login 우회 기능 삭제 2018-02-17 23:47:38 +09:00
Hide_D 6610662f74 명예의 전당 등록 기준을 45세 이후로 수정 2018-02-17 18:24:09 +09:00
Hide_D 9329ea1668 호황/재난의 증감이 해당 도시의 치안에 따르도록 변경 2018-02-17 16:47:40 +09:00
Hide_D b47285c545 새메시지, 클라이언트 단 메시지 시스템 1차 완성 2018-02-13 01:01:02 +09:00
Hide_D cd243ce950 수락, 거절 전송을 위한 dummy 생성 2018-02-13 00:08:19 +09:00
Hide_D 6f8ac8dc6f 새메시지, 로딩 즉시 필요한 데이터들을 모두 비동기로 불러오도록 변경 2018-02-12 23:57:12 +09:00
Hide_D 5d04b208a6 기본 정보를 basic_info.json으로 분리함. 2018-02-12 23:35:03 +09:00
Hide_D 7d465c444d 새메시지, mailboxList를 처리하는 코드 일부 추가 2018-02-12 22:42:05 +09:00
Hide_D 8a2d4c3540 generalID와 isChief를 sender_list에서 알려주도록 수정 2018-02-12 22:38:58 +09:00
Hide_D e864af0b6d 새메시지, 출력 방식 수정 2018-02-12 21:41:11 +09:00
Hide_D 63be06c98f 새메시지, json 파일을 일관성있게 수정 2018-02-12 21:40:50 +09:00
Hide_D 420469ef75 resetSessionGeneralValues() 를 lib.php로 이동 2018-02-12 21:36:58 +09:00
Hide_D ff2d5373f0 새메시지, 기본틀 완성. 2018-02-12 02:53:08 +09:00
Hide_D 4166093296 새메시지. 초기 버전 업로드 2018-02-12 01:55:55 +09:00
Hide_D db29e7d020 테스트용 pic 파일 위치 잘못된 것 수정 2018-02-12 01:54:45 +09:00
Hide_D ecd067be8e 새메시지, js 구현 준비 2018-02-12 01:15:01 +09:00
Hide_D 26d526f47c 다른 경로에서 lib.php를 불러왔을 때 생기는 문제 해결 2018-02-12 01:14:32 +09:00
Hide_D 18e663c529 템플릿 출력 준비
템플릿에 option 확인 기능 추가
현재 수뇌 여부도 반환
2018-02-11 05:30:34 +09:00
Hide_D 0a7d9cbe21 반환 값에 generalID가 있어야할 것 같아서 추가 2018-02-11 00:44:14 +09:00
Hide_D d49803baed String.prototype.format을 common.js로 이동 2018-02-11 00:13:11 +09:00
Hide_D 6052b3c577 메시지 예제 초기 데이터 준비
예제용 이미지 추가
fresh_result.json에 갠메, 전메, 국메, 외교 추가
2018-02-10 23:49:43 +09:00
Hide_D 75c99904c6 sendRawMessage가 DB 스키마와 맞지 않는 버그 해결 2018-02-10 22:05:50 +09:00
Hide_D da75e3c72a msg 기본 틀 준비 2018-02-10 20:26:43 +09:00
Hide_D efbdd28c6f json으로 받아온 내용을 출력하긴 위한 template 준비
common.js 파일 추가
메시지를 변환하기 위한 msg_template.html 작성
2018-02-10 18:51:03 +09:00
Hide_D 4993e8239c msgsubmit의 response를 변경 2018-02-10 01:13:55 +09:00
Hide_D 669e2d5141 DB Object에서 MYSQLI_OPT_INT_AND_FLOAT_NATIVE 켬. 2018-02-09 03:23:25 +09:00
Hide_D 1d8f973d48 diplomacy코드를 mailbox는 9000번대, diplomacy type만 지정하는 방식으로 변경 2018-02-09 03:05:00 +09:00
Hide_D b4669d6fcb 주석 추가 2018-02-09 03:00:58 +09:00
Hide_D 0e6eada718 오타수정 2018-02-09 02:59:49 +09:00
Hide_D 46eda74a6f 외교서신을 위한 mailbox code로 8000번대 지정 2018-02-09 02:58:45 +09:00
Hide_D 76226a2470 매 0분 0초에 나타나는 이벤트들을 분리 2018-02-09 02:43:14 +09:00
Hide_D d985cbdf6c message 테이블 변경 2018-02-09 02:38:16 +09:00
Hide_D d8a39290f6 특기 등장 확률을 randF가 아닌 randBool로 변경 2018-02-09 02:13:36 +09:00
Hide_D 4b414c0879 실수를 줄이기 위한 randBool 함수 추가 2018-02-09 02:11:58 +09:00
Hide_D 191226289d message 클래스는 변경한 table 구조에 맞게 변경 2018-02-09 02:10:38 +09:00
Hide_D 1eb3944b8a dictionary(php에선 associative array) 여부 확인하는 코드 추가
메시지 전송 코드를 message에 json을 이용하도록 변경. 외교 서신 등을 위한 $option을 추가
2018-02-09 02:02:38 +09:00
Hide_D 8b20985668 json_encode시 null을 없애기 위한 코드 추가 2018-02-09 01:32:44 +09:00
Hide_D 47016d7224 메시지 코드 준비 2018-02-04 22:55:33 +09:00
Hide_D c90af2df2c <O> 태그를 실험삼아 없애봄 2018-02-04 21:55:39 +09:00
Hide_D 9addefb79e 서버 정보를 span으로 바꿈 2018-02-04 20:03:26 +09:00
Hide_D b1841e1e93 임시로 전투 로그를 template화 해봄. 2018-02-04 19:39:25 +09:00
Hide_D ecca899a82 global 변수로 지정된 값을 GameConst의 형태로 변경중 2018-02-04 16:53:01 +09:00
Hide_D c914fd2aa8 서버 차단용 htaccess에 1분짜리 cache control을 추가 2018-02-04 05:43:46 +09:00
Hide_D 001d7037c5 새 메시지 시스템 준비 2018-02-04 05:37:41 +09:00
Hide_D df63869a29 각종 상수값들을 쓸 수 있는 GameConst 준비 2018-02-04 05:25:29 +09:00
Hide_D 5ed33b1cda general table의 no_member를 의미에 더 맞도록 owner로 변경.
general table의 user_id, password column 삭제. 코드도 이를 참조하지 않고 owner를 이용하도록 변경
2018-02-04 04:40:35 +09:00
Hide_D e42643d439 toInt에 강제 변환 기능 추가(=intval에 null만 추가) 2018-02-04 04:33:25 +09:00
Hide_D 2708b48bd9 vender 디렉토리를 검색에서 제외 2018-02-04 04:23:42 +09:00
Hide_D 4624e511fc 권한 없이도 reset.php에 접속하면 초기화 가능한 문제 해결 -_-; 2018-02-04 04:22:30 +09:00
Hide_D 26ab9044f0 귀모 내특 확률이 잘못 계산되던 문제 2018-02-04 04:00:37 +09:00
Hide_D 8866a05c01 id, pw 삭제중(진행중) 2018-02-03 06:10:04 +09:00
Hide_D 924864288c 스탯 주사위 폐기 2018-02-03 06:04:17 +09:00
Hide_D 7336847d04 main.php -> index.php 2018-02-03 05:30:12 +09:00
Hide_D 02dce232fd 불필요해진 파일들 삭제 2018-02-03 05:26:43 +09:00
Hide_D 76a5b9a214 세션 폴더 삭제 2018-02-03 05:23:20 +09:00
Hide_D 2516dd0166 주소가 고정되어있던 SVN deploy 코드 폐기 2018-02-03 05:22:07 +09:00
Hide_D 9c6deadf11 입장 절차를 바로 링크로 변경 2018-02-03 05:08:12 +09:00
Hide_D 172bf9bbbc 로그 저장시 noMember가 아니라 id로 저장되도록 우회 2018-02-03 05:01:50 +09:00
Hide_D 7729236a11 로그인 시 p_id를 같이 생성하도록 변경 2018-02-03 04:54:27 +09:00
Hide_D e957a91b19 p_id를 noMember 기반으로 변경 2018-02-03 04:49:54 +09:00
Hide_D ecac4b6edb 세션 테이블을 뒤집어 엎는 중.
session 디렉토리 제거. 서버의 자체 session으로 관리함. 필요하다면 자동로그인을 추가함.

login_process.php를 이용하지 않고 자체적으로 세션을 관리하도록 처리 중.
2018-02-03 04:39:22 +09:00
Hide_D e536e2d4ca 내부 전역 변수값 처리를 위해 함수 정리
conf.php에 getServPrefix 추가. 이후 같은 db에서 다른 서버를 운용할때 사용 가능할 것으로 예상.

$_SESSION 값을 직접 받아서 처리하지 않도록 하기위한 용도로 getUserID(), getGeneralID(), getGeneralName() 을 설정

$_SESSION['p_id']를 p_no로 착각하여 구현한 부분 수정

int|null 변환을 위한 toInt 함수 추가

func_string.php에서 null이 입력될 경우 일부 처리

각 서버에 계정이 생성되었는지 확인하는 isSigned()함수 추가
2018-02-03 03:36:34 +09:00
Hide_D 0bd51726c3 새 맵 최종 적용. 구형 map.php 제거 2018-02-02 22:50:58 +09:00
Hide_D 43836e9757 map.php를 모두 새 지도 형식으로 변경 2018-02-02 22:41:41 +09:00
Hide_D f435ce2d4c Merge branch 'php5_debug' of https://storage.hided.net/gogs/devsam/core into php5_debug 2018-02-02 22:26:54 +09:00
Hide_D 9ef4e2debb json 반환시 캐싱하지 않도록 설정.
연감용 json 반환에는 캐싱할 수 있도록 설정
2018-02-02 09:36:49 +09:00
Hide_D 75fb281264 func_map.php를 통해 현재 지도 값을 받아오는 코드 추가
j_map.php를 통해 지도를 json 형태로 열람하는 코드 추가

연감의 저장코드를 http를 통해 지도를 받아오는 방식에서 func_map.php를 이용하는 방식으로 변경

map.js에서 반환값이 올바른지 확인하는 코드 추가

b_CurrentCity.php의 도시 정보 값을 get으로도 받을 수 있도록 변경

map.js에서 재야 상태일때 올바르게 처리하도록 변경
2018-02-02 09:36:14 +09:00
Hide_D 9c2d4217b8 json 반환시 캐싱하지 않도록 설정.
연감용 json 반환에는 캐싱할 수 있도록 설정
2018-02-02 01:21:16 +09:00
Hide_D f85443cf17 map.js에서 재야 상태일때 올바르게 처리하도록 변경 2018-02-02 01:07:30 +09:00
Hide_D e9fc23b8ee 반환하는 모든 값 중 int가 되어야하는 값들을 변경 2018-02-02 01:03:03 +09:00
Hide_D 438511972e func_map.php에서 연관배열을 일반 배열로 착각한 버그 수정
func_map.php에서 result를 설정하지 않은 버그 수정

main.php에서 지도를 제대로 불러오도록 수정

map.js에서 국가가 재야인 경우 국가 tooltip을 띄우지 않도록 수정

b_CurrentCity.php의 도시 정보 값을 get으로도 받을 수 있도록 변경
2018-02-02 00:55:02 +09:00
Hide_D 0841950366 func_map.php를 통해 현재 지도 값을 받아오는 코드 추가
j_map.php를 통해 지도를 json 형태로 열람하는 코드 추가

연감의 저장코드를 http를 통해 지도를 받아오는 방식에서 func_map.php를 이용하는 방식으로 변경

map.js에서 반환값이 올바른지 확인하는 코드 추가
2018-02-02 00:30:04 +09:00
Hide_D 1a4d82f871 map.php 대신 j_map.php를 사용하도록 준비 2018-02-01 17:58:13 +09:00
Hide_D 2db446a06d json 기반 지도를 출력하도록 코드를 추가 2018-02-01 17:39:57 +09:00
Hide_D 9005d5c8be err.txt 삭제 2018-02-01 16:16:31 +09:00
Hide_D 4d925b111d 임관, 전쟁 켬/끔 제한 삭제 2018-02-01 00:45:34 +09:00
Hide_D 3b862b53eb 충돌 병합 2018-02-01 00:41:27 +09:00
Hide_D 45ae19d74b 충돌 병함 2018-02-01 00:40:40 +09:00
Hide_D 402910ba78 array_rand는 키를 반환하므로 값을 적용하도록 수정 2018-02-01 00:37:52 +09:00
Hide_D fd8ab0e4b0 새 지도 map.html 디버깅 코드 제거, 실제 데이터로 이식 준비 2018-01-31 17:32:49 +09:00
Hide_D 1352009350 단순 모드도 추가 2018-01-31 17:24:45 +09:00
Hide_D 9efb83323a 내 도시 강조 추가 2018-01-31 15:38:06 +09:00
Hide_D 54c7bf3a04 새 지도 테스트를 위한 goCity.php 예제 추가 2018-01-31 14:12:34 +09:00
Hide_D 8f3c4ded62 새지도에서 touchend와 click이 동시에 발생할때 생기는 문제 해결 2018-01-31 14:10:51 +09:00
Hide_D 907b490747 새 지도 터치스크린 이벤트 분리 2018-01-31 11:49:36 +09:00
Hide_D d5fecd0388 새 지도에서 터치스크린에서 1터치 -> tooltip, 2터치 -> 클릭 으로 동작하도록 변경 2018-01-31 10:59:11 +09:00
Hide_D 70e226c6d5 새맵 디버깅용 2018-01-31 03:32:48 +09:00
Hide_D f4a89ea376 새지도 수도 표기 버그 해결 2018-01-31 03:30:16 +09:00
Hide_D 2958b73b16 수도 깃발 추가 2018-01-31 03:25:25 +09:00
Hide_D 3bbd9b2fbc 새지도 깃발끊김 추가 2018-01-31 03:21:10 +09:00
Hide_D e9828cd38e 새지도 이벤트 표시 추가 2018-01-31 03:02:32 +09:00
Hide_D ce0fab873b 새 지도에서 배경, 도시가 정상적으로 보이도록 수정 2018-01-31 02:32:37 +09:00
Hide_D 7542248641 새 지도 이미지 준비. 아직 충돌 많음. 2018-01-30 17:57:22 +09:00
Hide_D f2f32347f1 새 지도 코드에서 예제로 사용할 result.json 손봄
새 지도 코드에서 (detail, basic), (click, select)를 같이 사용할 수 있도록 정비
2018-01-30 15:28:43 +09:00
Hide_D 783400d071 common.css의 body를 main.css로 이동 2018-01-30 13:40:52 +09:00
Hide_D 6177ea97d2 동적으로 생성하는 map 파일 중간 작업까지 완료. 2018-01-30 02:56:12 +09:00
Hide_D 8307451842 잠시 맵 만듦 2018-01-29 23:38:09 +09:00
Hide_D 8e18116f22 stylesheet.php 사용하는 남은 참조 제거 2018-01-29 22:58:56 +09:00
Hide_D 3b8b62ac9b 기본 stylesheet를 common.css로 변경 2018-01-29 22:56:31 +09:00
Hide_D ae0c2de758 font-size:13;을 font-size:13px;로 변경
allButton.php를 template로 이동.
2018-01-29 22:54:40 +09:00
Hide_D a1cb2da6c1 banner frame 제거 2018-01-29 22:09:15 +09:00
Hide_D d2abd6daf2 oncontextmenu, ondragstart 금지 코드 수정. 우클릭 가능하도록. 2018-01-29 22:08:15 +09:00
Hide_D a4ecf23dd0 css 기본틀 추가
bar() 함수 수정. 막대 수정
2018-01-29 22:04:50 +09:00
Hide_D 01eef993fb doctype 추가. 2018-01-29 22:00:38 +09:00
Hide_D 32893d6692 func.php에 빼먹은 php파일 include 2018-01-29 21:58:19 +09:00
Hide_D 20593b0e44 composer 사용으로 날려먹은 util 단축을 살림. 2018-01-29 21:55:38 +09:00
Hide_D a78d93f282 returnJson(); 추가 2018-01-29 21:46:44 +09:00
Hide_D 55d15bb562 message에 만약을 위해 aux 추가 2018-01-29 20:14:06 +09:00
Hide_D b7923e04a4 sammo를 쓰는 일부 파일을 getRootDB()를 이용하도록 수정
메시지 DB 형태 변경.

메시지를 전송하는 별도의 함수 sendMessage(), sendRawMessage() 생성

j_msgsubmit.php 전면 수정

가능한 메일함을 구해오는 getMailboxList() 함수 추가

CheckBlock를 getBlockLevel로 변경하고, 내부 구현 수정
2018-01-29 02:14:41 +09:00
Hide_D 6d30e40cd3 '참여' 텍스트 1차 제거 DB는 다음에 2018-01-28 23:56:01 +09:00
Hide_D dc56de8afd newRootDB(), newDB가 이전의 코드 수정으로 new를 수행하는 경우가 줄어들었으므로 getRootDB(), newDB() 로 이름 변경 2018-01-28 21:44:08 +09:00
Hide_D 373bcde70b e_lib 코드들을 composer로 이동
func_http 삭제. guzzle로 대체

php 파일에서 include, require 앞에 있는 구문들을 전부 뒤로 이동.
2018-01-28 21:38:04 +09:00
Hide_D d422c03003 외부 코드를 Composer 기반으로 변경 2018-01-28 19:25:31 +09:00
Hide_D 8a181055a0 queryFirstField을 queryFirstField로 변경. 헷갈려. 2018-01-28 18:20:32 +09:00
Hide_D ca2b345075 regnpc를 별도로 분리. 2018-01-28 06:03:45 +09:00
Hide_D 88add40d4c gamerule에 해당하는 일부 함수 분리. 2018-01-28 06:02:19 +09:00
Hide_D 207f190e0b j_msgsubmit도 " 기호 제거 2018-01-28 05:45:55 +09:00
Hide_D 5ac2f4e27d converter에서 많은 "를 '로 변경.
- html tag의 attribute에서 안전하게 "를 쓰기 위하여
  - PHP 변수가 들어가는 경우를 줄이기 위한 카운트
2018-01-28 05:43:33 +09:00
Hide_D da73997385 meekroDB 에서는 숫자는 %i임 2018-01-28 05:35:47 +09:00
Hide_D 1a5e67233f isLock, lock, unlock 개선 2018-01-28 05:32:52 +09:00
Hide_D 1b675eabe2 onlinenum을 단순화 2018-01-28 05:27:11 +09:00
Hide_D 7a6040bd4d func_template 분리.
func_template의 함수를 <?=func()?> 형식으로 사용할 수 있도록 수정
2018-01-28 05:22:57 +09:00
Hide_D 9ec48f5f09 func.php 파일을 file, legacy, converter로 분리.
message 클래스에서 nation이 NULL경우 예외 처리
2018-01-28 04:56:20 +09:00
Hide_D 0c0c4fa547 newDB 함수 사용시 static 변수로 DB Object를 보관하도록 설정. 모든 update 명령은 global lock 하에서 통제되므로 이 방식을 사용할 수 있음. 2018-01-28 04:17:13 +09:00
Hide_D 221652405f template와 message 클래스 변수가 일치하도록 수정 2018-01-28 04:09:33 +09:00
Hide_D 9b45ca41fa 메시지 관련 template 준비중 2018-01-28 03:44:27 +09:00
Hide_D 3ecee6a9e8 필살 확률을 15%로 고정 2018-01-27 07:05:52 +09:00
Hide_D 3f38b6b675 수비, 성벽 강화의 성공을 무력 기준으로 올바르게 변경 2018-01-27 06:42:52 +09:00
Hide_D dd2f45c5bd 유저장에서 거상 삭제. NPC의 경우 아직 남겨둠 2018-01-27 06:34:13 +09:00
Hide_D 2037e9b6af 등용장 삭제 2018-01-27 06:18:07 +09:00
Hide_D 86dfbe6bec 연감이 62che.com에서만 동작하는 문제 해결 2018-01-27 06:04:24 +09:00
Hide_D 82110d98ef 갠메 전송 시스템 추가 2018-01-22 02:05:08 +09:00
Hide_D 67e2f8342e \r\n 마저 제거 2018-01-21 18:26:15 +09:00
Hide_D 8c3cc7649f \r\n 마저 제거 2018-01-21 18:25:59 +09:00
Hide_D d080e5ec2c \r\n을 \n으로 변경. 메모장에서 열 것도 아니고..
로그인 확인 등 몇몇 유틸 함수 새 db 라이브러리 기준으로 추가
ajax 기반 msgsubmit 작업중
2018-01-21 16:58:19 +09:00
Hide_D 47d5a07a81 conf에 return hint 추가
메시지 전송 준비
2018-01-21 06:08:39 +09:00
Hide_D 60e7ee5c38 메시지 테이블 추가 2018-01-21 04:27:08 +09:00
Hide_D f48500dd71 config 설정 방식을 함수를 이용하도록 변경 2018-01-21 03:52:45 +09:00
Hide_D 6b7f0f8a14 BLOCKBODY 의미 없음. 삭제. 2018-01-21 03:00:24 +09:00
Hide_D a4aa0ba476 array 참조 문제 마저 해결 2018-01-21 02:09:20 +09:00
Hide_D dd28eb768f 새로운 설정 파일을 위한 gitignore 확보
처리하지 않고 남겨둔 array 참조 해결

main.js 를 별도로 이동
2018-01-21 01:45:09 +09:00
Hide_D 3515fc637e login_process를 일단 변경
func_string의 Fill 계열 함수 마저 static으로 변경

전메, 갠메 파일 열기 실패시 에러 반환
main.php 파일에 jQuery + js 파일 열수 있도록
2018-01-20 15:19:51 +09:00
Hide_D 1848af9f09 log 파일이 없을 때는 빈 텍스트를 리턴하도록 2018-01-20 06:00:17 +09:00
Hide_D 3e629c5c54 stylesheet를 우선 기본값으로 보여주도록 수정 2018-01-20 05:43:50 +09:00
Hide_D a39a1e8612 아이디 생성 가능 2018-01-20 05:35:11 +09:00
Hide_D 9e3182bf2a phpmailer5 최신버전으로 갱신 2018-01-20 04:32:15 +09:00
Hide_D 0df2484b8e 임시 메일 테스트를 위해 @localhost 사용가능하도록
String static 함수 문제 해결
2018-01-20 04:23:46 +09:00
Hide_D 3aaf7c8328 set.php 변경 메일 전송 준비 2018-01-20 04:19:03 +09:00
Hide_D 9c27544fb7 참여 정보가 없을 시 에러가 발생하지 않도록 변경 2018-01-20 04:09:21 +09:00
Hide_D 8fa3af0fb8 warning 확인을 위해 가능한 모든 replace 태그를 무효화함
index.php에 대한 iframe 일부 삭제
2018-01-20 04:00:59 +09:00
revofpla 8bf5433300 [php5_debug] jQuery 3.2.1로 고고 2018-01-18 17:40:00 +09:00
revofpla f9fe123431 [php5_debug] 경매 따옴표 누락 추가 2018-01-18 00:41:42 +09:00
revofpla 7b77d8ced9 [php5_debug] 잡다 오류 수정 2018-01-18 00:33:36 +09:00
revofpla 711600403f [php5_debug] 명장일람 디스플레이 부분 수정 2018-01-17 23:48:12 +09:00
revofpla fb84886f94 [php5_debug] 사소한 오류들 수정 2018-01-17 23:17:03 +09:00
revofpla d99707c3d7 [php5_debug] 따옴표 누락, 변수 초기화 누락(특히 log와 alllog) 수정 2018-01-17 22:35:02 +09:00
5252 changed files with 709237 additions and 129113 deletions
+15
View File
@@ -0,0 +1,15 @@
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3,
"modules": false
}
]
],
"plugins": [
"lodash"
]
}
+42
View File
@@ -0,0 +1,42 @@
module.exports = {
root: true,
parser: "vue-eslint-parser",
"env": {
"browser": true,
"es2021": true
},
ignorePatterns: ['*.test.ts', '.eslintrc.cjs', 'webpack.config.cjs', '*.js'],
overrides: [{
files: ['*.ts', '*.tsx', "*.vue"],
}],
plugins: [
"@typescript-eslint"
],
extends: [
"eslint:recommended",
"plugin:vue/vue3-essential",
"plugin:@typescript-eslint/recommended"
],
parserOptions: {
"sourceType": "module",
"project": "./tsconfig.json",
"ecmaVersion": 2021,
"parser": "@typescript-eslint/parser",
extraFileExtensions: ['.vue']
},
rules: {
'@typescript-eslint/no-floating-promises': 'error',
},
settings: {
'import/resolver': {
alias: {
map: [
['@', './hwe/ts'],
['@util', './hwe/ts/util'],
['@scss', './hwe/scss'],
]
}
}
},
};
+68 -120
View File
@@ -1,120 +1,68 @@
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
.static_storage/
.media/
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# 체섭 ignore
logs/*.txt
d_log/*.txt
d_setting/set.php
set.php
config.php
sess_*
*/logs/*.txt
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
/node_modules
package-lock.json
# 체섭 ignore
*.log
logs/*.txt
d_log/*.txt
d_log/*.zip
sess_*
*/logs/*.txt
*/logs/*/*.txt
*/logs/preserved
err.txt
che/.htaccess
kwe/.htaccess
pwe/.htaccess
twe/.htaccess
hwe/.htaccess
d_shared
/d_pic
d_pic/*.jpg
d_pic/*.gif
d_pic/*.png
d_pic/*.webp
d_pic/uploaded_image
*/dist_misc/*
*/dist_js/*
*/dist_css/*
/dist_misc/*
/dist_js/*
/dist_css/*
d_setting/*.php
*/d_setting/*.php
*/d_setting/templates/*.php
!*.orig.php
*/data/file_cache
**/old/*
test.*
/che
/kwe
/pwe
/nya
/pya
/twe
phpinfo.php
vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/*
*.sqlite3
ingame/js/*
ingame/css/*
gateway/js/*
gateway/css/*
+2
View File
@@ -0,0 +1,2 @@
RedirectMatch 404 /\.git
RedirectMatch 404 /\.gitignore
+202
View File
@@ -0,0 +1,202 @@
<?php
/**
* This configuration will be read and overlaid on top of the
* default configuration. Command-line arguments will be applied
* after this file is read.
*/
return [
// Supported values: `'5.6'`, `'7.0'`, `'7.1'`, `'7.2'`, `'7.3'`,
// `'7.4'`, `'8.0'`, `'8.1'`, `null`.
// If this is set to `null`,
// then Phan assumes the PHP version which is closest to the minor version
// of the php executable used to execute Phan.
//
// Note that the **only** effect of choosing `'5.6'` is to infer
// that functions removed in php 7.0 exist.
// (See `backward_compatibility_checks` for additional options)
"target_php_version" => '8.0',
'backward_compatibility_checks ' => true,
'minimum_severity' => \Phan\Issue::SEVERITY_NORMAL,
'file_list' => [
'f_config/config.php',
'hwe/_119_b.php',
'hwe/_119.php',
'hwe/a_bestGeneral.php',
'hwe/_admin1.php',
'hwe/_admin1_submit.php',
'hwe/_admin2.php',
'hwe/_admin2_submit.php',
'hwe/_admin4.php',
'hwe/_admin4_submit.php',
'hwe/_admin5.php',
'hwe/_admin5_submit.php',
'hwe/_admin7.php',
'hwe/_admin8.php',
'hwe/_admin_force_rehall.php',
'hwe/a_emperior_detail.php',
'hwe/a_emperior.php',
'hwe/a_genList.php',
'hwe/a_hallOfFame.php',
'hwe/a_history.php',
'hwe/a_kingdomList.php',
'hwe/a_npcList.php',
'hwe/api.php',
'hwe/a_status.php',
'hwe/a_traffic.php',
'hwe/a_vote.php',
'hwe/battle_simulator.php',
'hwe/b_auction.php',
'hwe/b_battleCenter.php',
'hwe/b_betting.php',
'hwe/v_chiefCenter.php',
'hwe/b_currentCity.php',
'hwe/b_dipcenter.php',
'hwe/b_diplomacy.php',
'hwe/b_genList.php',
'hwe/b_myBossInfo.php',
'hwe/b_myCityInfo.php',
'hwe/b_myGenInfo.php',
'hwe/b_myKingdomInfo.php',
'hwe/b_myPage.php',
'hwe/v_processing.php',
'hwe/b_tournament.php',
'hwe/b_troop.php',
'hwe/c_auction.php',
'hwe/c_dipcenter.php',
'hwe/c_tournament.php',
'hwe/c_vote.php',
'hwe/func_auction.php',
'hwe/func_command.php',
'hwe/func_converter.php',
'hwe/func_gamerule.php',
'hwe/func_history.php',
'hwe/func_legacy.php',
'hwe/func_map.php',
'hwe/func_message.php',
'hwe/func.php',
'hwe/func_process.php',
'hwe/func_string.php',
'hwe/func_template.php',
'hwe/func_time_event.php',
'hwe/func_tournament.php',
'hwe/index.php',
'hwe/install_db.php',
'hwe/install.php',
'hwe/j_adjust_icon.php',
'hwe/j_autoreset.php',
'hwe/j_basic_info.php',
'hwe/j_betting.php',
'hwe/j_board_article_add.php',
'hwe/j_board_comment_add.php',
'hwe/j_board_get_articles.php',
'hwe/j_chief_turn.php',
'hwe/j_die_immediately.php',
'hwe/j_diplomacy_destroy_letter.php',
'hwe/j_diplomacy_get_letter.php',
'hwe/j_diplomacy_respond_letter.php',
'hwe/j_diplomacy_rollback_letter.php',
'hwe/j_diplomacy_send_letter.php',
'hwe/j_export_simulator_object.php',
'hwe/j_general_log_old.php',
'hwe/j_general_set_permission.php',
'hwe/j_get_basic_general_list.php',
'hwe/j_getChiefTurn.php',
'hwe/j_get_city_list.php',
'hwe/j_get_general_list.php',
'hwe/j_get_nation_general_list.php',
'hwe/j_get_select_npc_token.php',
'hwe/j_get_select_pool.php',
'hwe/j_image_upload.php',
'hwe/j_install_db.php',
'hwe/j_install.php',
'hwe/j_load_scenarios.php',
'hwe/j_map_history.php',
'hwe/j_map.php',
'hwe/j_map_recent.php',
'hwe/j_msg_contact_list.php',
'hwe/j_msg_decide_opt.php',
'hwe/j_msg_delete.php',
'hwe/j_msg_get_old.php',
'hwe/j_msg_get_recent.php',
'hwe/j_msg_submit.php',
'hwe/j_myBossInfo.php',
'hwe/j_raise_event.php',
'hwe/j_select_npc.php',
'hwe/j_select_picked_general.php',
'hwe/j_server_basic_info.php',
'hwe/j_set_chief_command.php',
'hwe/j_set_general_command.php',
'hwe/j_set_my_setting.php',
'hwe/j_set_npc_control.php',
'hwe/j_simulate_battle.php',
'hwe/j_troop.php',
'hwe/j_update_picked_general.php',
'hwe/j_vacation.php',
'hwe/lib.php',
'hwe/process_war.php',
'hwe/proc.php',
'hwe/readme.php',
'hwe/recent_map.php',
'hwe/select_general_from_pool.php',
'hwe/select_npc.php',
'hwe/t_diplomacy.php',
'hwe/v_board.php',
'hwe/v_inheritPoint.php',
'hwe/v_join.php',
'hwe/v_NPCControl.php',
],
// A list of directories that should be parsed for class and
// method information. After excluding the directories
// defined in exclude_analysis_directory_list, the remaining
// files will be statically analyzed for errors.
//
// Thus, both first-party and third-party code being used by
// your application should be included in this list.
'directory_list' => [
'hwe/d_setting',
'hwe/sammo',
'd_setting',
'src/sammo',
'src/kakao',
'vendor'
],
'exclude_file_regex' => '/.*\.orig\.php$/',
// A directory list that defines files that will be excluded
// from static analysis, but whose class and method
// information should be included.
//
// Generally, you'll want to include the directories for
// third-party code (such as "vendor/") in this list.
//
// n.b.: If you'd like to parse but not analyze 3rd
// party code, directories containing that code
// should be added to the `directory_list` as
// to `exclude_analysis_directory_list`.
"exclude_analysis_directory_list" => [
'vendor/'
],
'suppress_issue_types' => [
'PhanUnreferencedUseNormal',
'PhanTypeArraySuspiciousNullable',
],
// A list of plugin files to execute.
// See https://github.com/phan/phan/tree/master/.phan/plugins for even more.
// (Pass these in as relative paths.
// The 0.10.2 release will allow passing 'AlwaysReturnPlugin' if referring to a plugin that is bundled with Phan)
'plugins' => [
// checks if a function, closure or method unconditionally returns.
// Checks for syntactically unreachable statements in
// the global scope or function bodies.
'UnreachableCodePlugin',
'DollarDollarPlugin',
'DuplicateArrayKeyPlugin',
'PregRegexCheckerPlugin',
'PrintfCheckerPlugin',
],
];
+19 -3
View File
@@ -5,12 +5,28 @@
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/logs/*.txt": true,
"**/logs/**/*.txt": true,
"**/session/sess*":true,
"/che":true,
"/kwe":true,
"/pwe":true,
"/nya":true,
"/pya":true,
"/twe":true,
},
"search.exclude": {
"e_lib/*":true,
},
"vendor/*":true,
"/che":true,
"/kwe":true,
"/pwe":true,
"/nya":true,
"/pya":true,
"/twe":true,
},
"cSpell.words": [
"josa",
"sammo"
],
}
+23
View File
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>닫혀 있습니다.</title>
<script>
setTimeout(function(){
window.location.href = '../';
}, 5000);
</script>
<style>
html, body{
background-color:black;
color:yellow;
}
</style>
</head>
<body>
서버가 닫혀있습니다.<br>
잠시 뒤에 입구로 이동합니다.
</body>
</html>
+21
View File
@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2021 Hide_D, 62che
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+70
View File
@@ -0,0 +1,70 @@
# 삼국지 모의전투 HiDCHe
삼국지 모의전투 유기체서버를 기반으로 더욱 더 진화한 서버입니다.
## 요구사항
* Apache2 또는 nginx
* Apache2인 경우 `mpm_event` 권장
* PHP 8.0 이상
* `php-fpm` 권장
* php에서 curl, pdo-sqlite을 실행가능해야 합니다.
* mysqli, mysqlnd
* gd
* mbstring
* NodeJS 14 이상
* 내부의 git을 통해 upgrade 때 `webpack build` 용도로 필요합니다.
* MariaDB 10.2.1 이상
* 현재 MySQL은 지원하지 않습니다.
* `git`
* `curl`
Linux는 Ubuntu 18.04, 20.04, Windows는 WSL2를 사용한 환경에서 테스트되었습니다.
Docker를 이용한 설치도 제공하고 있습니다.
## Docker를 이용한 설치
https://storage.hided.net/gogs/devsam/docker 를 참고해 주세요.
## 수동 설치
본 게임은 <code>git</code>을 이용한 업그레이드 시스템을 구현하였으므로, <code>git</code>이 필요합니다.
또한 웹 서비스 데몬을 운영중인 사용자(일반적으로 <code>www-data</code>, <code>apache</code>)에게 디렉토리 권한이 주어져야합니다.
### 다운로드
웹 데몬 user가 <code>www-data</code>인 경우 다음과 같이 입력하여 최신 배포버전과 이미지 파일을 얻을 수 있습니다.
```
sudo -u www-data git clone https://storage.hided.net/gogs/devsam/core.git
sudo -u www-data git clone https://storage.hided.net/gogs/devsam/image.git
```
> 이미지는 hook/git_hook.php을 통해 동기화되며, 서버 설치 과정에 이미지 갱신 키를 지정하는 것으로 '훼' 서버 업데이트 시 동기화됩니다. 이미지 서버가 게임 서버와 별개여도 동작하나, php와 git을 지원해야합니다.
### 설치
이후 해당 경로를 웹 브라우저를 통해 접근하여 설치를 진행할 수 있습니다.
Database 수는 로그인 관리 서버 1개, 내부 서버 7개로, 총 8개의 Database가 필요합니다. 내부 설정을 고쳐서 서버 수를 늘리거나 줄일 경우 그에 맞는 Database 수가 필요합니다. 또한 Database마다 관리할 별도의 계정을 만드는 것을 추천합니다.
설치 이후에는 서버관리 페이지에서 **업데이트** 명령을 통해 원 클릭 업데이트가 가능합니다.
## 카카오로그인 연동
서버 설치 시 카카오 로그인 연동을 위한 API KEY를 입력받습니다.
만약 설치 이후 API KEY를 변경하고자 하는 경우 <code>d_setting/KakaoKey.php</code>에서 API키를 변경해야 합니다.
## 라이선스
본 게임을 수정하거나 재배포할 경우 다음 중 하나의 라이선스를 선택하여 적용할 수 있습니다.
* MIT License
* GPL 2.0 또는 이후
만약 별도의 라이선스를 적용하고자 할 경우 Hide_D에게 문의하여 주십시오.
-9
View File
@@ -1,9 +0,0 @@
<?php
if(!defined('ROOT')){
define('ROOT', '.');
}
require_once(ROOT.'/f_config/config.php');
require_once(ROOT.W.F_CONFIG.W.APP.PHP);
require_once(ROOT.W.F_FUNC.W.FUNC.PHP);
CustomHeader();
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace sammo;
require(__DIR__ . '/vendor/autoload.php');
if (!class_exists('\\sammo\\RootDB')) {
Json::dieWithReason('No DB');
}
APIHelper::launch(dirname(__FILE__));
+54
View File
@@ -0,0 +1,54 @@
{
"name":"sammo-hid/sammo",
"description":"삼국지 모의전투 HiDCHe",
"license": [
"MIT",
"GPL-2.0-or-later",
"proprietary"
],
"config": {
"platform": {
"php": "8.0"
}
},
"require": {
"brandonwamboldt/utilphp": "^1.1",
"sergeytsalkov/meekrodb": "^2.3",
"league/plates": "^3.3",
"guzzlehttp/guzzle": "^6.3",
"monolog/monolog": "^1.23",
"firephp/firephp-core": "^0.4.0",
"vlucas/valitron": "^1.4",
"php-extended/php-tail": "^2.1",
"pguardiario/phpuri": "^1.0",
"symfony/lock": "^4.1",
"ezyang/htmlpurifier": "^4.10",
"xemlock/htmlpurifier-html5": "^0.1.7",
"catfan/medoo": "^1.5",
"phan/phan": "*",
"erusev/parsedown-extra": "^0.8.1",
"nette/caching": "^3.0",
"illuminate/database": "^8.61",
"illuminate/events": "^8.61"
},
"autoload": {
"psr-4": {
"sammo\\": [
"src/sammo"
],
"kakao\\": [
"src/kakao"
]
},
"classmap": [
"d_setting/"
],
"exclude-from-classmap": [
"**/*.orig.php"
],
"files":[
"f_config/config.php"
]
}
}
Generated
+4180
View File
File diff suppressed because it is too large Load Diff
Executable
BIN
View File
Binary file not shown.
+230
View File
@@ -0,0 +1,230 @@
@charset "utf-8";
#btn_back1{
position:absolute;
right: 6px;
margin:6px;
height:40px;
}
#user_list_frame{
min-width:920px;
}
#user_list_frame td, #user_list_frame th{
text-align:center;
vertical-align: middle;
}
#user_list td button{
padding: 0.15rem 0.3rem;
line-height:1.1em;
}
p.small, td.small{
line-height:1.2em;
}
.hide_text{
display:none;
}
p.user_grade_0 {
display:block;
color:#E74C3C;
}
#EntranceMember_00 {
width: 1100px; height: 20px;
border: none;
z-index: 2;
}
#EntranceMember_0000 {
width: 1098px; height: 50px;
top: 0px; left: 0px;
}
#EntranceMember_0001 {
width: 100px; height: 30px;
top: 10px; left: 750px;
}
#EntranceMember_0006 {
width: 1098px; height: 20px;
top: 52px; left: 0px;
}
#EntranceMember_000600 {
width: 200px; height: 20px;
top: 0px; left: 0px;
border: 0px;
line-height: 20px;
}
#EntranceMember_0002 {
width: 1098px; height: 20px;
top: 74px; left: 0px;
}
#EntranceMember_000200 {
width: 70px; height: 20px;
}
#EntranceMember_000201 {
width: 50px; height: 20px;
}
#EntranceMember_0003 {
width: 1098px; height: 20px;
top: 96px; left: 0px;
}
#EntranceMember_0004 {
width: 1100px; height: 20px;
top: 118px; left: 0px;
border: none;
}
#EntranceMember_000400 {
width: 38px; height: 20px;
}
#EntranceMember_000401 {
width: 98px; height: 20px;
}
#EntranceMember_000402 {
width: 68px; height: 20px;
}
#EntranceMember_000403 {
width: 88px; height: 20px;
}
#EntranceMember_000404 {
width: 98px; height: 20px;
}
#EntranceMember_000405 {
width: 38px; height: 20px;
}
#EntranceMember_000406 {
width: 138px; height: 20px;
}
#EntranceMember_000407 {
width: 38px; height: 20px;
}
#EntranceMember_000408 {
width: 138px; height: 20px;
}
#EntranceMember_000409 {
width: 38px; height: 20px;
}
#EntranceMember_000410 {
width: 58px; height: 20px;
}
#EntranceMember_000411 {
width: 78px; height: 20px;
}
#EntranceMember_000412 {
width: 88px; height: 20px;
}
#EntranceMember_000413 {
width: 28px; height: 20px;
}
#EntranceMember_000414 {
width: 38px; height: 20px;
}
#EntranceMember_0005 {
width: 1100px; height: 20px;
top: 140px; left: 0px;
border: none;
}
#EntranceMember_000500 {
border: none;
}
.EntranceMember_00050000 {
width: 38px;
}
.EntranceMember_00050001 {
width: 98px;
}
.EntranceMember_00050002 {
width: 68px;
}
.EntranceMember_00050003 {
width: 88px;
}
.EntranceMember_00050004 {
width: 98px;
}
.EntranceMember_00050005 {
width: 38px;
}
.EntranceMember_00050006 {
width: 138px;
}
.EntranceMember_00050007 {
width: 38px;
}
.EntranceMember_00050008 {
width: 138px;
}
.EntranceMember_00050009 {
width: 38px;
}
.EntranceMember_00050010 {
width: 58px;
}
.EntranceMember_00050011 {
width: 78px;
}
.EntranceMember_00050012 {
width: 88px;
}
.EntranceMember_00050013 {
width: 28px;
}
.EntranceMember_00050014 {
width: 38px;
}
+35
View File
@@ -0,0 +1,35 @@
@charset "utf-8";
#admin_userlist{
margin-top:10px;
}
#server_admin_table{
width:100%;
margin-top:30px;
margin-bottom:30px;
}
#server_admin_table input{
padding:2px 3px;
}
#admin_userlist .center_ordered_items {
padding:10px;
}
#notice_edit{
vertical-align: top;
display:inline-block;
margin:0;
padding:0;
height:4em;
background:black;
color:white;
}
#notice_change_btn{
vertical-align: top;
display:inline-block;
height:4em;
}
+235
View File
@@ -0,0 +1,235 @@
@charset "utf-8";
body {
color: white;
background-color: black;
font-family: 'Pretendard';
}
table {
border: solid 1px;
border-spacing: 0px;
border-collapse: separate;
border-top-color: gray;
border-left-color: gray;
border-right-color: black;
border-bottom-color: black;
padding: 0px;
font-size: 14px;
word-break: break-all;
text-align: center;
}
th,
td {
border: solid 1px;
border-spacing: 0px;
border-collapse: separate;
border-top-color: gray;
border-left-color: gray;
border-right-color: black;
border-bottom-color: black;
padding: 0px;
font-size: 14px;
word-break: break-all;
text-align: center;
}
a.just_link {
text-decoration: none;
}
.with_border {
margin: 0;
border: solid 1px;
border-spacing: 0px;
border-collapse: separate;
border-top-color: gray;
border-left-color: gray;
border-right-color: black;
border-bottom-color: black;
}
.section_title {
height: 50px;
line-height: 50px;
font-size: 30px;
font-weight: bold;
text-align: center;
color: white;
padding: 0;
}
.legacy_layout div {
border: solid 1px;
border-spacing: 0px;
border-collapse: separate;
border-top-color: gray;
border-left-color: gray;
border-right-color: black;
border-bottom-color: black;
padding: 0px;
font-size: 14px;
word-break: break-all;
text-align: center;
}
.obj_fill {
display: block;
width: 100%;
height: 100%;
}
button.with_skin {
padding: 0 4px;
background-color: black;
color: white;
font-size: 14px;
}
button.with_skin:disabled {
background-color: #333333;
}
input.with_skin {
background-color: black;
color: white;
font-size: 14px;
}
input.with_skin:disabled {
background-color: #333333;
}
.font0 {
font-size: 10px;
}
.font1 {
font-size: 14px;
}
.font2 {
font-size: 15px;
}
.font3 {
font-size: 20px;
}
.font4 {
font-size: 30px;
}
.font5 {
font-size: 50px;
}
caption.section_title {
caption-side: top;
}
.samButton {
float: left;
display: block;
padding: 0;
margin: 0;
text-decoration: none;
position: relative;
}
a.samButton.disabled {
pointer-events: none;
cursor: default;
}
.samButtonOuter {
display: table;
border: outset 2px white;
box-sizing: border-box;
font-weight: bold;
padding: 1px 6px;
width: 125px;
height: 30px;
background-color: #000000;
color: #ffffff;
}
.samButtonOuter:active {
border: inset 2px white;
}
.samButtonInner {
display: table-cell;
vertical-align: middle;
width: 100%;
margin: 0 auto;
text-align: center;
user-select: none;
}
.samToolbarButton>.samButtonOuter {
width: 125px;
height: 30px;
background-color: #225500;
color: white;
}
.samToolbarButton2>.samButtonOuter {
width: 125px;
height: 30px;
background-color: #225500;
color: magenta;
}
.samCommandButton>.samButtonOuter {
width: 111px;
height: 30px;
}
.samCommandButton.disabled>.samButtonOuter {
background-color: transparent !important;
color: gray !important;
border-color: transparent !important;
}
.samCommandButton.disabled>.samButtonOuter>.samButtonInner::before {
content: '【'
}
.samCommandButton.disabled>.samButtonOuter>.samButtonInner::after {
content: '】'
}
.tooltip_copyable_info .tooltiptext {
display: inline;
color: rgba(0, 0, 0, 0);
font-size: 0;
}
.tooltiptext {
display: none;
}
.hidden_but_copyable {
color: rgba(0, 0, 0, 0);
font-size: 0;
}
.vertical_flex {
height: 100%;
display: flex;
align-content: center;
flex-direction: column;
align-items: stretch;
}
.vertical_flex .item {
display: block;
flex-grow: 1;
}
.fill_box {
display: block;
width: 100%;
height: 100%;
}
+156
View File
@@ -0,0 +1,156 @@
@charset "utf-8";
body {
line-height: 1.3;
}
#server_notice {
margin: 10px 0;
border: none;
text-align: center;
}
#server_list_container {
width: 800px;
position: absolute;
left: 50%;
margin-left: -400px;
}
#server_list_table {
width: 100%;
}
#server_list tr {
height: 66px;
}
.ignore_border {
border: 0;
margin: 0;
padding: 0;
}
#user_info {
margin-top: 20px;
width: 800px;
height: 130px;
}
#user_info button {
width: 200px;
height: 50px;
margin: 10px 50px;
}
.center_ordered_items {
text-align: center;
}
.Entrance_ServerList {
width: 800px;
height: 64px;
border: none;
float: left;
}
.Entrance_ServerListServer {
width: 98px;
height: 64px;
float: left;
}
.Entrance_ServerListDown {
width: 698px;
height: 64px;
float: left;
}
.Entrance_ServerListInfo {
width: 398px;
height: 64px;
float: left;
}
.Entrance_ServerListBlock {
width: 298px;
height: 64px;
float: left;
line-height: 64px;
}
.Entrance_ServerListCharacter {
width: 64px;
height: 64px;
float: left;
}
.Entrance_ServerListName {
width: 112px;
height: 64px;
float: left;
line-height: 64px;
}
.Entrance_ServerListSelect {
width: 120px;
height: 32px;
float: left;
}
#Entrance_000003 {
width: 798px;
height: 155px;
text-align: left;
}
.Entrance_Alert {
color: red;
font-size: 15px;
font-weight: bold;
}
.Entrance_Che {
color: white;
font-size: 15px;
font-weight: bold;
}
.Entrance_Kwe {
color: yellow;
font-size: 15px;
font-weight: bold;
}
.Entrance_Pwe {
color: orange;
font-size: 15px;
font-weight: bold;
}
.Entrance_Twe {
color: magenta;
font-size: 15px;
font-weight: bold;
}
.Entrance_Nya {
color: #e67e22;
font-size: 15px;
font-weight: bold;
}
.Entrance_Pya {
color: #9b59b6;
font-size: 15px;
font-weight: bold;
}
.Entrance_Hwe {
color: red;
font-size: 15px;
font-weight: bold;
}
.BtnPlate {
height: inherit;
}
+67
View File
@@ -0,0 +1,67 @@
body, html{
height: 100%;
background-repeat: no-repeat;
}
.main{
margin-top: 70px;
}
h1.title {
font-size: 50px;
font-family: 'Pretendard', 'Apple SD Gothic Neo', 'Noto Sans KR', 'Malgun Gothic';
font-weight: 400;
}
hr{
width: 10%;
/*color: #fff;*/
}
.form-group{
margin-bottom: 15px;
}
label{
margin-bottom: 15px;
}
input,
input::-webkit-input-placeholder {
font-size: 11px;
padding-top: 3px;
}
.main-login{
/*background-color: #fff;*/
/* shadows and rounded borders */
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
-moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
}
.main-center{
margin-top: 30px;
margin: 0 auto;
max-width: 330px;
padding: 40px 40px;
}
.login-button{
margin-top: 5px;
}
.login-register{
font-size: 11px;
text-align: center;
}
.terms{
max-height: 200px; overflow: auto;
}
+67
View File
@@ -0,0 +1,67 @@
body, html{
height: 100%;
background-repeat: no-repeat;
}
.main{
margin-top: 70px;
}
h1.title {
font-size: 50px;
font-family: 'Pretendard', 'Apple SD Gothic Neo', 'Noto Sans KR', 'Malgun Gothic';
font-weight: 400;
}
hr{
width: 10%;
/*color: #fff;*/
}
.form-group{
margin-bottom: 15px;
}
label{
margin-bottom: 15px;
}
input,
input::-webkit-input-placeholder {
font-size: 11px;
padding-top: 3px;
}
.main-login{
/*background-color: #fff;*/
/* shadows and rounded borders */
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
-moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
}
.main-center{
margin-top: 30px;
margin: 0 auto;
max-width: 330px;
padding: 40px 40px;
}
.login-button{
margin-top: 5px;
}
.login-register{
font-size: 11px;
text-align: center;
}
.terms{
max-height: 200px; overflow: auto;
}
+86
View File
@@ -0,0 +1,86 @@
@charset "utf-8";
#user_info_container{
width:550px;
position:absolute;
left:50%;
margin-left:-250px;
}
#user_info_table{
width:100%;
margin-top:30px;
}
#user_info_table th{
padding:5px;
}
#btn_back1{
position:absolute;
right: 6px;
margin:6px;
height:40px;
line-height:40px;
}
#btn_delete_me{
bottom:0;
left:0;
margin:0 1px;
position:absolute;
width:100%;
}
#change_pw{
width:100%;
}
#image_upload_filename{
position:absolute;
height:20px;
left:10px;
width:130px;
top:12px;
}
#image_upload_fake_btn{
top:12px;
height:22px;
right:10px;
position:absolute;
}
#image_upload{
opacity: 0;
position:absolute;
top:12px;
left:0;
height:20px;
width:100%;
}
#slot_new_icon{
visibility: hidden;
}
#btn_image_submit{
position:absolute;
bottom:0;
left:0;
width:50%;
}
#btn_remove_icon{
position:absolute;
bottom:0;
right:0;
width:50%;
}
#third_use_disallow{
display:none;
margin-left:10px;
width:40px;
}
-18
View File
@@ -1,18 +0,0 @@
DB Connect() error
DB Connect() error: sammo_che
DB Connect() error: _che
DB Connect() error: sammo\_che
DB Connect() error: sammo\_che
DB Connect() error: sammo\_che
DB Connect() error: sammo\_che
DB Connect() error: test
DB Connect() error: test
DB Connect() error: test
DB Connect() error: test
DB Connect() error: test
DB Connect() error: test
DB Connect() error: test
DB Connect() error: test
DB Connect() error: test
DB Connect() error: test
이미 설치되어 있습니다. 재설치하려면 설정 파일을 지우세요.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

-9
View File
@@ -1,9 +0,0 @@
<?php
if(!defined('ROOT')){
define('ROOT', '..');
}
require_once(ROOT.'/f_config/config.php');
require_once(ROOT.W.F_CONFIG.W.APP.PHP);
require_once(ROOT.W.F_FUNC.W.FUNC.PHP);
CustomHeader();
-11
View File
@@ -1,11 +0,0 @@
<?php /*
localhost
sam_dev
letmein
sammo
smtp.gmail.com
465
aser
ewrwer
@gmail.com
*/
-15
View File
@@ -1,15 +0,0 @@
#!/bin/bash
SAM=che
SRC=~/svn/trunk/sam/che/
TAR=~/www/sam/${SAM}/
ALT=~/www/sam/${SAM}/
if [ -e $TAR ]
then
echo The server is closed. Location: $TAR
rsync -av --delete --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $TAR
else
echo The server is on service. Location: $ALT
rsync -av --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $ALT
fi
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
SAM=hwe
SRC=~/svn/branches/che_devel/
TAR=~/www/sam/${SAM}/
ALT=~/www/sam/${SAM}/
if [ -e $TAR ]
then
echo The server is closed. Location: $TAR
rsync -avu --delete --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $TAR
else
echo The server is on service. Location: $ALT
rsync -avu --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $ALT
fi
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
SAM=kwe
SRC=~/svn/branches/che_devel/
TAR=~/www/sam/${SAM}/
ALT=~/www/sam/${SAM}/
if [ -e $TAR ]
then
echo The server is closed. Location: $TAR
rsync -avu --delete --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $TAR
else
echo The server is on service. Location: $ALT
rsync -avu --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $ALT
fi
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
SAM=pwe
SRC=~/svn/branches/che_devel/
TAR=~/www/sam/${SAM}/
ALT=~/www/sam/${SAM}/
if [ -e $TAR ]
then
echo The server is closed. Location: $TAR
rsync -avu --delete --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $TAR
else
echo The server is on service. Location: $ALT
rsync -avu --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $ALT
fi
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
SAM=twe
SRC=~/svn/branches/che_devel/
TAR=~/www/sam/${SAM}/
ALT=~/www/sam/${SAM}/
if [ -e $TAR ]
then
echo The server is closed. Location: $TAR
rsync -avu --delete --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $TAR
else
echo The server is on service. Location: $ALT
rsync -avu --exclude=.* --exclude=logs --exclude=data --exclude=d_setting $SRC $ALT
fi
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
SRC=~/svn/trunk/sam/
TAR=~/www/sam/
echo Location: $SRC '<->' $TAR
rsync -avu --delete --exclude=.* --exclude=deploy* --exclude=d_* --exclude=e_* --exclude=che* --exclude=kwe* --exclude=pwe* --exclude=twe* --exclude=hwe* ~/svn/trunk/sam/ $TAR
-4
View File
@@ -1,4 +0,0 @@
Andreas Fernandez <a.fernandez@scripting-base.de> <andreas.fernandez@aspedia.de>
Mike Benoit <mikeb@timetrex.com> MikeB <ipso@snappymail.ca>
Mike Benoit <mikeb@timetrex.com> mike.benoit
-496
View File
@@ -1,496 +0,0 @@
ADOdb License
=============
ADOdb is dual licensed under BSD and LGPL.
In plain English, you do not need to distribute your application in source code form,
nor do you need to distribute ADOdb source code, provided you follow the rest of
terms of the BSD license.
For more info about ADOdb, visit http://adodb.sourceforge.net/
BSD 3-Clause License
--------------------
(c) 2000-2013 John Lim (jlim@natsoft.com)
(c) 2014 Damien Regad, Mark Newnham and the ADOdb community
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
### DISCLAIMER
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
GNU LESSER GENERAL PUBLIC LICENSE
---------------------------------
_Version 2.1, February 1999_
_Copyright © 1991, 1999 Free Software Foundation, Inc._
_51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA_
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
_This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1._
### Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: **(1)** we copyright the
library, and **(2)** we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the “Lesser” General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
“work based on the library” and a “work that uses the library”. The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
**0.** This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called “this License”).
Each licensee is addressed as “you”.
A “library” means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The “Library”, below, refers to any such software library or work
which has been distributed under these terms. A “work based on the
Library” means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term “modification”.)
“Source code” for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
**1.** You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
**2.** You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
* **a)** The modified work must itself be a software library.
* **b)** You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
* **c)** You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
* **d)** If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
**3.** You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
**4.** You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
**5.** A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a “work that uses the Library”. Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a “work that uses the Library” with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a “work that uses the
library”. The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a “work that uses the Library” uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
**6.** As an exception to the Sections above, you may also combine or
link a “work that uses the Library” with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
* **a)** Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable “work that
uses the Library”, as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
* **b)** Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
* **c)** Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
* **d)** If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
* **e)** Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the “work that uses the
Library” must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
**7.** You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
* **a)** Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
* **b)** Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
**8.** You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
**9.** You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
**10.** Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
**11.** If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
**12.** If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
**13.** The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
“any later version”, you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
**14.** If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
### NO WARRANTY
**15.** BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY “AS IS” WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
**16.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
_END OF TERMS AND CONDITIONS_
-109
View File
@@ -1,109 +0,0 @@
ADOdb Library for PHP5
======================
[![Join chat on Gitter](https://img.shields.io/gitter/room/form-data/form-data.svg)](https://gitter.im/adodb/adodb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Download ADOdb](https://img.shields.io/sourceforge/dm/adodb.svg)](https://sourceforge.net/projects/adodb/files/latest/download)
(c) 2000-2013 John Lim (jlim@natsoft.com)
(c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both [BSD 3-Clause](https://github.com/ADOdb/ADOdb/blob/master/LICENSE.md#bsd-3-clause-license)
and [GNU Lesser GPL library 2.1](https://github.com/ADOdb/ADOdb/blob/master/LICENSE.md#gnu-lesser-general-public-license)
licenses.
This means you can use it in proprietary products;
see [License](https://github.com/ADOdb/ADOdb/blob/master/LICENSE.md) for details.
Home page: http://adodb.org/
> **WARNING: known issue with Associative Fetch Mode in ADOdb v5.19
-- PLEASE UPGRADE TO v5.20 !**
> When fetching data in Associative mode (i.e. when `$ADODB_FETCH_MODE` is
> set to *ADODB_FETCH_ASSOC*), recordsets do not return any data (empty strings)
> when using some database drivers. The problem has been reported on MSSQL,
> Interbase and Foxpro, but possibly affects other drivers as well; all drivers
> derived from the above are also impacted.
> For further details, please refer to [Issue #20](https://github.com/ADOdb/ADOdb/issues/20).
Introduction
============
PHP's database access functions are not standardized. This creates a
need for a database class library to hide the differences between the
different databases (encapsulate the differences) so we can easily
switch databases.
The library currently supports MySQL, Interbase, Sybase, PostgreSQL, Oracle,
Microsoft SQL server, Foxpro ODBC, Access ODBC, Informix, DB2,
Sybase SQL Anywhere, generic ODBC and Microsoft's ADO.
We hope more people will contribute drivers to support other databases.
Installation
============
Unpack all the files into a directory accessible by your web server.
To test, try modifying some of the tutorial examples.
Make sure you customize the connection settings correctly.
You can debug using:
``` php
<?php
include('adodb/adodb.inc.php');
$db = ADONewConnection($driver); # eg. 'mysql' or 'oci8'
$db->debug = true;
$db->Connect($server, $user, $password, $database);
$rs = $db->Execute('select * from some_small_table');
print "<pre>";
print_r($rs->GetRows());
print "</pre>";
```
Documentation and Examples
==========================
Refer to the [ADOdb website](http://adodb.org/) for library documentation and examples. The documentation can also be [downloaded for offline viewing](https://sourceforge.net/projects/adodb/files/Documentation/).
- [Main documentation](http://adodb.org/dokuwiki/doku.php?id=v5:userguide:userguide_index): Query, update and insert records using a portable API.
- [Data dictionary](http://adodb.org/dokuwiki/doku.php?id=v5:dictionary:dictionary_index) describes how to create database tables and indexes in a portable manner.
- [Database performance monitoring](http://adodb.org/dokuwiki/doku.php?id=v5:performance:performance_index) allows you to perform health checks, tune and monitor your database.
- [Database-backed sessions](http://adodb.org/dokuwiki/doku.php?id=v5:session:session_index).
There is also a [tutorial](http://adodb.org/dokuwiki/doku.php?id=v5:userguide:mysql_tutorial) that contrasts ADOdb code with PHP native MySQL code.
Files
=====
- `adodb.inc.php` is the library's main file. You only need to include this file.
- `adodb-*.inc.php` are the database specific driver code.
- `adodb-session.php` is the PHP4 session handling code.
- `test.php` contains a list of test commands to exercise the class library.
- `testdatabases.inc.php` contains the list of databases to apply the tests on.
- `Benchmark.php` is a simple benchmark to test the throughput of a SELECT
statement for databases described in testdatabases.inc.php. The benchmark
tables are created in test.php.
Support
=======
To discuss with the ADOdb development team and users, connect to our
[Gitter chatroom](https://gitter.im/adodb/adodb) using your Github credentials.
Please report bugs, issues and feature requests on Github:
https://github.com/ADOdb/ADOdb/issues
You may also find legacy issues in
- the old [ADOdb forums](http://phplens.com/lens/lensforum/topics.php?id=4) on phplens.com
- the [SourceForge tickets section](http://sourceforge.net/p/adodb/_list/tickets)
However, please note that they are not actively monitored and should
only be used as reference.
-1142
View File
@@ -1,1142 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Latest version is available at http://adodb.sourceforge.net
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Active Record implementation. Superset of Zend Framework's.
Version 0.92
See http://www-128.ibm.com/developerworks/java/library/j-cb03076/?ca=dgr-lnxw01ActiveRecord
for info on Ruby on Rails Active Record implementation
*/
global $_ADODB_ACTIVE_DBS;
global $ADODB_ACTIVE_CACHESECS; // set to true to enable caching of metadata such as field info
global $ACTIVE_RECORD_SAFETY; // set to false to disable safety checks
global $ADODB_ACTIVE_DEFVALS; // use default values of table definition when creating new active record.
// array of ADODB_Active_DB's, indexed by ADODB_Active_Record->_dbat
$_ADODB_ACTIVE_DBS = array();
$ACTIVE_RECORD_SAFETY = true;
$ADODB_ACTIVE_DEFVALS = false;
$ADODB_ACTIVE_CACHESECS = 0;
class ADODB_Active_DB {
var $db; // ADOConnection
var $tables; // assoc array of ADODB_Active_Table objects, indexed by tablename
}
class ADODB_Active_Table {
var $name; // table name
var $flds; // assoc array of adofieldobjs, indexed by fieldname
var $keys; // assoc array of primary keys, indexed by fieldname
var $_created; // only used when stored as a cached file
var $_belongsTo = array();
var $_hasMany = array();
}
// $db = database connection
// $index = name of index - can be associative, for an example see
// http://phplens.com/lens/lensforum/msgs.php?id=17790
// returns index into $_ADODB_ACTIVE_DBS
function ADODB_SetDatabaseAdapter(&$db, $index=false)
{
global $_ADODB_ACTIVE_DBS;
foreach($_ADODB_ACTIVE_DBS as $k => $d) {
if (PHP_VERSION >= 5) {
if ($d->db === $db) {
return $k;
}
} else {
if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database) {
return $k;
}
}
}
$obj = new ADODB_Active_DB();
$obj->db = $db;
$obj->tables = array();
if ($index == false) {
$index = sizeof($_ADODB_ACTIVE_DBS);
}
$_ADODB_ACTIVE_DBS[$index] = $obj;
return sizeof($_ADODB_ACTIVE_DBS)-1;
}
class ADODB_Active_Record {
static $_changeNames = true; // dynamically pluralize table names
static $_quoteNames = false;
static $_foreignSuffix = '_id'; //
var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat]
var $_table; // tablename, if set in class definition then use it as table name
var $_tableat; // associative index pointing to ADODB_Active_Table, eg $ADODB_Active_DBS[_dbat]->tables[$this->_tableat]
var $_where; // where clause set in Load()
var $_saved = false; // indicates whether data is already inserted.
var $_lasterr = false; // last error message
var $_original = false; // the original values loaded or inserted, refreshed on update
var $foreignName; // CFR: class name when in a relationship
var $lockMode = ' for update '; // you might want to change to
static function UseDefaultValues($bool=null)
{
global $ADODB_ACTIVE_DEFVALS;
if (isset($bool)) {
$ADODB_ACTIVE_DEFVALS = $bool;
}
return $ADODB_ACTIVE_DEFVALS;
}
// should be static
static function SetDatabaseAdapter(&$db, $index=false)
{
return ADODB_SetDatabaseAdapter($db, $index);
}
public function __set($name, $value)
{
$name = str_replace(' ', '_', $name);
$this->$name = $value;
}
// php5 constructor
function __construct($table = false, $pkeyarr=false, $db=false)
{
global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS;
if ($db == false && is_object($pkeyarr)) {
$db = $pkeyarr;
$pkeyarr = false;
}
if (!$table) {
if (!empty($this->_table)) {
$table = $this->_table;
}
else $table = $this->_pluralize(get_class($this));
}
$this->foreignName = strtolower(get_class($this)); // CFR: default foreign name
if ($db) {
$this->_dbat = ADODB_Active_Record::SetDatabaseAdapter($db);
} else if (!isset($this->_dbat)) {
if (sizeof($_ADODB_ACTIVE_DBS) == 0) {
$this->Error(
"No database connection set; use ADOdb_Active_Record::SetDatabaseAdapter(\$db)",
'ADODB_Active_Record::__constructor'
);
}
end($_ADODB_ACTIVE_DBS);
$this->_dbat = key($_ADODB_ACTIVE_DBS);
}
$this->_table = $table;
$this->_tableat = $table; # reserved for setting the assoc value to a non-table name, eg. the sql string in future
$this->UpdateActiveTable($pkeyarr);
}
function __wakeup()
{
$class = get_class($this);
new $class;
}
function _pluralize($table)
{
if (!ADODB_Active_Record::$_changeNames) {
return $table;
}
$ut = strtoupper($table);
$len = strlen($table);
$lastc = $ut[$len-1];
$lastc2 = substr($ut,$len-2);
switch ($lastc) {
case 'S':
return $table.'es';
case 'Y':
return substr($table,0,$len-1).'ies';
case 'X':
return $table.'es';
case 'H':
if ($lastc2 == 'CH' || $lastc2 == 'SH') {
return $table.'es';
}
default:
return $table.'s';
}
}
// CFR Lamest singular inflector ever - @todo Make it real!
// Note: There is an assumption here...and it is that the argument's length >= 4
function _singularize($tables)
{
if (!ADODB_Active_Record::$_changeNames) {
return $table;
}
$ut = strtoupper($tables);
$len = strlen($tables);
if($ut[$len-1] != 'S') {
return $tables; // I know...forget oxen
}
if($ut[$len-2] != 'E') {
return substr($tables, 0, $len-1);
}
switch($ut[$len-3]) {
case 'S':
case 'X':
return substr($tables, 0, $len-2);
case 'I':
return substr($tables, 0, $len-3) . 'y';
case 'H';
if($ut[$len-4] == 'C' || $ut[$len-4] == 'S') {
return substr($tables, 0, $len-2);
}
default:
return substr($tables, 0, $len-1); // ?
}
}
function hasMany($foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
{
$ar = new $foreignClass($foreignRef);
$ar->foreignName = $foreignRef;
$ar->UpdateActiveTable();
$ar->foreignKey = ($foreignKey) ? $foreignKey : $foreignRef.ADODB_Active_Record::$_foreignSuffix;
$table =& $this->TableInfo();
$table->_hasMany[$foreignRef] = $ar;
# $this->$foreignRef = $this->_hasMany[$foreignRef]; // WATCHME Removed assignment by ref. to please __get()
}
// use when you don't want ADOdb to auto-pluralize tablename
static function TableHasMany($table, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
{
$ar = new ADODB_Active_Record($table);
$ar->hasMany($foreignRef, $foreignKey, $foreignClass);
}
// use when you don't want ADOdb to auto-pluralize tablename
static function TableKeyHasMany($table, $tablePKey, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
{
if (!is_array($tablePKey)) {
$tablePKey = array($tablePKey);
}
$ar = new ADODB_Active_Record($table,$tablePKey);
$ar->hasMany($foreignRef, $foreignKey, $foreignClass);
}
// use when you want ADOdb to auto-pluralize tablename for you. Note that the class must already be defined.
// e.g. class Person will generate relationship for table Persons
static function ClassHasMany($parentclass, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
{
$ar = new $parentclass();
$ar->hasMany($foreignRef, $foreignKey, $foreignClass);
}
function belongsTo($foreignRef,$foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
global $inflector;
$ar = new $parentClass($this->_pluralize($foreignRef));
$ar->foreignName = $foreignRef;
$ar->parentKey = $parentKey;
$ar->UpdateActiveTable();
$ar->foreignKey = ($foreignKey) ? $foreignKey : $foreignRef.ADODB_Active_Record::$_foreignSuffix;
$table =& $this->TableInfo();
$table->_belongsTo[$foreignRef] = $ar;
# $this->$foreignRef = $this->_belongsTo[$foreignRef];
}
static function ClassBelongsTo($class, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
$ar = new $class();
$ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
}
static function TableBelongsTo($table, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
$ar = new ADOdb_Active_Record($table);
$ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
}
static function TableKeyBelongsTo($table, $tablePKey, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
if (!is_array($tablePKey)) {
$tablePKey = array($tablePKey);
}
$ar = new ADOdb_Active_Record($table, $tablePKey);
$ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
}
/**
* __get Access properties - used for lazy loading
*
* @param mixed $name
* @access protected
* @return mixed
*/
function __get($name)
{
return $this->LoadRelations($name, '', -1, -1);
}
/**
* @param string $name
* @param string $whereOrderBy : eg. ' AND field1 = value ORDER BY field2'
* @param offset
* @param limit
* @return mixed
*/
function LoadRelations($name, $whereOrderBy='', $offset=-1,$limit=-1)
{
$extras = array();
$table = $this->TableInfo();
if ($limit >= 0) {
$extras['limit'] = $limit;
}
if ($offset >= 0) {
$extras['offset'] = $offset;
}
if (strlen($whereOrderBy)) {
if (!preg_match('/^[ \n\r]*AND/i', $whereOrderBy)) {
if (!preg_match('/^[ \n\r]*ORDER[ \n\r]/i', $whereOrderBy)) {
$whereOrderBy = 'AND ' . $whereOrderBy;
}
}
}
if(!empty($table->_belongsTo[$name])) {
$obj = $table->_belongsTo[$name];
$columnName = $obj->foreignKey;
if(empty($this->$columnName)) {
$this->$name = null;
}
else {
if ($obj->parentKey) {
$key = $obj->parentKey;
}
else {
$key = reset($table->keys);
}
$arrayOfOne = $obj->Find($key.'='.$this->$columnName.' '.$whereOrderBy,false,false,$extras);
if ($arrayOfOne) {
$this->$name = $arrayOfOne[0];
return $arrayOfOne[0];
}
}
}
if(!empty($table->_hasMany[$name])) {
$obj = $table->_hasMany[$name];
$key = reset($table->keys);
$id = @$this->$key;
if (!is_numeric($id)) {
$db = $this->DB();
$id = $db->qstr($id);
}
$objs = $obj->Find($obj->foreignKey.'='.$id. ' '.$whereOrderBy,false,false,$extras);
if (!$objs) {
$objs = array();
}
$this->$name = $objs;
return $objs;
}
return array();
}
//////////////////////////////////
// update metadata
function UpdateActiveTable($pkeys=false,$forceUpdate=false)
{
global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS , $ADODB_CACHE_DIR, $ADODB_ACTIVE_CACHESECS;
global $ADODB_ACTIVE_DEFVALS,$ADODB_FETCH_MODE;
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$table = $this->_table;
$tables = $activedb->tables;
$tableat = $this->_tableat;
if (!$forceUpdate && !empty($tables[$tableat])) {
$acttab = $tables[$tableat];
foreach($acttab->flds as $name => $fld) {
if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) {
$this->$name = $fld->default_value;
}
else {
$this->$name = null;
}
}
return;
}
$db = $activedb->db;
$fname = $ADODB_CACHE_DIR . '/adodb_' . $db->databaseType . '_active_'. $table . '.cache';
if (!$forceUpdate && $ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR && file_exists($fname)) {
$fp = fopen($fname,'r');
@flock($fp, LOCK_SH);
$acttab = unserialize(fread($fp,100000));
fclose($fp);
if ($acttab->_created + $ADODB_ACTIVE_CACHESECS - (abs(rand()) % 16) > time()) {
// abs(rand()) randomizes deletion, reducing contention to delete/refresh file
// ideally, you should cache at least 32 secs
foreach($acttab->flds as $name => $fld) {
if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) {
$this->$name = $fld->default_value;
}
else {
$this->$name = null;
}
}
$activedb->tables[$table] = $acttab;
//if ($db->debug) ADOConnection::outp("Reading cached active record file: $fname");
return;
} else if ($db->debug) {
ADOConnection::outp("Refreshing cached active record file: $fname");
}
}
$activetab = new ADODB_Active_Table();
$activetab->name = $table;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($db->fetchMode !== false) {
$savem = $db->SetFetchMode(false);
}
$cols = $db->MetaColumns($table);
if (isset($savem)) {
$db->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!$cols) {
$this->Error("Invalid table name: $table",'UpdateActiveTable');
return false;
}
$fld = reset($cols);
if (!$pkeys) {
if (isset($fld->primary_key)) {
$pkeys = array();
foreach($cols as $name => $fld) {
if (!empty($fld->primary_key)) {
$pkeys[] = $name;
}
}
} else
$pkeys = $this->GetPrimaryKeys($db, $table);
}
if (empty($pkeys)) {
$this->Error("No primary key found for table $table",'UpdateActiveTable');
return false;
}
$attr = array();
$keys = array();
switch($ADODB_ASSOC_CASE) {
case 0:
foreach($cols as $name => $fldobj) {
$name = strtolower($name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
$this->$name = $fldobj->default_value;
}
else {
$this->$name = null;
}
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[strtolower($name)] = strtolower($name);
}
break;
case 1:
foreach($cols as $name => $fldobj) {
$name = strtoupper($name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
$this->$name = $fldobj->default_value;
}
else {
$this->$name = null;
}
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[strtoupper($name)] = strtoupper($name);
}
break;
default:
foreach($cols as $name => $fldobj) {
$name = ($fldobj->name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
$this->$name = $fldobj->default_value;
}
else {
$this->$name = null;
}
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[$name] = $cols[$name]->name;
}
break;
}
$activetab->keys = $keys;
$activetab->flds = $attr;
if ($ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR) {
$activetab->_created = time();
$s = serialize($activetab);
if (!function_exists('adodb_write_file')) {
include(ADODB_DIR.'/adodb-csvlib.inc.php');
}
adodb_write_file($fname,$s);
}
if (isset($activedb->tables[$table])) {
$oldtab = $activedb->tables[$table];
if ($oldtab) {
$activetab->_belongsTo = $oldtab->_belongsTo;
$activetab->_hasMany = $oldtab->_hasMany;
}
}
$activedb->tables[$table] = $activetab;
}
function GetPrimaryKeys(&$db, $table)
{
return $db->MetaPrimaryKeys($table);
}
// error handler for both PHP4+5.
function Error($err,$fn)
{
global $_ADODB_ACTIVE_DBS;
$fn = get_class($this).'::'.$fn;
$this->_lasterr = $fn.': '.$err;
if ($this->_dbat < 0) {
$db = false;
}
else {
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$db = $activedb->db;
}
if (function_exists('adodb_throw')) {
if (!$db) {
adodb_throw('ADOdb_Active_Record', $fn, -1, $err, 0, 0, false);
}
else {
adodb_throw($db->databaseType, $fn, -1, $err, 0, 0, $db);
}
} else {
if (!$db || $db->debug) {
ADOConnection::outp($this->_lasterr);
}
}
}
// return last error message
function ErrorMsg()
{
if (!function_exists('adodb_throw')) {
if ($this->_dbat < 0) {
$db = false;
}
else {
$db = $this->DB();
}
// last error could be database error too
if ($db && $db->ErrorMsg()) {
return $db->ErrorMsg();
}
}
return $this->_lasterr;
}
function ErrorNo()
{
if ($this->_dbat < 0) {
return -9999; // no database connection...
}
$db = $this->DB();
return (int) $db->ErrorNo();
}
// retrieve ADOConnection from _ADODB_Active_DBs
function DB()
{
global $_ADODB_ACTIVE_DBS;
if ($this->_dbat < 0) {
$false = false;
$this->Error("No database connection set: use ADOdb_Active_Record::SetDatabaseAdaptor(\$db)", "DB");
return $false;
}
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$db = $activedb->db;
return $db;
}
// retrieve ADODB_Active_Table
function &TableInfo()
{
global $_ADODB_ACTIVE_DBS;
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$table = $activedb->tables[$this->_tableat];
return $table;
}
// I have an ON INSERT trigger on a table that sets other columns in the table.
// So, I find that for myTable, I want to reload an active record after saving it. -- Malcolm Cook
function Reload()
{
$db = $this->DB();
if (!$db) {
return false;
}
$table = $this->TableInfo();
$where = $this->GenWhere($db, $table);
return($this->Load($where));
}
// set a numeric array (using natural table field ordering) as object properties
function Set(&$row)
{
global $ACTIVE_RECORD_SAFETY;
$db = $this->DB();
if (!$row) {
$this->_saved = false;
return false;
}
$this->_saved = true;
$table = $this->TableInfo();
if ($ACTIVE_RECORD_SAFETY && sizeof($table->flds) != sizeof($row)) {
# <AP>
$bad_size = TRUE;
if (sizeof($row) == 2 * sizeof($table->flds)) {
// Only keep string keys
$keys = array_filter(array_keys($row), 'is_string');
if (sizeof($keys) == sizeof($table->flds)) {
$bad_size = FALSE;
}
}
if ($bad_size) {
$this->Error("Table structure of $this->_table has changed","Load");
return false;
}
# </AP>
}
else
$keys = array_keys($row);
# <AP>
reset($keys);
$this->_original = array();
foreach($table->flds as $name=>$fld) {
$value = $row[current($keys)];
$this->$name = $value;
$this->_original[] = $value;
next($keys);
}
# </AP>
return true;
}
// get last inserted id for INSERT
function LastInsertID(&$db,$fieldname)
{
if ($db->hasInsertID) {
$val = $db->Insert_ID($this->_table,$fieldname);
}
else {
$val = false;
}
if (is_null($val) || $val === false) {
// this might not work reliably in multi-user environment
return $db->GetOne("select max(".$fieldname.") from ".$this->_table);
}
return $val;
}
// quote data in where clause
function doquote(&$db, $val,$t)
{
switch($t) {
case 'L':
if (strpos($db->databaseType,'postgres') !== false) {
return $db->qstr($val);
}
case 'D':
case 'T':
if (empty($val)) {
return 'null';
}
case 'B':
case 'N':
case 'C':
case 'X':
if (is_null($val)) {
return 'null';
}
if (strlen($val)>0 &&
(strncmp($val,"'",1) != 0 || substr($val,strlen($val)-1,1) != "'")
) {
return $db->qstr($val);
break;
}
default:
return $val;
break;
}
}
// generate where clause for an UPDATE/SELECT
function GenWhere(&$db, &$table)
{
$keys = $table->keys;
$parr = array();
foreach($keys as $k) {
$f = $table->flds[$k];
if ($f) {
$parr[] = $k.' = '.$this->doquote($db,$this->$k,$db->MetaType($f->type));
}
}
return implode(' and ', $parr);
}
function _QName($n,$db=false)
{
if (!ADODB_Active_Record::$_quoteNames) {
return $n;
}
if (!$db) {
$db = $this->DB();
if (!$db) {
return false;
}
}
return $db->nameQuote.$n.$db->nameQuote;
}
//------------------------------------------------------------ Public functions below
function Load($where=null,$bindarr=false, $lock = false)
{
global $ADODB_FETCH_MODE;
$db = $this->DB();
if (!$db) {
return false;
}
$this->_where = $where;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($db->fetchMode !== false) {
$savem = $db->SetFetchMode(false);
}
$qry = "select * from ".$this->_table;
if($where) {
$qry .= ' WHERE '.$where;
}
if ($lock) {
$qry .= $this->lockMode;
}
$row = $db->GetRow($qry,$bindarr);
if (isset($savem)) {
$db->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $this->Set($row);
}
function LoadLocked($where=null, $bindarr=false)
{
$this->Load($where,$bindarr,true);
}
# useful for multiple record inserts
# see http://phplens.com/lens/lensforum/msgs.php?id=17795
function Reset()
{
$this->_where=null;
$this->_saved = false;
$this->_lasterr = false;
$this->_original = false;
$vars=get_object_vars($this);
foreach($vars as $k=>$v){
if(substr($k,0,1)!=='_'){
$this->{$k}=null;
}
}
$this->foreignName=strtolower(get_class($this));
return true;
}
// false on error
function Save()
{
if ($this->_saved) {
$ok = $this->Update();
}
else {
$ok = $this->Insert();
}
return $ok;
}
// false on error
function Insert()
{
$db = $this->DB();
if (!$db) {
return false;
}
$cnt = 0;
$table = $this->TableInfo();
$valarr = array();
$names = array();
$valstr = array();
foreach($table->flds as $name=>$fld) {
$val = $this->$name;
if(!is_array($val) || !is_null($val) || !array_key_exists($name, $table->keys)) {
$valarr[] = $val;
$names[] = $this->_QName($name,$db);
$valstr[] = $db->Param($cnt);
$cnt += 1;
}
}
if (empty($names)){
foreach($table->flds as $name=>$fld) {
$valarr[] = null;
$names[] = $name;
$valstr[] = $db->Param($cnt);
$cnt += 1;
}
}
$sql = 'INSERT INTO '.$this->_table."(".implode(',',$names).') VALUES ('.implode(',',$valstr).')';
$ok = $db->Execute($sql,$valarr);
if ($ok) {
$this->_saved = true;
$autoinc = false;
foreach($table->keys as $k) {
if (is_null($this->$k)) {
$autoinc = true;
break;
}
}
if ($autoinc && sizeof($table->keys) == 1) {
$k = reset($table->keys);
$this->$k = $this->LastInsertID($db,$k);
}
}
$this->_original = $valarr;
return !empty($ok);
}
function Delete()
{
$db = $this->DB();
if (!$db) {
return false;
}
$table = $this->TableInfo();
$where = $this->GenWhere($db,$table);
$sql = 'DELETE FROM '.$this->_table.' WHERE '.$where;
$ok = $db->Execute($sql);
return $ok ? true : false;
}
// returns an array of active record objects
function Find($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array())
{
$db = $this->DB();
if (!$db || empty($this->_table)) {
return false;
}
$arr = $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr,$extra);
return $arr;
}
// returns 0 on error, 1 on update, 2 on insert
function Replace()
{
global $ADODB_ASSOC_CASE;
$db = $this->DB();
if (!$db) {
return false;
}
$table = $this->TableInfo();
$pkey = $table->keys;
foreach($table->flds as $name=>$fld) {
$val = $this->$name;
/*
if (is_null($val)) {
if (isset($fld->not_null) && $fld->not_null) {
if (isset($fld->default_value) && strlen($fld->default_value)) {
continue;
}
else {
$this->Error("Cannot update null into $name","Replace");
return false;
}
}
}*/
if (is_null($val) && !empty($fld->auto_increment)) {
continue;
}
if (is_array($val)) {
continue;
}
$t = $db->MetaType($fld->type);
$arr[$name] = $this->doquote($db,$val,$t);
$valarr[] = $val;
}
if (!is_array($pkey)) {
$pkey = array($pkey);
}
if ($ADODB_ASSOC_CASE == 0) {
foreach($pkey as $k => $v)
$pkey[$k] = strtolower($v);
}
elseif ($ADODB_ASSOC_CASE == 1) {
foreach($pkey as $k => $v) {
$pkey[$k] = strtoupper($v);
}
}
$ok = $db->Replace($this->_table,$arr,$pkey);
if ($ok) {
$this->_saved = true; // 1= update 2=insert
if ($ok == 2) {
$autoinc = false;
foreach($table->keys as $k) {
if (is_null($this->$k)) {
$autoinc = true;
break;
}
}
if ($autoinc && sizeof($table->keys) == 1) {
$k = reset($table->keys);
$this->$k = $this->LastInsertID($db,$k);
}
}
$this->_original = $valarr;
}
return $ok;
}
// returns 0 on error, 1 on update, -1 if no change in data (no update)
function Update()
{
$db = $this->DB();
if (!$db) {
return false;
}
$table = $this->TableInfo();
$where = $this->GenWhere($db, $table);
if (!$where) {
$this->error("Where missing for table $table", "Update");
return false;
}
$valarr = array();
$neworig = array();
$pairs = array();
$i = -1;
$cnt = 0;
foreach($table->flds as $name=>$fld) {
$i += 1;
$val = $this->$name;
$neworig[] = $val;
if (isset($table->keys[$name]) || is_array($val)) {
continue;
}
if (is_null($val)) {
if (isset($fld->not_null) && $fld->not_null) {
if (isset($fld->default_value) && strlen($fld->default_value)) {
continue;
}
else {
$this->Error("Cannot set field $name to NULL","Update");
return false;
}
}
}
if (isset($this->_original[$i]) && strcmp($val,$this->_original[$i]) == 0) {
continue;
}
if (is_null($this->_original[$i]) && is_null($val)) {
continue;
}
$valarr[] = $val;
$pairs[] = $this->_QName($name,$db).'='.$db->Param($cnt);
$cnt += 1;
}
if (!$cnt) {
return -1;
}
$sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where;
$ok = $db->Execute($sql,$valarr);
if ($ok) {
$this->_original = $neworig;
return 1;
}
return 0;
}
function GetAttributeNames()
{
$table = $this->TableInfo();
if (!$table) {
return false;
}
return array_keys($table->flds);
}
};
function adodb_GetActiveRecordsClass(&$db, $class, $table,$whereOrderBy,$bindarr, $primkeyArr,
$extra)
{
global $_ADODB_ACTIVE_DBS;
$save = $db->SetFetchMode(ADODB_FETCH_NUM);
$qry = "select * from ".$table;
if (!empty($whereOrderBy)) {
$qry .= ' WHERE '.$whereOrderBy;
}
if(isset($extra['limit'])) {
$rows = false;
if(isset($extra['offset'])) {
$rs = $db->SelectLimit($qry, $extra['limit'], $extra['offset'],$bindarr);
} else {
$rs = $db->SelectLimit($qry, $extra['limit'],-1,$bindarr);
}
if ($rs) {
while (!$rs->EOF) {
$rows[] = $rs->fields;
$rs->MoveNext();
}
}
} else
$rows = $db->GetAll($qry,$bindarr);
$db->SetFetchMode($save);
$false = false;
if ($rows === false) {
return $false;
}
if (!class_exists($class)) {
$db->outp_throw("Unknown class $class in GetActiveRecordsClass()",'GetActiveRecordsClass');
return $false;
}
$arr = array();
// arrRef will be the structure that knows about our objects.
// It is an associative array.
// We will, however, return arr, preserving regular 0.. order so that
// obj[0] can be used by app developpers.
$arrRef = array();
$bTos = array(); // Will store belongTo's indices if any
foreach($rows as $row) {
$obj = new $class($table,$primkeyArr,$db);
if ($obj->ErrorNo()){
$db->_errorMsg = $obj->ErrorMsg();
return $false;
}
$obj->Set($row);
$arr[] = $obj;
} // foreach($rows as $row)
return $arr;
}
-1497
View File
@@ -1,1497 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Latest version is available at http://adodb.sourceforge.net
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Active Record implementation. Superset of Zend Framework's.
This is "Active Record eXtended" to support JOIN, WORK and LAZY mode by Chris Ravenscroft chris#voilaweb.com
Version 0.9
See http://www-128.ibm.com/developerworks/java/library/j-cb03076/?ca=dgr-lnxw01ActiveRecord
for info on Ruby on Rails Active Record implementation
*/
// CFR: Active Records Definitions
define('ADODB_JOIN_AR', 0x01);
define('ADODB_WORK_AR', 0x02);
define('ADODB_LAZY_AR', 0x03);
global $_ADODB_ACTIVE_DBS;
global $ADODB_ACTIVE_CACHESECS; // set to true to enable caching of metadata such as field info
global $ACTIVE_RECORD_SAFETY; // set to false to disable safety checks
global $ADODB_ACTIVE_DEFVALS; // use default values of table definition when creating new active record.
// array of ADODB_Active_DB's, indexed by ADODB_Active_Record->_dbat
$_ADODB_ACTIVE_DBS = array();
$ACTIVE_RECORD_SAFETY = true; // CFR: disabled while playing with relations
$ADODB_ACTIVE_DEFVALS = false;
class ADODB_Active_DB {
var $db; // ADOConnection
var $tables; // assoc array of ADODB_Active_Table objects, indexed by tablename
}
class ADODB_Active_Table {
var $name; // table name
var $flds; // assoc array of adofieldobjs, indexed by fieldname
var $keys; // assoc array of primary keys, indexed by fieldname
var $_created; // only used when stored as a cached file
var $_belongsTo = array();
var $_hasMany = array();
var $_colsCount; // total columns count, including relations
function updateColsCount()
{
$this->_colsCount = sizeof($this->flds);
foreach($this->_belongsTo as $foreignTable)
$this->_colsCount += sizeof($foreignTable->TableInfo()->flds);
foreach($this->_hasMany as $foreignTable)
$this->_colsCount += sizeof($foreignTable->TableInfo()->flds);
}
}
// returns index into $_ADODB_ACTIVE_DBS
function ADODB_SetDatabaseAdapter(&$db)
{
global $_ADODB_ACTIVE_DBS;
foreach($_ADODB_ACTIVE_DBS as $k => $d) {
if (PHP_VERSION >= 5) {
if ($d->db === $db) {
return $k;
}
} else {
if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database) {
return $k;
}
}
}
$obj = new ADODB_Active_DB();
$obj->db = $db;
$obj->tables = array();
$_ADODB_ACTIVE_DBS[] = $obj;
return sizeof($_ADODB_ACTIVE_DBS)-1;
}
class ADODB_Active_Record {
static $_changeNames = true; // dynamically pluralize table names
static $_foreignSuffix = '_id'; //
var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat]
var $_table; // tablename, if set in class definition then use it as table name
var $_sTable; // singularized table name
var $_pTable; // pluralized table name
var $_tableat; // associative index pointing to ADODB_Active_Table, eg $ADODB_Active_DBS[_dbat]->tables[$this->_tableat]
var $_where; // where clause set in Load()
var $_saved = false; // indicates whether data is already inserted.
var $_lasterr = false; // last error message
var $_original = false; // the original values loaded or inserted, refreshed on update
var $foreignName; // CFR: class name when in a relationship
static function UseDefaultValues($bool=null)
{
global $ADODB_ACTIVE_DEFVALS;
if (isset($bool)) {
$ADODB_ACTIVE_DEFVALS = $bool;
}
return $ADODB_ACTIVE_DEFVALS;
}
// should be static
static function SetDatabaseAdapter(&$db)
{
return ADODB_SetDatabaseAdapter($db);
}
public function __set($name, $value)
{
$name = str_replace(' ', '_', $name);
$this->$name = $value;
}
// php5 constructor
// Note: if $table is defined, then we will use it as our table name
// Otherwise we will use our classname...
// In our database, table names are pluralized (because there can be
// more than one row!)
// Similarly, if $table is defined here, it has to be plural form.
//
// $options is an array that allows us to tweak the constructor's behaviour
// if $options['refresh'] is true, we re-scan our metadata information
// if $options['new'] is true, we forget all relations
function __construct($table = false, $pkeyarr=false, $db=false, $options=array())
{
global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS;
if ($db == false && is_object($pkeyarr)) {
$db = $pkeyarr;
$pkeyarr = false;
}
if($table) {
// table argument exists. It is expected to be
// already plural form.
$this->_pTable = $table;
$this->_sTable = $this->_singularize($this->_pTable);
}
else {
// We will use current classname as table name.
// We need to pluralize it for the real table name.
$this->_sTable = strtolower(get_class($this));
$this->_pTable = $this->_pluralize($this->_sTable);
}
$this->_table = &$this->_pTable;
$this->foreignName = $this->_sTable; // CFR: default foreign name (singular)
if ($db) {
$this->_dbat = ADODB_Active_Record::SetDatabaseAdapter($db);
} else
$this->_dbat = sizeof($_ADODB_ACTIVE_DBS)-1;
if ($this->_dbat < 0) {
$this->Error(
"No database connection set; use ADOdb_Active_Record::SetDatabaseAdapter(\$db)",
'ADODB_Active_Record::__constructor'
);
}
$this->_tableat = $this->_table; # reserved for setting the assoc value to a non-table name, eg. the sql string in future
// CFR: Just added this option because UpdateActiveTable() can refresh its information
// but there was no way to ask it to do that.
$forceUpdate = (isset($options['refresh']) && true === $options['refresh']);
$this->UpdateActiveTable($pkeyarr, $forceUpdate);
if(isset($options['new']) && true === $options['new']) {
$table =& $this->TableInfo();
unset($table->_hasMany);
unset($table->_belongsTo);
$table->_hasMany = array();
$table->_belongsTo = array();
}
}
function __wakeup()
{
$class = get_class($this);
new $class;
}
// CFR: Constants found in Rails
static $IrregularP = array(
'PERSON' => 'people',
'MAN' => 'men',
'WOMAN' => 'women',
'CHILD' => 'children',
'COW' => 'kine',
);
static $IrregularS = array(
'PEOPLE' => 'PERSON',
'MEN' => 'man',
'WOMEN' => 'woman',
'CHILDREN' => 'child',
'KINE' => 'cow',
);
static $WeIsI = array(
'EQUIPMENT' => true,
'INFORMATION' => true,
'RICE' => true,
'MONEY' => true,
'SPECIES' => true,
'SERIES' => true,
'FISH' => true,
'SHEEP' => true,
);
function _pluralize($table)
{
if (!ADODB_Active_Record::$_changeNames) {
return $table;
}
$ut = strtoupper($table);
if(isset(self::$WeIsI[$ut])) {
return $table;
}
if(isset(self::$IrregularP[$ut])) {
return self::$IrregularP[$ut];
}
$len = strlen($table);
$lastc = $ut[$len-1];
$lastc2 = substr($ut,$len-2);
switch ($lastc) {
case 'S':
return $table.'es';
case 'Y':
return substr($table,0,$len-1).'ies';
case 'X':
return $table.'es';
case 'H':
if ($lastc2 == 'CH' || $lastc2 == 'SH') {
return $table.'es';
}
default:
return $table.'s';
}
}
// CFR Lamest singular inflector ever - @todo Make it real!
// Note: There is an assumption here...and it is that the argument's length >= 4
function _singularize($table)
{
if (!ADODB_Active_Record::$_changeNames) {
return $table;
}
$ut = strtoupper($table);
if(isset(self::$WeIsI[$ut])) {
return $table;
}
if(isset(self::$IrregularS[$ut])) {
return self::$IrregularS[$ut];
}
$len = strlen($table);
if($ut[$len-1] != 'S') {
return $table; // I know...forget oxen
}
if($ut[$len-2] != 'E') {
return substr($table, 0, $len-1);
}
switch($ut[$len-3]) {
case 'S':
case 'X':
return substr($table, 0, $len-2);
case 'I':
return substr($table, 0, $len-3) . 'y';
case 'H';
if($ut[$len-4] == 'C' || $ut[$len-4] == 'S') {
return substr($table, 0, $len-2);
}
default:
return substr($table, 0, $len-1); // ?
}
}
/*
* ar->foreignName will contain the name of the tables associated with this table because
* these other tables' rows may also be referenced by this table using theirname_id or the provided
* foreign keys (this index name is stored in ar->foreignKey)
*
* this-table.id = other-table-#1.this-table_id
* = other-table-#2.this-table_id
*/
function hasMany($foreignRef,$foreignKey=false)
{
$ar = new ADODB_Active_Record($foreignRef);
$ar->foreignName = $foreignRef;
$ar->UpdateActiveTable();
$ar->foreignKey = ($foreignKey) ? $foreignKey : strtolower(get_class($this)) . self::$_foreignSuffix;
$table =& $this->TableInfo();
if(!isset($table->_hasMany[$foreignRef])) {
$table->_hasMany[$foreignRef] = $ar;
$table->updateColsCount();
}
# @todo Can I make this guy be lazy?
$this->$foreignRef = $table->_hasMany[$foreignRef]; // WATCHME Removed assignment by ref. to please __get()
}
/**
* ar->foreignName will contain the name of the tables associated with this table because
* this table's rows may also be referenced by those tables using thistable_id or the provided
* foreign keys (this index name is stored in ar->foreignKey)
*
* this-table.other-table_id = other-table.id
*/
function belongsTo($foreignRef,$foreignKey=false)
{
global $inflector;
$ar = new ADODB_Active_Record($this->_pluralize($foreignRef));
$ar->foreignName = $foreignRef;
$ar->UpdateActiveTable();
$ar->foreignKey = ($foreignKey) ? $foreignKey : $ar->foreignName . self::$_foreignSuffix;
$table =& $this->TableInfo();
if(!isset($table->_belongsTo[$foreignRef])) {
$table->_belongsTo[$foreignRef] = $ar;
$table->updateColsCount();
}
$this->$foreignRef = $table->_belongsTo[$foreignRef];
}
/**
* __get Access properties - used for lazy loading
*
* @param mixed $name
* @access protected
* @return void
*/
function __get($name)
{
return $this->LoadRelations($name, '', -1. -1);
}
function LoadRelations($name, $whereOrderBy, $offset=-1, $limit=-1)
{
$extras = array();
if($offset >= 0) {
$extras['offset'] = $offset;
}
if($limit >= 0) {
$extras['limit'] = $limit;
}
$table =& $this->TableInfo();
if (strlen($whereOrderBy)) {
if (!preg_match('/^[ \n\r]*AND/i',$whereOrderBy)) {
if (!preg_match('/^[ \n\r]*ORDER[ \n\r]/i',$whereOrderBy)) {
$whereOrderBy = 'AND '.$whereOrderBy;
}
}
}
if(!empty($table->_belongsTo[$name])) {
$obj = $table->_belongsTo[$name];
$columnName = $obj->foreignKey;
if(empty($this->$columnName)) {
$this->$name = null;
}
else {
if(($k = reset($obj->TableInfo()->keys))) {
$belongsToId = $k;
}
else {
$belongsToId = 'id';
}
$arrayOfOne =
$obj->Find(
$belongsToId.'='.$this->$columnName.' '.$whereOrderBy, false, false, $extras);
$this->$name = $arrayOfOne[0];
}
return $this->$name;
}
if(!empty($table->_hasMany[$name])) {
$obj = $table->_hasMany[$name];
if(($k = reset($table->keys))) {
$hasManyId = $k;
}
else {
$hasManyId = 'id';
}
$this->$name =
$obj->Find(
$obj->foreignKey.'='.$this->$hasManyId.' '.$whereOrderBy, false, false, $extras);
return $this->$name;
}
}
//////////////////////////////////
// update metadata
function UpdateActiveTable($pkeys=false,$forceUpdate=false)
{
global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS , $ADODB_CACHE_DIR, $ADODB_ACTIVE_CACHESECS;
global $ADODB_ACTIVE_DEFVALS, $ADODB_FETCH_MODE;
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$table = $this->_table;
$tables = $activedb->tables;
$tableat = $this->_tableat;
if (!$forceUpdate && !empty($tables[$tableat])) {
$tobj = $tables[$tableat];
foreach($tobj->flds as $name => $fld) {
if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) {
$this->$name = $fld->default_value;
}
else {
$this->$name = null;
}
}
return;
}
$db = $activedb->db;
$fname = $ADODB_CACHE_DIR . '/adodb_' . $db->databaseType . '_active_'. $table . '.cache';
if (!$forceUpdate && $ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR && file_exists($fname)) {
$fp = fopen($fname,'r');
@flock($fp, LOCK_SH);
$acttab = unserialize(fread($fp,100000));
fclose($fp);
if ($acttab->_created + $ADODB_ACTIVE_CACHESECS - (abs(rand()) % 16) > time()) {
// abs(rand()) randomizes deletion, reducing contention to delete/refresh file
// ideally, you should cache at least 32 secs
$activedb->tables[$table] = $acttab;
//if ($db->debug) ADOConnection::outp("Reading cached active record file: $fname");
return;
} else if ($db->debug) {
ADOConnection::outp("Refreshing cached active record file: $fname");
}
}
$activetab = new ADODB_Active_Table();
$activetab->name = $table;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($db->fetchMode !== false) {
$savem = $db->SetFetchMode(false);
}
$cols = $db->MetaColumns($table);
if (isset($savem)) {
$db->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!$cols) {
$this->Error("Invalid table name: $table",'UpdateActiveTable');
return false;
}
$fld = reset($cols);
if (!$pkeys) {
if (isset($fld->primary_key)) {
$pkeys = array();
foreach($cols as $name => $fld) {
if (!empty($fld->primary_key)) {
$pkeys[] = $name;
}
}
} else {
$pkeys = $this->GetPrimaryKeys($db, $table);
}
}
if (empty($pkeys)) {
$this->Error("No primary key found for table $table",'UpdateActiveTable');
return false;
}
$attr = array();
$keys = array();
switch($ADODB_ASSOC_CASE) {
case 0:
foreach($cols as $name => $fldobj) {
$name = strtolower($name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
$this->$name = $fldobj->default_value;
}
else {
$this->$name = null;
}
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[strtolower($name)] = strtolower($name);
}
break;
case 1:
foreach($cols as $name => $fldobj) {
$name = strtoupper($name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
$this->$name = $fldobj->default_value;
}
else {
$this->$name = null;
}
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[strtoupper($name)] = strtoupper($name);
}
break;
default:
foreach($cols as $name => $fldobj) {
$name = ($fldobj->name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
$this->$name = $fldobj->default_value;
}
else {
$this->$name = null;
}
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[$name] = $cols[$name]->name;
}
break;
}
$activetab->keys = $keys;
$activetab->flds = $attr;
$activetab->updateColsCount();
if ($ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR) {
$activetab->_created = time();
$s = serialize($activetab);
if (!function_exists('adodb_write_file')) {
include(ADODB_DIR.'/adodb-csvlib.inc.php');
}
adodb_write_file($fname,$s);
}
if (isset($activedb->tables[$table])) {
$oldtab = $activedb->tables[$table];
if ($oldtab) {
$activetab->_belongsTo = $oldtab->_belongsTo;
$activetab->_hasMany = $oldtab->_hasMany;
}
}
$activedb->tables[$table] = $activetab;
}
function GetPrimaryKeys(&$db, $table)
{
return $db->MetaPrimaryKeys($table);
}
// error handler for both PHP4+5.
function Error($err,$fn)
{
global $_ADODB_ACTIVE_DBS;
$fn = get_class($this).'::'.$fn;
$this->_lasterr = $fn.': '.$err;
if ($this->_dbat < 0) {
$db = false;
}
else {
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$db = $activedb->db;
}
if (function_exists('adodb_throw')) {
if (!$db) {
adodb_throw('ADOdb_Active_Record', $fn, -1, $err, 0, 0, false);
}
else {
adodb_throw($db->databaseType, $fn, -1, $err, 0, 0, $db);
}
} else {
if (!$db || $db->debug) {
ADOConnection::outp($this->_lasterr);
}
}
}
// return last error message
function ErrorMsg()
{
if (!function_exists('adodb_throw')) {
if ($this->_dbat < 0) {
$db = false;
}
else {
$db = $this->DB();
}
// last error could be database error too
if ($db && $db->ErrorMsg()) {
return $db->ErrorMsg();
}
}
return $this->_lasterr;
}
function ErrorNo()
{
if ($this->_dbat < 0) {
return -9999; // no database connection...
}
$db = $this->DB();
return (int) $db->ErrorNo();
}
// retrieve ADOConnection from _ADODB_Active_DBs
function DB()
{
global $_ADODB_ACTIVE_DBS;
if ($this->_dbat < 0) {
$false = false;
$this->Error("No database connection set: use ADOdb_Active_Record::SetDatabaseAdaptor(\$db)", "DB");
return $false;
}
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$db = $activedb->db;
return $db;
}
// retrieve ADODB_Active_Table
function &TableInfo()
{
global $_ADODB_ACTIVE_DBS;
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$table = $activedb->tables[$this->_tableat];
return $table;
}
// I have an ON INSERT trigger on a table that sets other columns in the table.
// So, I find that for myTable, I want to reload an active record after saving it. -- Malcolm Cook
function Reload()
{
$db =& $this->DB();
if (!$db) {
return false;
}
$table =& $this->TableInfo();
$where = $this->GenWhere($db, $table);
return($this->Load($where));
}
// set a numeric array (using natural table field ordering) as object properties
function Set(&$row)
{
global $ACTIVE_RECORD_SAFETY;
$db = $this->DB();
if (!$row) {
$this->_saved = false;
return false;
}
$this->_saved = true;
$table = $this->TableInfo();
$sizeofFlds = sizeof($table->flds);
$sizeofRow = sizeof($row);
if ($ACTIVE_RECORD_SAFETY && $table->_colsCount != $sizeofRow && $sizeofFlds != $sizeofRow) {
# <AP>
$bad_size = TRUE;
if($sizeofRow == 2 * $table->_colsCount || $sizeofRow == 2 * $sizeofFlds) {
// Only keep string keys
$keys = array_filter(array_keys($row), 'is_string');
if (sizeof($keys) == sizeof($table->flds)) {
$bad_size = FALSE;
}
}
if ($bad_size) {
$this->Error("Table structure of $this->_table has changed","Load");
return false;
}
# </AP>
}
else {
$keys = array_keys($row);
}
# <AP>
reset($keys);
$this->_original = array();
foreach($table->flds as $name=>$fld) {
$value = $row[current($keys)];
$this->$name = $value;
$this->_original[] = $value;
if(!next($keys)) {
break;
}
}
$table =& $this->TableInfo();
foreach($table->_belongsTo as $foreignTable) {
$ft = $foreignTable->TableInfo();
$propertyName = $ft->name;
foreach($ft->flds as $name=>$fld) {
$value = $row[current($keys)];
$foreignTable->$name = $value;
$foreignTable->_original[] = $value;
if(!next($keys)) {
break;
}
}
}
foreach($table->_hasMany as $foreignTable) {
$ft = $foreignTable->TableInfo();
foreach($ft->flds as $name=>$fld) {
$value = $row[current($keys)];
$foreignTable->$name = $value;
$foreignTable->_original[] = $value;
if(!next($keys)) {
break;
}
}
}
# </AP>
return true;
}
// get last inserted id for INSERT
function LastInsertID(&$db,$fieldname)
{
if ($db->hasInsertID) {
$val = $db->Insert_ID($this->_table,$fieldname);
}
else {
$val = false;
}
if (is_null($val) || $val === false) {
// this might not work reliably in multi-user environment
return $db->GetOne("select max(".$fieldname.") from ".$this->_table);
}
return $val;
}
// quote data in where clause
function doquote(&$db, $val,$t)
{
switch($t) {
case 'D':
case 'T':
if (empty($val)) {
return 'null';
}
case 'C':
case 'X':
if (is_null($val)) {
return 'null';
}
if (strlen($val)>0 &&
(strncmp($val,"'",1) != 0 || substr($val,strlen($val)-1,1) != "'")
) {
return $db->qstr($val);
break;
}
default:
return $val;
break;
}
}
// generate where clause for an UPDATE/SELECT
function GenWhere(&$db, &$table)
{
$keys = $table->keys;
$parr = array();
foreach($keys as $k) {
$f = $table->flds[$k];
if ($f) {
$parr[] = $k.' = '.$this->doquote($db,$this->$k,$db->MetaType($f->type));
}
}
return implode(' and ', $parr);
}
//------------------------------------------------------------ Public functions below
function Load($where=null,$bindarr=false)
{
$db = $this->DB();
if (!$db) {
return false;
}
$this->_where = $where;
$save = $db->SetFetchMode(ADODB_FETCH_NUM);
$qry = "select * from ".$this->_table;
$table =& $this->TableInfo();
if(($k = reset($table->keys))) {
$hasManyId = $k;
}
else {
$hasManyId = 'id';
}
foreach($table->_belongsTo as $foreignTable) {
if(($k = reset($foreignTable->TableInfo()->keys))) {
$belongsToId = $k;
}
else {
$belongsToId = 'id';
}
$qry .= ' LEFT JOIN '.$foreignTable->_table.' ON '.
$this->_table.'.'.$foreignTable->foreignKey.'='.
$foreignTable->_table.'.'.$belongsToId;
}
foreach($table->_hasMany as $foreignTable)
{
$qry .= ' LEFT JOIN '.$foreignTable->_table.' ON '.
$this->_table.'.'.$hasManyId.'='.
$foreignTable->_table.'.'.$foreignTable->foreignKey;
}
if($where) {
$qry .= ' WHERE '.$where;
}
// Simple case: no relations. Load row and return.
if((count($table->_hasMany) + count($table->_belongsTo)) < 1) {
$row = $db->GetRow($qry,$bindarr);
if(!$row) {
return false;
}
$db->SetFetchMode($save);
return $this->Set($row);
}
// More complex case when relations have to be collated
$rows = $db->GetAll($qry,$bindarr);
if(!$rows) {
return false;
}
$db->SetFetchMode($save);
if(count($rows) < 1) {
return false;
}
$class = get_class($this);
$isFirstRow = true;
if(($k = reset($this->TableInfo()->keys))) {
$myId = $k;
}
else {
$myId = 'id';
}
$index = 0; $found = false;
/** @todo Improve by storing once and for all in table metadata */
/** @todo Also re-use info for hasManyId */
foreach($this->TableInfo()->flds as $fld) {
if($fld->name == $myId) {
$found = true;
break;
}
$index++;
}
if(!$found) {
$this->outp_throw("Unable to locate key $myId for $class in Load()",'Load');
}
foreach($rows as $row) {
$rowId = intval($row[$index]);
if($rowId > 0) {
if($isFirstRow) {
$isFirstRow = false;
if(!$this->Set($row)) {
return false;
}
}
$obj = new $class($table,false,$db);
$obj->Set($row);
// TODO Copy/paste code below: bad!
if(count($table->_hasMany) > 0) {
foreach($table->_hasMany as $foreignTable) {
$foreignName = $foreignTable->foreignName;
if(!empty($obj->$foreignName)) {
if(!is_array($this->$foreignName)) {
$foreignObj = $this->$foreignName;
$this->$foreignName = array(clone($foreignObj));
}
else {
$foreignObj = $obj->$foreignName;
array_push($this->$foreignName, clone($foreignObj));
}
}
}
}
if(count($table->_belongsTo) > 0) {
foreach($table->_belongsTo as $foreignTable) {
$foreignName = $foreignTable->foreignName;
if(!empty($obj->$foreignName)) {
if(!is_array($this->$foreignName)) {
$foreignObj = $this->$foreignName;
$this->$foreignName = array(clone($foreignObj));
}
else {
$foreignObj = $obj->$foreignName;
array_push($this->$foreignName, clone($foreignObj));
}
}
}
}
}
}
return true;
}
// false on error
function Save()
{
if ($this->_saved) {
$ok = $this->Update();
}
else {
$ok = $this->Insert();
}
return $ok;
}
// CFR: Sometimes we may wish to consider that an object is not to be replaced but inserted.
// Sample use case: an 'undo' command object (after a delete())
function Dirty()
{
$this->_saved = false;
}
// false on error
function Insert()
{
$db = $this->DB();
if (!$db) {
return false;
}
$cnt = 0;
$table = $this->TableInfo();
$valarr = array();
$names = array();
$valstr = array();
foreach($table->flds as $name=>$fld) {
$val = $this->$name;
if(!is_null($val) || !array_key_exists($name, $table->keys)) {
$valarr[] = $val;
$names[] = $name;
$valstr[] = $db->Param($cnt);
$cnt += 1;
}
}
if (empty($names)){
foreach($table->flds as $name=>$fld) {
$valarr[] = null;
$names[] = $name;
$valstr[] = $db->Param($cnt);
$cnt += 1;
}
}
$sql = 'INSERT INTO '.$this->_table."(".implode(',',$names).') VALUES ('.implode(',',$valstr).')';
$ok = $db->Execute($sql,$valarr);
if ($ok) {
$this->_saved = true;
$autoinc = false;
foreach($table->keys as $k) {
if (is_null($this->$k)) {
$autoinc = true;
break;
}
}
if ($autoinc && sizeof($table->keys) == 1) {
$k = reset($table->keys);
$this->$k = $this->LastInsertID($db,$k);
}
}
$this->_original = $valarr;
return !empty($ok);
}
function Delete()
{
$db = $this->DB();
if (!$db) {
return false;
}
$table = $this->TableInfo();
$where = $this->GenWhere($db,$table);
$sql = 'DELETE FROM '.$this->_table.' WHERE '.$where;
$ok = $db->Execute($sql);
return $ok ? true : false;
}
// returns an array of active record objects
function Find($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array())
{
$db = $this->DB();
if (!$db || empty($this->_table)) {
return false;
}
$table =& $this->TableInfo();
$arr = $db->GetActiveRecordsClass(get_class($this),$this, $whereOrderBy,$bindarr,$pkeysArr,$extra,
array('foreignName'=>$this->foreignName, 'belongsTo'=>$table->_belongsTo, 'hasMany'=>$table->_hasMany));
return $arr;
}
// CFR: In introduced this method to ensure that inner workings are not disturbed by
// subclasses...for instance when GetActiveRecordsClass invokes Find()
// Why am I not invoking parent::Find?
// Shockingly because I want to preserve PHP4 compatibility.
function packageFind($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array())
{
$db = $this->DB();
if (!$db || empty($this->_table)) {
return false;
}
$table =& $this->TableInfo();
$arr = $db->GetActiveRecordsClass(get_class($this),$this, $whereOrderBy,$bindarr,$pkeysArr,$extra,
array('foreignName'=>$this->foreignName, 'belongsTo'=>$table->_belongsTo, 'hasMany'=>$table->_hasMany));
return $arr;
}
// returns 0 on error, 1 on update, 2 on insert
function Replace()
{
global $ADODB_ASSOC_CASE;
$db = $this->DB();
if (!$db) {
return false;
}
$table = $this->TableInfo();
$pkey = $table->keys;
foreach($table->flds as $name=>$fld) {
$val = $this->$name;
/*
if (is_null($val)) {
if (isset($fld->not_null) && $fld->not_null) {
if (isset($fld->default_value) && strlen($fld->default_value)) {
continue;
}
else {
$this->Error("Cannot update null into $name","Replace");
return false;
}
}
}*/
if (is_null($val) && !empty($fld->auto_increment)) {
continue;
}
$t = $db->MetaType($fld->type);
$arr[$name] = $this->doquote($db,$val,$t);
$valarr[] = $val;
}
if (!is_array($pkey)) {
$pkey = array($pkey);
}
switch ($ADODB_ASSOC_CASE == 0) {
case ADODB_ASSOC_CASE_LOWER:
foreach($pkey as $k => $v) {
$pkey[$k] = strtolower($v);
}
break;
case ADODB_ASSOC_CASE_UPPER:
foreach($pkey as $k => $v) {
$pkey[$k] = strtoupper($v);
}
break;
}
$ok = $db->Replace($this->_table,$arr,$pkey);
if ($ok) {
$this->_saved = true; // 1= update 2=insert
if ($ok == 2) {
$autoinc = false;
foreach($table->keys as $k) {
if (is_null($this->$k)) {
$autoinc = true;
break;
}
}
if ($autoinc && sizeof($table->keys) == 1) {
$k = reset($table->keys);
$this->$k = $this->LastInsertID($db,$k);
}
}
$this->_original = $valarr;
}
return $ok;
}
// returns 0 on error, 1 on update, -1 if no change in data (no update)
function Update()
{
$db = $this->DB();
if (!$db) {
return false;
}
$table = $this->TableInfo();
$where = $this->GenWhere($db, $table);
if (!$where) {
$this->error("Where missing for table $table", "Update");
return false;
}
$valarr = array();
$neworig = array();
$pairs = array();
$i = -1;
$cnt = 0;
foreach($table->flds as $name=>$fld) {
$i += 1;
$val = $this->$name;
$neworig[] = $val;
if (isset($table->keys[$name])) {
continue;
}
if (is_null($val)) {
if (isset($fld->not_null) && $fld->not_null) {
if (isset($fld->default_value) && strlen($fld->default_value)) {
continue;
}
else {
$this->Error("Cannot set field $name to NULL","Update");
return false;
}
}
}
if (isset($this->_original[$i]) && $val === $this->_original[$i]) {
continue;
}
$valarr[] = $val;
$pairs[] = $name.'='.$db->Param($cnt);
$cnt += 1;
}
if (!$cnt) {
return -1;
}
$sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where;
$ok = $db->Execute($sql,$valarr);
if ($ok) {
$this->_original = $neworig;
return 1;
}
return 0;
}
function GetAttributeNames()
{
$table = $this->TableInfo();
if (!$table) {
return false;
}
return array_keys($table->flds);
}
};
function adodb_GetActiveRecordsClass(&$db, $class, $tableObj,$whereOrderBy,$bindarr, $primkeyArr,
$extra, $relations)
{
global $_ADODB_ACTIVE_DBS;
if (empty($extra['loading'])) {
$extra['loading'] = ADODB_LAZY_AR;
}
$save = $db->SetFetchMode(ADODB_FETCH_NUM);
$table = &$tableObj->_table;
$tableInfo =& $tableObj->TableInfo();
if(($k = reset($tableInfo->keys))) {
$myId = $k;
}
else {
$myId = 'id';
}
$index = 0; $found = false;
/** @todo Improve by storing once and for all in table metadata */
/** @todo Also re-use info for hasManyId */
foreach($tableInfo->flds as $fld)
{
if($fld->name == $myId) {
$found = true;
break;
}
$index++;
}
if(!$found) {
$db->outp_throw("Unable to locate key $myId for $class in GetActiveRecordsClass()",'GetActiveRecordsClass');
}
$qry = "select * from ".$table;
if(ADODB_JOIN_AR == $extra['loading']) {
if(!empty($relations['belongsTo'])) {
foreach($relations['belongsTo'] as $foreignTable) {
if(($k = reset($foreignTable->TableInfo()->keys))) {
$belongsToId = $k;
}
else {
$belongsToId = 'id';
}
$qry .= ' LEFT JOIN '.$foreignTable->_table.' ON '.
$table.'.'.$foreignTable->foreignKey.'='.
$foreignTable->_table.'.'.$belongsToId;
}
}
if(!empty($relations['hasMany'])) {
if(empty($relations['foreignName'])) {
$db->outp_throw("Missing foreignName is relation specification in GetActiveRecordsClass()",'GetActiveRecordsClass');
}
if(($k = reset($tableInfo->keys))) {
$hasManyId = $k;
}
else {
$hasManyId = 'id';
}
foreach($relations['hasMany'] as $foreignTable) {
$qry .= ' LEFT JOIN '.$foreignTable->_table.' ON '.
$table.'.'.$hasManyId.'='.
$foreignTable->_table.'.'.$foreignTable->foreignKey;
}
}
}
if (!empty($whereOrderBy)) {
$qry .= ' WHERE '.$whereOrderBy;
}
if(isset($extra['limit'])) {
$rows = false;
if(isset($extra['offset'])) {
$rs = $db->SelectLimit($qry, $extra['limit'], $extra['offset']);
} else {
$rs = $db->SelectLimit($qry, $extra['limit']);
}
if ($rs) {
while (!$rs->EOF) {
$rows[] = $rs->fields;
$rs->MoveNext();
}
}
} else
$rows = $db->GetAll($qry,$bindarr);
$db->SetFetchMode($save);
$false = false;
if ($rows === false) {
return $false;
}
if (!isset($_ADODB_ACTIVE_DBS)) {
include(ADODB_DIR.'/adodb-active-record.inc.php');
}
if (!class_exists($class)) {
$db->outp_throw("Unknown class $class in GetActiveRecordsClass()",'GetActiveRecordsClass');
return $false;
}
$uniqArr = array(); // CFR Keep track of records for relations
$arr = array();
// arrRef will be the structure that knows about our objects.
// It is an associative array.
// We will, however, return arr, preserving regular 0.. order so that
// obj[0] can be used by app developpers.
$arrRef = array();
$bTos = array(); // Will store belongTo's indices if any
foreach($rows as $row) {
$obj = new $class($table,$primkeyArr,$db);
if ($obj->ErrorNo()){
$db->_errorMsg = $obj->ErrorMsg();
return $false;
}
$obj->Set($row);
// CFR: FIXME: Insane assumption here:
// If the first column returned is an integer, then it's a 'id' field
// And to make things a bit worse, I use intval() rather than is_int() because, in fact,
// $row[0] is not an integer.
//
// So, what does this whole block do?
// When relationships are found, we perform JOINs. This is fast. But not accurate:
// instead of returning n objects with their n' associated cousins,
// we get n*n' objects. This code fixes this.
// Note: to-many relationships mess around with the 'limit' parameter
$rowId = intval($row[$index]);
if(ADODB_WORK_AR == $extra['loading']) {
$arrRef[$rowId] = $obj;
$arr[] = &$arrRef[$rowId];
if(!isset($indices)) {
$indices = $rowId;
}
else {
$indices .= ','.$rowId;
}
if(!empty($relations['belongsTo'])) {
foreach($relations['belongsTo'] as $foreignTable) {
$foreignTableRef = $foreignTable->foreignKey;
// First array: list of foreign ids we are looking for
if(empty($bTos[$foreignTableRef])) {
$bTos[$foreignTableRef] = array();
}
// Second array: list of ids found
if(empty($obj->$foreignTableRef)) {
continue;
}
if(empty($bTos[$foreignTableRef][$obj->$foreignTableRef])) {
$bTos[$foreignTableRef][$obj->$foreignTableRef] = array();
}
$bTos[$foreignTableRef][$obj->$foreignTableRef][] = $obj;
}
}
continue;
}
if($rowId>0) {
if(ADODB_JOIN_AR == $extra['loading']) {
$isNewObj = !isset($uniqArr['_'.$row[0]]);
if($isNewObj) {
$uniqArr['_'.$row[0]] = $obj;
}
// TODO Copy/paste code below: bad!
if(!empty($relations['hasMany'])) {
foreach($relations['hasMany'] as $foreignTable) {
$foreignName = $foreignTable->foreignName;
if(!empty($obj->$foreignName)) {
$masterObj = &$uniqArr['_'.$row[0]];
// Assumption: this property exists in every object since they are instances of the same class
if(!is_array($masterObj->$foreignName)) {
// Pluck!
$foreignObj = $masterObj->$foreignName;
$masterObj->$foreignName = array(clone($foreignObj));
}
else {
// Pluck pluck!
$foreignObj = $obj->$foreignName;
array_push($masterObj->$foreignName, clone($foreignObj));
}
}
}
}
if(!empty($relations['belongsTo'])) {
foreach($relations['belongsTo'] as $foreignTable) {
$foreignName = $foreignTable->foreignName;
if(!empty($obj->$foreignName)) {
$masterObj = &$uniqArr['_'.$row[0]];
// Assumption: this property exists in every object since they are instances of the same class
if(!is_array($masterObj->$foreignName)) {
// Pluck!
$foreignObj = $masterObj->$foreignName;
$masterObj->$foreignName = array(clone($foreignObj));
}
else {
// Pluck pluck!
$foreignObj = $obj->$foreignName;
array_push($masterObj->$foreignName, clone($foreignObj));
}
}
}
}
if(!$isNewObj) {
unset($obj); // We do not need this object itself anymore and do not want it re-added to the main array
}
}
else if(ADODB_LAZY_AR == $extra['loading']) {
// Lazy loading: we need to give AdoDb a hint that we have not really loaded
// anything, all the while keeping enough information on what we wish to load.
// Let's do this by keeping the relevant info in our relationship arrays
// but get rid of the actual properties.
// We will then use PHP's __get to load these properties on-demand.
if(!empty($relations['hasMany'])) {
foreach($relations['hasMany'] as $foreignTable) {
$foreignName = $foreignTable->foreignName;
if(!empty($obj->$foreignName)) {
unset($obj->$foreignName);
}
}
}
if(!empty($relations['belongsTo'])) {
foreach($relations['belongsTo'] as $foreignTable) {
$foreignName = $foreignTable->foreignName;
if(!empty($obj->$foreignName)) {
unset($obj->$foreignName);
}
}
}
}
}
if(isset($obj)) {
$arr[] = $obj;
}
}
if(ADODB_WORK_AR == $extra['loading']) {
// The best of both worlds?
// Here, the number of queries is constant: 1 + n*relationship.
// The second query will allow us to perform a good join
// while preserving LIMIT etc.
if(!empty($relations['hasMany'])) {
foreach($relations['hasMany'] as $foreignTable) {
$foreignName = $foreignTable->foreignName;
$className = ucfirst($foreignTable->_singularize($foreignName));
$obj = new $className();
$dbClassRef = $foreignTable->foreignKey;
$objs = $obj->packageFind($dbClassRef.' IN ('.$indices.')');
foreach($objs as $obj) {
if(!is_array($arrRef[$obj->$dbClassRef]->$foreignName)) {
$arrRef[$obj->$dbClassRef]->$foreignName = array();
}
array_push($arrRef[$obj->$dbClassRef]->$foreignName, $obj);
}
}
}
if(!empty($relations['belongsTo'])) {
foreach($relations['belongsTo'] as $foreignTable) {
$foreignTableRef = $foreignTable->foreignKey;
if(empty($bTos[$foreignTableRef])) {
continue;
}
if(($k = reset($foreignTable->TableInfo()->keys))) {
$belongsToId = $k;
}
else {
$belongsToId = 'id';
}
$origObjsArr = $bTos[$foreignTableRef];
$bTosString = implode(',', array_keys($bTos[$foreignTableRef]));
$foreignName = $foreignTable->foreignName;
$className = ucfirst($foreignTable->_singularize($foreignName));
$obj = new $className();
$objs = $obj->packageFind($belongsToId.' IN ('.$bTosString.')');
foreach($objs as $obj)
{
foreach($origObjsArr[$obj->$belongsToId] as $idx=>$origObj)
{
$origObj->$foreignName = $obj;
}
}
}
}
}
return $arr;
}
-319
View File
@@ -1,319 +0,0 @@
<?php
// security - hide paths
if (!defined('ADODB_DIR')) die();
global $ADODB_INCLUDED_CSV;
$ADODB_INCLUDED_CSV = 1;
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Library for CSV serialization. This is used by the csv/proxy driver and is the
CacheExecute() serialization format.
==== NOTE ====
Format documented at http://php.weblogs.com/ADODB_CSV
==============
*/
/**
* convert a recordset into special format
*
* @param rs the recordset
*
* @return the CSV formated data
*/
function _rs2serialize(&$rs,$conn=false,$sql='')
{
$max = ($rs) ? $rs->FieldCount() : 0;
if ($sql) $sql = urlencode($sql);
// metadata setup
if ($max <= 0 || $rs->dataProvider == 'empty') { // is insert/update/delete
if (is_object($conn)) {
$sql .= ','.$conn->Affected_Rows();
$sql .= ','.$conn->Insert_ID();
} else
$sql .= ',,';
$text = "====-1,0,$sql\n";
return $text;
}
$tt = ($rs->timeCreated) ? $rs->timeCreated : time();
## changed format from ====0 to ====1
$line = "====1,$tt,$sql\n";
if ($rs->databaseType == 'array') {
$rows = $rs->_array;
} else {
$rows = array();
while (!$rs->EOF) {
$rows[] = $rs->fields;
$rs->MoveNext();
}
}
for($i=0; $i < $max; $i++) {
$o = $rs->FetchField($i);
$flds[] = $o;
}
$savefetch = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode;
$class = $rs->connection->arrayClass;
$rs2 = new $class();
$rs2->timeCreated = $rs->timeCreated; # memcache fix
$rs2->sql = $rs->sql;
$rs2->oldProvider = $rs->dataProvider;
$rs2->InitArrayFields($rows,$flds);
$rs2->fetchMode = $savefetch;
return $line.serialize($rs2);
}
/**
* Open CSV file and convert it into Data.
*
* @param url file/ftp/http url
* @param err returns the error message
* @param timeout dispose if recordset has been alive for $timeout secs
*
* @return recordset, or false if error occured. If no
* error occurred in sql INSERT/UPDATE/DELETE,
* empty recordset is returned
*/
function csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
{
$false = false;
$err = false;
$fp = @fopen($url,'rb');
if (!$fp) {
$err = $url.' file/URL not found';
return $false;
}
@flock($fp, LOCK_SH);
$arr = array();
$ttl = 0;
if ($meta = fgetcsv($fp, 32000, ",")) {
// check if error message
if (strncmp($meta[0],'****',4) === 0) {
$err = trim(substr($meta[0],4,1024));
fclose($fp);
return $false;
}
// check for meta data
// $meta[0] is -1 means return an empty recordset
// $meta[1] contains a time
if (strncmp($meta[0], '====',4) === 0) {
if ($meta[0] == "====-1") {
if (sizeof($meta) < 5) {
$err = "Corrupt first line for format -1";
fclose($fp);
return $false;
}
fclose($fp);
if ($timeout > 0) {
$err = " Illegal Timeout $timeout ";
return $false;
}
$rs = new $rsclass($val=true);
$rs->fields = array();
$rs->timeCreated = $meta[1];
$rs->EOF = true;
$rs->_numOfFields = 0;
$rs->sql = urldecode($meta[2]);
$rs->affectedrows = (integer)$meta[3];
$rs->insertid = $meta[4];
return $rs;
}
# Under high volume loads, we want only 1 thread/process to _write_file
# so that we don't have 50 processes queueing to write the same data.
# We use probabilistic timeout, ahead of time.
#
# -4 sec before timeout, give processes 1/32 chance of timing out
# -2 sec before timeout, give processes 1/16 chance of timing out
# -1 sec after timeout give processes 1/4 chance of timing out
# +0 sec after timeout, give processes 100% chance of timing out
if (sizeof($meta) > 1) {
if($timeout >0){
$tdiff = (integer)( $meta[1]+$timeout - time());
if ($tdiff <= 2) {
switch($tdiff) {
case 4:
case 3:
if ((rand() & 31) == 0) {
fclose($fp);
$err = "Timeout 3";
return $false;
}
break;
case 2:
if ((rand() & 15) == 0) {
fclose($fp);
$err = "Timeout 2";
return $false;
}
break;
case 1:
if ((rand() & 3) == 0) {
fclose($fp);
$err = "Timeout 1";
return $false;
}
break;
default:
fclose($fp);
$err = "Timeout 0";
return $false;
} // switch
} // if check flush cache
}// (timeout>0)
$ttl = $meta[1];
}
//================================================
// new cache format - use serialize extensively...
if ($meta[0] === '====1') {
// slurp in the data
$MAXSIZE = 128000;
$text = fread($fp,$MAXSIZE);
if (strlen($text)) {
while ($txt = fread($fp,$MAXSIZE)) {
$text .= $txt;
}
}
fclose($fp);
$rs = unserialize($text);
if (is_object($rs)) $rs->timeCreated = $ttl;
else {
$err = "Unable to unserialize recordset";
//echo htmlspecialchars($text),' !--END--!<p>';
}
return $rs;
}
$meta = false;
$meta = fgetcsv($fp, 32000, ",");
if (!$meta) {
fclose($fp);
$err = "Unexpected EOF 1";
return $false;
}
}
// Get Column definitions
$flds = array();
foreach($meta as $o) {
$o2 = explode(':',$o);
if (sizeof($o2)!=3) {
$arr[] = $meta;
$flds = false;
break;
}
$fld = new ADOFieldObject();
$fld->name = urldecode($o2[0]);
$fld->type = $o2[1];
$fld->max_length = $o2[2];
$flds[] = $fld;
}
} else {
fclose($fp);
$err = "Recordset had unexpected EOF 2";
return $false;
}
// slurp in the data
$MAXSIZE = 128000;
$text = '';
while ($txt = fread($fp,$MAXSIZE)) {
$text .= $txt;
}
fclose($fp);
@$arr = unserialize($text);
//var_dump($arr);
if (!is_array($arr)) {
$err = "Recordset had unexpected EOF (in serialized recordset)";
if (get_magic_quotes_runtime()) $err .= ". Magic Quotes Runtime should be disabled!";
return $false;
}
$rs = new $rsclass();
$rs->timeCreated = $ttl;
$rs->InitArrayFields($arr,$flds);
return $rs;
}
/**
* Save a file $filename and its $contents (normally for caching) with file locking
* Returns true if ok, false if fopen/fwrite error, 0 if rename error (eg. file is locked)
*/
function adodb_write_file($filename, $contents,$debug=false)
{
# http://www.php.net/bugs.php?id=9203 Bug that flock fails on Windows
# So to simulate locking, we assume that rename is an atomic operation.
# First we delete $filename, then we create a $tempfile write to it and
# rename to the desired $filename. If the rename works, then we successfully
# modified the file exclusively.
# What a stupid need - having to simulate locking.
# Risks:
# 1. $tempfile name is not unique -- very very low
# 2. unlink($filename) fails -- ok, rename will fail
# 3. adodb reads stale file because unlink fails -- ok, $rs timeout occurs
# 4. another process creates $filename between unlink() and rename() -- ok, rename() fails and cache updated
if (strncmp(PHP_OS,'WIN',3) === 0) {
// skip the decimal place
$mtime = substr(str_replace(' ','_',microtime()),2);
// getmypid() actually returns 0 on Win98 - never mind!
$tmpname = $filename.uniqid($mtime).getmypid();
if (!($fd = @fopen($tmpname,'w'))) return false;
if (fwrite($fd,$contents)) $ok = true;
else $ok = false;
fclose($fd);
if ($ok) {
@chmod($tmpname,0644);
// the tricky moment
@unlink($filename);
if (!@rename($tmpname,$filename)) {
@unlink($tmpname);
$ok = 0;
}
if (!$ok) {
if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed'));
}
}
return $ok;
}
if (!($fd = @fopen($filename, 'a'))) return false;
if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) {
if (fwrite( $fd, $contents )) $ok = true;
else $ok = false;
fclose($fd);
@chmod($filename,0644);
}else {
fclose($fd);
if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename<br>\n");
$ok = false;
}
return $ok;
}
-1033
View File
@@ -1,1033 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
DOCUMENTATION:
See adodb/tests/test-datadict.php for docs and examples.
*/
/*
Test script for parser
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
function Lens_ParseTest()
{
$str = "`zcol ACOL` NUMBER(32,2) DEFAULT 'The \"cow\" (and Jim''s dog) jumps over the moon' PRIMARY, INTI INT AUTO DEFAULT 0, zcol2\"afs ds";
print "<p>$str</p>";
$a= Lens_ParseArgs($str);
print "<pre>";
print_r($a);
print "</pre>";
}
if (!function_exists('ctype_alnum')) {
function ctype_alnum($text) {
return preg_match('/^[a-z0-9]*$/i', $text);
}
}
//Lens_ParseTest();
/**
Parse arguments, treat "text" (text) and 'text' as quotation marks.
To escape, use "" or '' or ))
Will read in "abc def" sans quotes, as: abc def
Same with 'abc def'.
However if `abc def`, then will read in as `abc def`
@param endstmtchar Character that indicates end of statement
@param tokenchars Include the following characters in tokens apart from A-Z and 0-9
@returns 2 dimensional array containing parsed tokens.
*/
function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
{
$pos = 0;
$intoken = false;
$stmtno = 0;
$endquote = false;
$tokens = array();
$tokens[$stmtno] = array();
$max = strlen($args);
$quoted = false;
$tokarr = array();
while ($pos < $max) {
$ch = substr($args,$pos,1);
switch($ch) {
case ' ':
case "\t":
case "\n":
case "\r":
if (!$quoted) {
if ($intoken) {
$intoken = false;
$tokens[$stmtno][] = implode('',$tokarr);
}
break;
}
$tokarr[] = $ch;
break;
case '`':
if ($intoken) $tokarr[] = $ch;
case '(':
case ')':
case '"':
case "'":
if ($intoken) {
if (empty($endquote)) {
$tokens[$stmtno][] = implode('',$tokarr);
if ($ch == '(') $endquote = ')';
else $endquote = $ch;
$quoted = true;
$intoken = true;
$tokarr = array();
} else if ($endquote == $ch) {
$ch2 = substr($args,$pos+1,1);
if ($ch2 == $endquote) {
$pos += 1;
$tokarr[] = $ch2;
} else {
$quoted = false;
$intoken = false;
$tokens[$stmtno][] = implode('',$tokarr);
$endquote = '';
}
} else
$tokarr[] = $ch;
}else {
if ($ch == '(') $endquote = ')';
else $endquote = $ch;
$quoted = true;
$intoken = true;
$tokarr = array();
if ($ch == '`') $tokarr[] = '`';
}
break;
default:
if (!$intoken) {
if ($ch == $endstmtchar) {
$stmtno += 1;
$tokens[$stmtno] = array();
break;
}
$intoken = true;
$quoted = false;
$endquote = false;
$tokarr = array();
}
if ($quoted) $tokarr[] = $ch;
else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch;
else {
if ($ch == $endstmtchar) {
$tokens[$stmtno][] = implode('',$tokarr);
$stmtno += 1;
$tokens[$stmtno] = array();
$intoken = false;
$tokarr = array();
break;
}
$tokens[$stmtno][] = implode('',$tokarr);
$tokens[$stmtno][] = $ch;
$intoken = false;
}
}
$pos += 1;
}
if ($intoken) $tokens[$stmtno][] = implode('',$tokarr);
return $tokens;
}
class ADODB_DataDict {
var $connection;
var $debug = false;
var $dropTable = 'DROP TABLE %s';
var $renameTable = 'RENAME TABLE %s TO %s';
var $dropIndex = 'DROP INDEX %s';
var $addCol = ' ADD';
var $alterCol = ' ALTER COLUMN';
var $dropCol = ' DROP COLUMN';
var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s'; // table, old-column, new-column, column-definitions (not used by default)
var $nameRegex = '\w';
var $nameRegexBrackets = 'a-zA-Z0-9_\(\)';
var $schema = false;
var $serverInfo = array();
var $autoIncrement = false;
var $dataProvider;
var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql
var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob
/// in other words, we use a text area for editting.
function GetCommentSQL($table,$col)
{
return false;
}
function SetCommentSQL($table,$col,$cmt)
{
return false;
}
function MetaTables()
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaTables();
}
function MetaColumns($tab, $upper=true, $schema=false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema);
}
function MetaPrimaryKeys($tab,$owner=false,$intkey=false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey);
}
function MetaIndexes($table, $primary = false, $owner = false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner);
}
function MetaType($t,$len=-1,$fieldobj=false)
{
static $typeMap = array(
'VARCHAR' => 'C',
'VARCHAR2' => 'C',
'CHAR' => 'C',
'C' => 'C',
'STRING' => 'C',
'NCHAR' => 'C',
'NVARCHAR' => 'C',
'VARYING' => 'C',
'BPCHAR' => 'C',
'CHARACTER' => 'C',
'INTERVAL' => 'C', # Postgres
'MACADDR' => 'C', # postgres
'VAR_STRING' => 'C', # mysql
##
'LONGCHAR' => 'X',
'TEXT' => 'X',
'NTEXT' => 'X',
'M' => 'X',
'X' => 'X',
'CLOB' => 'X',
'NCLOB' => 'X',
'LVARCHAR' => 'X',
##
'BLOB' => 'B',
'IMAGE' => 'B',
'BINARY' => 'B',
'VARBINARY' => 'B',
'LONGBINARY' => 'B',
'B' => 'B',
##
'YEAR' => 'D', // mysql
'DATE' => 'D',
'D' => 'D',
##
'UNIQUEIDENTIFIER' => 'C', # MS SQL Server
##
'TIME' => 'T',
'TIMESTAMP' => 'T',
'DATETIME' => 'T',
'TIMESTAMPTZ' => 'T',
'SMALLDATETIME' => 'T',
'T' => 'T',
'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql
##
'BOOL' => 'L',
'BOOLEAN' => 'L',
'BIT' => 'L',
'L' => 'L',
##
'COUNTER' => 'R',
'R' => 'R',
'SERIAL' => 'R', // ifx
'INT IDENTITY' => 'R',
##
'INT' => 'I',
'INT2' => 'I',
'INT4' => 'I',
'INT8' => 'I',
'INTEGER' => 'I',
'INTEGER UNSIGNED' => 'I',
'SHORT' => 'I',
'TINYINT' => 'I',
'SMALLINT' => 'I',
'I' => 'I',
##
'LONG' => 'N', // interbase is numeric, oci8 is blob
'BIGINT' => 'N', // this is bigger than PHP 32-bit integers
'DECIMAL' => 'N',
'DEC' => 'N',
'REAL' => 'N',
'DOUBLE' => 'N',
'DOUBLE PRECISION' => 'N',
'SMALLFLOAT' => 'N',
'FLOAT' => 'N',
'NUMBER' => 'N',
'NUM' => 'N',
'NUMERIC' => 'N',
'MONEY' => 'N',
## informix 9.2
'SQLINT' => 'I',
'SQLSERIAL' => 'I',
'SQLSMINT' => 'I',
'SQLSMFLOAT' => 'N',
'SQLFLOAT' => 'N',
'SQLMONEY' => 'N',
'SQLDECIMAL' => 'N',
'SQLDATE' => 'D',
'SQLVCHAR' => 'C',
'SQLCHAR' => 'C',
'SQLDTIME' => 'T',
'SQLINTERVAL' => 'N',
'SQLBYTES' => 'B',
'SQLTEXT' => 'X',
## informix 10
"SQLINT8" => 'I8',
"SQLSERIAL8" => 'I8',
"SQLNCHAR" => 'C',
"SQLNVCHAR" => 'C',
"SQLLVARCHAR" => 'X',
"SQLBOOL" => 'L'
);
if (!$this->connection->IsConnected()) {
$t = strtoupper($t);
if (isset($typeMap[$t])) return $typeMap[$t];
return 'N';
}
return $this->connection->MetaType($t,$len,$fieldobj);
}
function NameQuote($name = NULL,$allowBrackets=false)
{
if (!is_string($name)) {
return FALSE;
}
$name = trim($name);
if ( !is_object($this->connection) ) {
return $name;
}
$quote = $this->connection->nameQuote;
// if name is of the form `name`, quote it
if ( preg_match('/^`(.+)`$/', $name, $matches) ) {
return $quote . $matches[1] . $quote;
}
// if name contains special characters, quote it
$regex = ($allowBrackets) ? $this->nameRegexBrackets : $this->nameRegex;
if ( !preg_match('/^[' . $regex . ']+$/', $name) ) {
return $quote . $name . $quote;
}
return $name;
}
function TableName($name)
{
if ( $this->schema ) {
return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name);
}
return $this->NameQuote($name);
}
// Executes the sql array returned by GetTableSQL and GetIndexSQL
function ExecuteSQLArray($sql, $continueOnError = true)
{
$rez = 2;
$conn = $this->connection;
$saved = $conn->debug;
foreach($sql as $line) {
if ($this->debug) $conn->debug = true;
$ok = $conn->Execute($line);
$conn->debug = $saved;
if (!$ok) {
if ($this->debug) ADOConnection::outp($conn->ErrorMsg());
if (!$continueOnError) return 0;
$rez = 1;
}
}
return $rez;
}
/**
Returns the actual type given a character code.
C: varchar
X: CLOB (character large object) or largest varchar size if CLOB is not supported
C2: Multibyte varchar
X2: Multibyte CLOB
B: BLOB (binary large object)
D: Date
T: Date-time
L: Integer field suitable for storing booleans (0 or 1)
I: Integer
F: Floating point number
N: Numeric or decimal number
*/
function ActualType($meta)
{
return $meta;
}
function CreateDatabase($dbname,$options=false)
{
$options = $this->_Options($options);
$sql = array();
$s = 'CREATE DATABASE ' . $this->NameQuote($dbname);
if (isset($options[$this->upperName]))
$s .= ' '.$options[$this->upperName];
$sql[] = $s;
return $sql;
}
/*
Generates the SQL to create index. Returns an array of sql strings.
*/
function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false)
{
if (!is_array($flds)) {
$flds = explode(',',$flds);
}
foreach($flds as $key => $fld) {
# some indexes can use partial fields, eg. index first 32 chars of "name" with NAME(32)
$flds[$key] = $this->NameQuote($fld,$allowBrackets=true);
}
return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions));
}
function DropIndexSQL ($idxname, $tabname = NULL)
{
return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname)));
}
function SetSchema($schema)
{
$this->schema = $schema;
}
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
foreach($lines as $v) {
$sql[] = $alter . $v;
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
/**
* Change the definition of one column
*
* As some DBM's can't do that on there own, you need to supply the complete defintion of the new table,
* to allow, recreating the table and copying the content over to the new table
* @param string $tabname table-name
* @param string $flds column-name and type for the changed column
* @param string $tableflds='' complete defintion of the new table, eg. for postgres, default ''
* @param array/string $tableoptions='' options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
foreach($lines as $v) {
$sql[] = $alter . $v;
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
/**
* Rename one column
*
* Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql)
* @param string $tabname table-name
* @param string $oldcolumn column-name to be renamed
* @param string $newcolumn new column-name
* @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default=''
* @return array with SQL strings
*/
function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='')
{
$tabname = $this->TableName ($tabname);
if ($flds) {
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
list(,$first) = each($lines);
list(,$column_def) = preg_split("/[\t ]+/",$first,2);
}
return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def));
}
/**
* Drop one column
*
* Some DBM's can't do that on there own, you need to supply the complete defintion of the new table,
* to allow, recreating the table and copying the content over to the new table
* @param string $tabname table-name
* @param string $flds column-name and type for the changed column
* @param string $tableflds='' complete defintion of the new table, eg. for postgres, default ''
* @param array/string $tableoptions='' options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
if (!is_array($flds)) $flds = explode(',',$flds);
$sql = array();
$alter = 'ALTER TABLE ' . $tabname . $this->dropCol . ' ';
foreach($flds as $v) {
$sql[] = $alter . $this->NameQuote($v);
}
return $sql;
}
function DropTableSQL($tabname)
{
return array (sprintf($this->dropTable, $this->TableName($tabname)));
}
function RenameTableSQL($tabname,$newname)
{
return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname)));
}
/**
Generate the SQL to create table. Returns an array of sql strings.
*/
function CreateTableSQL($tabname, $flds, $tableoptions=array())
{
list($lines,$pkey,$idxs) = $this->_GenFields($flds, true);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$taboptions = $this->_Options($tableoptions);
$tabname = $this->TableName ($tabname);
$sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
// ggiunta - 2006/10/12 - KLUDGE:
// if we are on autoincrement, and table options includes REPLACE, the
// autoincrement sequence has already been dropped on table creation sql, so
// we avoid passing REPLACE to trigger creation code. This prevents
// creating sql that double-drops the sequence
if ($this->autoIncrement && isset($taboptions['REPLACE']))
unset($taboptions['REPLACE']);
$tsql = $this->_Triggers($tabname,$taboptions);
foreach($tsql as $s) $sql[] = $s;
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
function _GenFields($flds,$widespacing=false)
{
if (is_string($flds)) {
$padding = ' ';
$txt = $flds.$padding;
$flds = array();
$flds0 = Lens_ParseArgs($txt,',');
$hasparam = false;
foreach($flds0 as $f0) {
$f1 = array();
foreach($f0 as $token) {
switch (strtoupper($token)) {
case 'INDEX':
$f1['INDEX'] = '';
// fall through intentionally
case 'CONSTRAINT':
case 'DEFAULT':
$hasparam = $token;
break;
default:
if ($hasparam) $f1[$hasparam] = $token;
else $f1[] = $token;
$hasparam = false;
break;
}
}
// 'index' token without a name means single column index: name it after column
if (array_key_exists('INDEX', $f1) && $f1['INDEX'] == '') {
$f1['INDEX'] = isset($f0['NAME']) ? $f0['NAME'] : $f0[0];
// check if column name used to create an index name was quoted
if (($f1['INDEX'][0] == '"' || $f1['INDEX'][0] == "'" || $f1['INDEX'][0] == "`") &&
($f1['INDEX'][0] == substr($f1['INDEX'], -1))) {
$f1['INDEX'] = $f1['INDEX'][0].'idx_'.substr($f1['INDEX'], 1, -1).$f1['INDEX'][0];
}
else
$f1['INDEX'] = 'idx_'.$f1['INDEX'];
}
// reset it, so we don't get next field 1st token as INDEX...
$hasparam = false;
$flds[] = $f1;
}
}
$this->autoIncrement = false;
$lines = array();
$pkey = array();
$idxs = array();
foreach($flds as $fld) {
$fld = _array_change_key_case($fld);
$fname = false;
$fdefault = false;
$fautoinc = false;
$ftype = false;
$fsize = false;
$fprec = false;
$fprimary = false;
$fnoquote = false;
$fdefts = false;
$fdefdate = false;
$fconstraint = false;
$fnotnull = false;
$funsigned = false;
$findex = '';
$funiqueindex = false;
//-----------------
// Parse attributes
foreach($fld as $attr => $v) {
if ($attr == 2 && is_numeric($v)) $attr = 'SIZE';
else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v);
switch($attr) {
case '0':
case 'NAME': $fname = $v; break;
case '1':
case 'TYPE': $ty = $v; $ftype = $this->ActualType(strtoupper($v)); break;
case 'SIZE':
$dotat = strpos($v,'.'); if ($dotat === false) $dotat = strpos($v,',');
if ($dotat === false) $fsize = $v;
else {
$fsize = substr($v,0,$dotat);
$fprec = substr($v,$dotat+1);
}
break;
case 'UNSIGNED': $funsigned = true; break;
case 'AUTOINCREMENT':
case 'AUTO': $fautoinc = true; $fnotnull = true; break;
case 'KEY':
// a primary key col can be non unique in itself (if key spans many cols...)
case 'PRIMARY': $fprimary = $v; $fnotnull = true; /*$funiqueindex = true;*/ break;
case 'DEF':
case 'DEFAULT': $fdefault = $v; break;
case 'NOTNULL': $fnotnull = $v; break;
case 'NOQUOTE': $fnoquote = $v; break;
case 'DEFDATE': $fdefdate = $v; break;
case 'DEFTIMESTAMP': $fdefts = $v; break;
case 'CONSTRAINT': $fconstraint = $v; break;
// let INDEX keyword create a 'very standard' index on column
case 'INDEX': $findex = $v; break;
case 'UNIQUE': $funiqueindex = true; break;
} //switch
} // foreach $fld
//--------------------
// VALIDATE FIELD INFO
if (!strlen($fname)) {
if ($this->debug) ADOConnection::outp("Undefined NAME");
return false;
}
$fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname));
$fname = $this->NameQuote($fname);
if (!strlen($ftype)) {
if ($this->debug) ADOConnection::outp("Undefined TYPE for field '$fname'");
return false;
} else {
$ftype = strtoupper($ftype);
}
$ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec);
if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls
if ($fprimary) $pkey[] = $fname;
// some databases do not allow blobs to have defaults
if ($ty == 'X') $fdefault = false;
// build list of indexes
if ($findex != '') {
if (array_key_exists($findex, $idxs)) {
$idxs[$findex]['cols'][] = ($fname);
if (in_array('UNIQUE', $idxs[$findex]['opts']) != $funiqueindex) {
if ($this->debug) ADOConnection::outp("Index $findex defined once UNIQUE and once not");
}
if ($funiqueindex && !in_array('UNIQUE', $idxs[$findex]['opts']))
$idxs[$findex]['opts'][] = 'UNIQUE';
}
else
{
$idxs[$findex] = array();
$idxs[$findex]['cols'] = array($fname);
if ($funiqueindex)
$idxs[$findex]['opts'] = array('UNIQUE');
else
$idxs[$findex]['opts'] = array();
}
}
//--------------------
// CONSTRUCT FIELD SQL
if ($fdefts) {
if (substr($this->connection->databaseType,0,5) == 'mysql') {
$ftype = 'TIMESTAMP';
} else {
$fdefault = $this->connection->sysTimeStamp;
}
} else if ($fdefdate) {
if (substr($this->connection->databaseType,0,5) == 'mysql') {
$ftype = 'TIMESTAMP';
} else {
$fdefault = $this->connection->sysDate;
}
} else if ($fdefault !== false && !$fnoquote) {
if ($ty == 'C' or $ty == 'X' or
( substr($fdefault,0,1) != "'" && !is_numeric($fdefault))) {
if (($ty == 'D' || $ty == 'T') && strtolower($fdefault) != 'null') {
// convert default date into database-aware code
if ($ty == 'T')
{
$fdefault = $this->connection->DBTimeStamp($fdefault);
}
else
{
$fdefault = $this->connection->DBDate($fdefault);
}
}
else
if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ')
$fdefault = trim($fdefault);
else if (strtolower($fdefault) != 'null')
$fdefault = $this->connection->qstr($fdefault);
}
}
$suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
// add index creation
if ($widespacing) $fname = str_pad($fname,24);
// check for field names appearing twice
if (array_key_exists($fid, $lines)) {
ADOConnection::outp("Field '$fname' defined twice");
}
$lines[$fid] = $fname.' '.$ftype.$suffix;
if ($fautoinc) $this->autoIncrement = true;
} // foreach $flds
return array($lines,$pkey,$idxs);
}
/**
GENERATE THE SIZE PART OF THE DATATYPE
$ftype is the actual type
$ty is the type defined originally in the DDL
*/
function _GetSize($ftype, $ty, $fsize, $fprec)
{
if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) {
$ftype .= "(".$fsize;
if (strlen($fprec)) $ftype .= ",".$fprec;
$ftype .= ')';
}
return $ftype;
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname);
if ( isset($idxoptions['DROP']) )
return $sql;
}
if ( empty ($flds) ) {
return $sql;
}
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
$s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' ';
if ( isset($idxoptions[$this->upperName]) )
$s .= $idxoptions[$this->upperName];
if ( is_array($flds) )
$flds = implode(', ',$flds);
$s .= '(' . $flds . ')';
$sql[] = $s;
return $sql;
}
function _DropAutoIncrement($tabname)
{
return false;
}
function _TableSQL($tabname,$lines,$pkey,$tableoptions)
{
$sql = array();
if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) {
$sql[] = sprintf($this->dropTable,$tabname);
if ($this->autoIncrement) {
$sInc = $this->_DropAutoIncrement($tabname);
if ($sInc) $sql[] = $sInc;
}
if ( isset ($tableoptions['DROP']) ) {
return $sql;
}
}
$s = "CREATE TABLE $tabname (\n";
$s .= implode(",\n", $lines);
if (sizeof($pkey)>0) {
$s .= ",\n PRIMARY KEY (";
$s .= implode(", ",$pkey).")";
}
if (isset($tableoptions['CONSTRAINTS']))
$s .= "\n".$tableoptions['CONSTRAINTS'];
if (isset($tableoptions[$this->upperName.'_CONSTRAINTS']))
$s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS'];
$s .= "\n)";
if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName];
$sql[] = $s;
return $sql;
}
/**
GENERATE TRIGGERS IF NEEDED
used when table has auto-incrementing field that is emulated using triggers
*/
function _Triggers($tabname,$taboptions)
{
return array();
}
/**
Sanitize options, so that array elements with no keys are promoted to keys
*/
function _Options($opts)
{
if (!is_array($opts)) return array();
$newopts = array();
foreach($opts as $k => $v) {
if (is_numeric($k)) $newopts[strtoupper($v)] = $v;
else $newopts[strtoupper($k)] = $v;
}
return $newopts;
}
function _getSizePrec($size)
{
$fsize = false;
$fprec = false;
$dotat = strpos($size,'.');
if ($dotat === false) $dotat = strpos($size,',');
if ($dotat === false) $fsize = $size;
else {
$fsize = substr($size,0,$dotat);
$fprec = substr($size,$dotat+1);
}
return array($fsize, $fprec);
}
/**
"Florian Buzin [ easywe ]" <florian.buzin#easywe.de>
This function changes/adds new fields to your table. You don't
have to know if the col is new or not. It will check on its own.
*/
function ChangeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($this->connection->fetchMode !== false) $savem = $this->connection->SetFetchMode(false);
// check table exists
$save_handler = $this->connection->raiseErrorFn;
$this->connection->raiseErrorFn = '';
$cols = $this->MetaColumns($tablename);
$this->connection->raiseErrorFn = $save_handler;
if (isset($savem)) $this->connection->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ( empty($cols)) {
return $this->CreateTableSQL($tablename, $flds, $tableoptions);
}
if (is_array($flds)) {
// Cycle through the update fields, comparing
// existing fields to fields to update.
// if the Metatype and size is exactly the
// same, ignore - by Mark Newham
$holdflds = array();
foreach($flds as $k=>$v) {
if ( isset($cols[$k]) && is_object($cols[$k]) ) {
// If already not allowing nulls, then don't change
$obj = $cols[$k];
if (isset($obj->not_null) && $obj->not_null)
$v = str_replace('NOT NULL','',$v);
if (isset($obj->auto_increment) && $obj->auto_increment && empty($v['AUTOINCREMENT']))
$v = str_replace('AUTOINCREMENT','',$v);
$c = $cols[$k];
$ml = $c->max_length;
$mt = $this->MetaType($c->type,$ml);
if (isset($c->scale)) $sc = $c->scale;
else $sc = 99; // always force change if scale not known.
if ($sc == -1) $sc = false;
list($fsize, $fprec) = $this->_getSizePrec($v['SIZE']);
if ($ml == -1) $ml = '';
if ($mt == 'X') $ml = $v['SIZE'];
if (($mt != $v['TYPE']) || ($ml != $fsize || $sc != $fprec) || (isset($v['AUTOINCREMENT']) && $v['AUTOINCREMENT'] != $obj->auto_increment)) {
$holdflds[$k] = $v;
}
} else {
$holdflds[$k] = $v;
}
}
$flds = $holdflds;
}
// already exists, alter table instead
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $this->TableName($tablename);
$sql = array();
foreach ( $lines as $id => $v ) {
if ( isset($cols[$id]) && is_object($cols[$id]) ) {
$flds = Lens_ParseArgs($v,',');
// We are trying to change the size of the field, if not allowed, simply ignore the request.
// $flds[1] holds the type, $flds[2] holds the size -postnuke addition
if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)
&& (isset($flds[0][2]) && is_numeric($flds[0][2]))) {
if ($this->debug) ADOConnection::outp(sprintf("<h3>%s cannot be changed to %s currently</h3>", $flds[0][0], $flds[0][1]));
#echo "<h3>$this->alterCol cannot be changed to $flds currently</h3>";
continue;
}
$sql[] = $alter . $this->alterCol . ' ' . $v;
} else {
$sql[] = $alter . $this->addCol . ' ' . $v;
}
}
if ($dropOldFlds) {
foreach ( $cols as $id => $v )
if ( !isset($lines[$id]) )
$sql[] = $alter . $this->dropCol . ' ' . $v->name;
}
return $sql;
}
} // class
-265
View File
@@ -1,265 +0,0 @@
<?php
/**
* @version v5.20.9 21-Dec-2016
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
* The following code is adapted from the PEAR DB error handling code.
* Portions (c)1997-2002 The PHP Group.
*/
if (!defined("DB_ERROR")) define("DB_ERROR",-1);
if (!defined("DB_ERROR_SYNTAX")) {
define("DB_ERROR_SYNTAX", -2);
define("DB_ERROR_CONSTRAINT", -3);
define("DB_ERROR_NOT_FOUND", -4);
define("DB_ERROR_ALREADY_EXISTS", -5);
define("DB_ERROR_UNSUPPORTED", -6);
define("DB_ERROR_MISMATCH", -7);
define("DB_ERROR_INVALID", -8);
define("DB_ERROR_NOT_CAPABLE", -9);
define("DB_ERROR_TRUNCATED", -10);
define("DB_ERROR_INVALID_NUMBER", -11);
define("DB_ERROR_INVALID_DATE", -12);
define("DB_ERROR_DIVZERO", -13);
define("DB_ERROR_NODBSELECTED", -14);
define("DB_ERROR_CANNOT_CREATE", -15);
define("DB_ERROR_CANNOT_DELETE", -16);
define("DB_ERROR_CANNOT_DROP", -17);
define("DB_ERROR_NOSUCHTABLE", -18);
define("DB_ERROR_NOSUCHFIELD", -19);
define("DB_ERROR_NEED_MORE_DATA", -20);
define("DB_ERROR_NOT_LOCKED", -21);
define("DB_ERROR_VALUE_COUNT_ON_ROW", -22);
define("DB_ERROR_INVALID_DSN", -23);
define("DB_ERROR_CONNECT_FAILED", -24);
define("DB_ERROR_EXTENSION_NOT_FOUND",-25);
define("DB_ERROR_NOSUCHDB", -25);
define("DB_ERROR_ACCESS_VIOLATION", -26);
define("DB_ERROR_DEADLOCK", -27);
define("DB_ERROR_STATEMENT_TIMEOUT", -28);
define("DB_ERROR_SERIALIZATION_FAILURE", -29);
}
function adodb_errormsg($value)
{
global $ADODB_LANG,$ADODB_LANG_ARRAY;
if (empty($ADODB_LANG)) $ADODB_LANG = 'en';
if (isset($ADODB_LANG_ARRAY['LANG']) && $ADODB_LANG_ARRAY['LANG'] == $ADODB_LANG) ;
else {
include_once(ADODB_DIR."/lang/adodb-$ADODB_LANG.inc.php");
}
return isset($ADODB_LANG_ARRAY[$value]) ? $ADODB_LANG_ARRAY[$value] : $ADODB_LANG_ARRAY[DB_ERROR];
}
function adodb_error($provider,$dbType,$errno)
{
//var_dump($errno);
if (is_numeric($errno) && $errno == 0) return 0;
switch($provider) {
case 'mysql': $map = adodb_error_mysql(); break;
case 'oracle':
case 'oci8': $map = adodb_error_oci8(); break;
case 'ibase': $map = adodb_error_ibase(); break;
case 'odbc': $map = adodb_error_odbc(); break;
case 'mssql':
case 'sybase': $map = adodb_error_mssql(); break;
case 'informix': $map = adodb_error_ifx(); break;
case 'postgres': return adodb_error_pg($errno); break;
case 'sqlite': return $map = adodb_error_sqlite(); break;
default:
return DB_ERROR;
}
//print_r($map);
//var_dump($errno);
if (isset($map[$errno])) return $map[$errno];
return DB_ERROR;
}
//**************************************************************************************
function adodb_error_pg($errormsg)
{
if (is_numeric($errormsg)) return (integer) $errormsg;
// Postgres has no lock-wait timeout. The best we could do would be to set a statement timeout.
static $error_regexps = array(
'(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$' => DB_ERROR_NOSUCHTABLE,
'Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key.*violates unique constraint' => DB_ERROR_ALREADY_EXISTS,
'database ".+" does not exist$' => DB_ERROR_NOSUCHDB,
'(divide|division) by zero$' => DB_ERROR_DIVZERO,
'pg_atoi: error in .*: can\'t parse ' => DB_ERROR_INVALID_NUMBER,
'ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']' => DB_ERROR_NOSUCHFIELD,
'(parser: parse|syntax) error at or near \"' => DB_ERROR_SYNTAX,
'referential integrity violation' => DB_ERROR_CONSTRAINT,
'deadlock detected$' => DB_ERROR_DEADLOCK,
'canceling statement due to statement timeout$' => DB_ERROR_STATEMENT_TIMEOUT,
'could not serialize access due to' => DB_ERROR_SERIALIZATION_FAILURE
);
reset($error_regexps);
while (list($regexp,$code) = each($error_regexps)) {
if (preg_match("/$regexp/mi", $errormsg)) {
return $code;
}
}
// Fall back to DB_ERROR if there was no mapping.
return DB_ERROR;
}
function adodb_error_odbc()
{
static $MAP = array(
'01004' => DB_ERROR_TRUNCATED,
'07001' => DB_ERROR_MISMATCH,
'21S01' => DB_ERROR_MISMATCH,
'21S02' => DB_ERROR_MISMATCH,
'22003' => DB_ERROR_INVALID_NUMBER,
'22008' => DB_ERROR_INVALID_DATE,
'22012' => DB_ERROR_DIVZERO,
'23000' => DB_ERROR_CONSTRAINT,
'24000' => DB_ERROR_INVALID,
'34000' => DB_ERROR_INVALID,
'37000' => DB_ERROR_SYNTAX,
'42000' => DB_ERROR_SYNTAX,
'IM001' => DB_ERROR_UNSUPPORTED,
'S0000' => DB_ERROR_NOSUCHTABLE,
'S0001' => DB_ERROR_NOT_FOUND,
'S0002' => DB_ERROR_NOSUCHTABLE,
'S0011' => DB_ERROR_ALREADY_EXISTS,
'S0012' => DB_ERROR_NOT_FOUND,
'S0021' => DB_ERROR_ALREADY_EXISTS,
'S0022' => DB_ERROR_NOT_FOUND,
'S1000' => DB_ERROR_NOSUCHTABLE,
'S1009' => DB_ERROR_INVALID,
'S1090' => DB_ERROR_INVALID,
'S1C00' => DB_ERROR_NOT_CAPABLE
);
return $MAP;
}
function adodb_error_ibase()
{
static $MAP = array(
-104 => DB_ERROR_SYNTAX,
-150 => DB_ERROR_ACCESS_VIOLATION,
-151 => DB_ERROR_ACCESS_VIOLATION,
-155 => DB_ERROR_NOSUCHTABLE,
-157 => DB_ERROR_NOSUCHFIELD,
-158 => DB_ERROR_VALUE_COUNT_ON_ROW,
-170 => DB_ERROR_MISMATCH,
-171 => DB_ERROR_MISMATCH,
-172 => DB_ERROR_INVALID,
-204 => DB_ERROR_INVALID,
-205 => DB_ERROR_NOSUCHFIELD,
-206 => DB_ERROR_NOSUCHFIELD,
-208 => DB_ERROR_INVALID,
-219 => DB_ERROR_NOSUCHTABLE,
-297 => DB_ERROR_CONSTRAINT,
-530 => DB_ERROR_CONSTRAINT,
-803 => DB_ERROR_CONSTRAINT,
-551 => DB_ERROR_ACCESS_VIOLATION,
-552 => DB_ERROR_ACCESS_VIOLATION,
-922 => DB_ERROR_NOSUCHDB,
-923 => DB_ERROR_CONNECT_FAILED,
-924 => DB_ERROR_CONNECT_FAILED
);
return $MAP;
}
function adodb_error_ifx()
{
static $MAP = array(
'-201' => DB_ERROR_SYNTAX,
'-206' => DB_ERROR_NOSUCHTABLE,
'-217' => DB_ERROR_NOSUCHFIELD,
'-329' => DB_ERROR_NODBSELECTED,
'-1204' => DB_ERROR_INVALID_DATE,
'-1205' => DB_ERROR_INVALID_DATE,
'-1206' => DB_ERROR_INVALID_DATE,
'-1209' => DB_ERROR_INVALID_DATE,
'-1210' => DB_ERROR_INVALID_DATE,
'-1212' => DB_ERROR_INVALID_DATE
);
return $MAP;
}
function adodb_error_oci8()
{
static $MAP = array(
1 => DB_ERROR_ALREADY_EXISTS,
900 => DB_ERROR_SYNTAX,
904 => DB_ERROR_NOSUCHFIELD,
923 => DB_ERROR_SYNTAX,
942 => DB_ERROR_NOSUCHTABLE,
955 => DB_ERROR_ALREADY_EXISTS,
1476 => DB_ERROR_DIVZERO,
1722 => DB_ERROR_INVALID_NUMBER,
2289 => DB_ERROR_NOSUCHTABLE,
2291 => DB_ERROR_CONSTRAINT,
2449 => DB_ERROR_CONSTRAINT
);
return $MAP;
}
function adodb_error_mssql()
{
static $MAP = array(
208 => DB_ERROR_NOSUCHTABLE,
2601 => DB_ERROR_ALREADY_EXISTS
);
return $MAP;
}
function adodb_error_sqlite()
{
static $MAP = array(
1 => DB_ERROR_SYNTAX
);
return $MAP;
}
function adodb_error_mysql()
{
static $MAP = array(
1004 => DB_ERROR_CANNOT_CREATE,
1005 => DB_ERROR_CANNOT_CREATE,
1006 => DB_ERROR_CANNOT_CREATE,
1007 => DB_ERROR_ALREADY_EXISTS,
1008 => DB_ERROR_CANNOT_DROP,
1045 => DB_ERROR_ACCESS_VIOLATION,
1046 => DB_ERROR_NODBSELECTED,
1049 => DB_ERROR_NOSUCHDB,
1050 => DB_ERROR_ALREADY_EXISTS,
1051 => DB_ERROR_NOSUCHTABLE,
1054 => DB_ERROR_NOSUCHFIELD,
1062 => DB_ERROR_ALREADY_EXISTS,
1064 => DB_ERROR_SYNTAX,
1100 => DB_ERROR_NOT_LOCKED,
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
1146 => DB_ERROR_NOSUCHTABLE,
1048 => DB_ERROR_CONSTRAINT,
2002 => DB_ERROR_CONNECT_FAILED,
2005 => DB_ERROR_CONNECT_FAILED
);
return $MAP;
}
-80
View File
@@ -1,80 +0,0 @@
<?php
/**
* @version v5.20.9 21-Dec-2016
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://php.weblogs.com
*
*/
// added Claudio Bustos clbustos#entelchile.net
if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR);
if (!defined('ADODB_ERROR_HANDLER')) define('ADODB_ERROR_HANDLER','ADODB_Error_Handler');
/**
* Default Error Handler. This will be called with the following params
*
* @param $dbms the RDBMS you are connecting to
* @param $fn the name of the calling function (in uppercase)
* @param $errno the native error number from the database
* @param $errmsg the native error msg from the database
* @param $p1 $fn specific parameter - see below
* @param $p2 $fn specific parameter - see below
* @param $thisConn $current connection object - can be false if no connection object created
*/
function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection)
{
if (error_reporting() == 0) return; // obey @ protocol
switch($fn) {
case 'EXECUTE':
$sql = $p1;
$inputparams = $p2;
$s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")\n";
break;
case 'PCONNECT':
case 'CONNECT':
$host = $p1;
$database = $p2;
$s = "$dbms error: [$errno: $errmsg] in $fn($host, '****', '****', $database)\n";
break;
default:
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n";
break;
}
/*
* Log connection error somewhere
* 0 message is sent to PHP's system logger, using the Operating System's system
* logging mechanism or a file, depending on what the error_log configuration
* directive is set to.
* 1 message is sent by email to the address in the destination parameter.
* This is the only message type where the fourth parameter, extra_headers is used.
* This message type uses the same internal function as mail() does.
* 2 message is sent through the PHP debugging connection.
* This option is only available if remote debugging has been enabled.
* In this case, the destination parameter specifies the host name or IP address
* and optionally, port number, of the socket receiving the debug information.
* 3 message is appended to the file destination
*/
if (defined('ADODB_ERROR_LOG_TYPE')) {
$t = date('Y-m-d H:i:s');
if (defined('ADODB_ERROR_LOG_DEST'))
error_log("($t) $s", ADODB_ERROR_LOG_TYPE, ADODB_ERROR_LOG_DEST);
else
error_log("($t) $s", ADODB_ERROR_LOG_TYPE);
}
//print "<p>$s</p>";
trigger_error($s,ADODB_ERROR_HANDLER_TYPE);
}
-88
View File
@@ -1,88 +0,0 @@
<?php
/**
* @version v5.20.9 21-Dec-2016
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://php.weblogs.com
*
*/
include_once('PEAR.php');
if (!defined('ADODB_ERROR_HANDLER')) define('ADODB_ERROR_HANDLER','ADODB_Error_PEAR');
/*
* Enabled the following if you want to terminate scripts when an error occurs
*/
//PEAR::setErrorHandling (PEAR_ERROR_DIE);
/*
* Name of the PEAR_Error derived class to call.
*/
if (!defined('ADODB_PEAR_ERROR_CLASS')) define('ADODB_PEAR_ERROR_CLASS','PEAR_Error');
/*
* Store the last PEAR_Error object here
*/
global $ADODB_Last_PEAR_Error; $ADODB_Last_PEAR_Error = false;
/**
* Error Handler with PEAR support. This will be called with the following params
*
* @param $dbms the RDBMS you are connecting to
* @param $fn the name of the calling function (in uppercase)
* @param $errno the native error number from the database
* @param $errmsg the native error msg from the database
* @param $p1 $fn specific parameter - see below
* @param $P2 $fn specific parameter - see below
*/
function ADODB_Error_PEAR($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false)
{
global $ADODB_Last_PEAR_Error;
if (error_reporting() == 0) return; // obey @ protocol
switch($fn) {
case 'EXECUTE':
$sql = $p1;
$inputparams = $p2;
$s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")";
break;
case 'PCONNECT':
case 'CONNECT':
$host = $p1;
$database = $p2;
$s = "$dbms error: [$errno: $errmsg] in $fn('$host', ?, ?, '$database')";
break;
default:
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)";
break;
}
$class = ADODB_PEAR_ERROR_CLASS;
$ADODB_Last_PEAR_Error = new $class($s, $errno,
$GLOBALS['_PEAR_default_error_mode'],
$GLOBALS['_PEAR_default_error_options'],
$errmsg);
//print "<p>!$s</p>";
}
/**
* Returns last PEAR_Error object. This error might be for an error that
* occured several sql statements ago.
*/
function ADODB_PEAR_Error()
{
global $ADODB_Last_PEAR_Error;
return $ADODB_Last_PEAR_Error;
}
-81
View File
@@ -1,81 +0,0 @@
<?php
/**
* @version v5.20.9 21-Dec-2016
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://php.weblogs.com
*
* Exception-handling code using PHP5 exceptions (try-catch-throw).
*/
if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR);
define('ADODB_ERROR_HANDLER','adodb_throw');
class ADODB_Exception extends Exception {
var $dbms;
var $fn;
var $sql = '';
var $params = '';
var $host = '';
var $database = '';
function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
{
switch($fn) {
case 'EXECUTE':
$this->sql = is_array($p1) ? $p1[0] : $p1;
$this->params = $p2;
$s = "$dbms error: [$errno: $errmsg] in $fn(\"$this->sql\")";
break;
case 'PCONNECT':
case 'CONNECT':
$user = $thisConnection->user;
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)";
break;
default:
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)";
break;
}
$this->dbms = $dbms;
if ($thisConnection) {
$this->host = $thisConnection->host;
$this->database = $thisConnection->database;
}
$this->fn = $fn;
$this->msg = $errmsg;
if (!is_numeric($errno)) $errno = -1;
parent::__construct($s,$errno);
}
}
/**
* Default Error Handler. This will be called with the following params
*
* @param $dbms the RDBMS you are connecting to
* @param $fn the name of the calling function (in uppercase)
* @param $errno the native error number from the database
* @param $errmsg the native error msg from the database
* @param $p1 $fn specific parameter - see below
* @param $P2 $fn specific parameter - see below
*/
function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
{
global $ADODB_EXCEPTION;
if (error_reporting() == 0) return; // obey @ protocol
if (is_string($ADODB_EXCEPTION)) $errfn = $ADODB_EXCEPTION;
else $errfn = 'ADODB_EXCEPTION';
throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
}
-26
View File
@@ -1,26 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4.
Declares the ADODB Base Class for PHP5 "ADODB_BASE_RS", and supports iteration with
the ADODB_Iterator class.
$rs = $db->Execute("select * from adoxyz");
foreach($rs as $k => $v) {
echo $k; print_r($v); echo "<br>";
}
Iterator code based on http://cvs.php.net/cvs.php/php-src/ext/spl/examples/cachingiterator.inc?login=2
Moved to adodb.inc.php to improve performance.
*/
-1251
View File
@@ -1,1251 +0,0 @@
<?php
// security - hide paths
if (!defined('ADODB_DIR')) die();
global $ADODB_INCLUDED_LIB;
$ADODB_INCLUDED_LIB = 1;
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Less commonly used functions are placed here to reduce size of adodb.inc.php.
*/
function adodb_strip_order_by($sql)
{
$rez = preg_match('/(\sORDER\s+BY\s(?:[^)](?!LIMIT))*)/is', $sql, $arr);
if ($arr)
if (strpos($arr[1], '(') !== false) {
$at = strpos($sql, $arr[1]);
$cntin = 0;
for ($i=$at, $max=strlen($sql); $i < $max; $i++) {
$ch = $sql[$i];
if ($ch == '(') {
$cntin += 1;
} elseif($ch == ')') {
$cntin -= 1;
if ($cntin < 0) {
break;
}
}
}
$sql = substr($sql,0,$at).substr($sql,$i);
} else {
$sql = str_replace($arr[1], '', $sql);
}
return $sql;
}
if (false) {
$sql = 'select * from (select a from b order by a(b),b(c) desc)';
$sql = '(select * from abc order by 1)';
die(adodb_strip_order_by($sql));
}
function adodb_probetypes(&$array,&$types,$probe=8)
{
// probe and guess the type
$types = array();
if ($probe > sizeof($array)) $max = sizeof($array);
else $max = $probe;
for ($j=0;$j < $max; $j++) {
$row = $array[$j];
if (!$row) break;
$i = -1;
foreach($row as $v) {
$i += 1;
if (isset($types[$i]) && $types[$i]=='C') continue;
//print " ($i ".$types[$i]. "$v) ";
$v = trim($v);
if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
$types[$i] = 'C'; // once C, always C
continue;
}
if ($j == 0) {
// If empty string, we presume is character
// test for integer for 1st row only
// after that it is up to testing other rows to prove
// that it is not an integer
if (strlen($v) == 0) $types[$i] = 'C';
if (strpos($v,'.') !== false) $types[$i] = 'N';
else $types[$i] = 'I';
continue;
}
if (strpos($v,'.') !== false) $types[$i] = 'N';
}
}
}
function adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs)
{
$oldX = sizeof(reset($arr));
$oldY = sizeof($arr);
if ($hdr) {
$startx = 1;
$hdr = array('Fields');
for ($y = 0; $y < $oldY; $y++) {
$hdr[] = $arr[$y][0];
}
} else
$startx = 0;
for ($x = $startx; $x < $oldX; $x++) {
if ($fobjs) {
$o = $fobjs[$x];
$newarr[] = array($o->name);
} else
$newarr[] = array();
for ($y = 0; $y < $oldY; $y++) {
$newarr[$x-$startx][] = $arr[$y][$x];
}
}
}
// Force key to upper.
// See also http://www.php.net/manual/en/function.array-change-key-case.php
function _array_change_key_case($an_array)
{
if (is_array($an_array)) {
$new_array = array();
foreach($an_array as $key=>$value)
$new_array[strtoupper($key)] = $value;
return $new_array;
}
return $an_array;
}
function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
{
if (count($fieldArray) == 0) return 0;
$first = true;
$uSet = '';
if (!is_array($keyCol)) {
$keyCol = array($keyCol);
}
foreach($fieldArray as $k => $v) {
if ($v === null) {
$v = 'NULL';
$fieldArray[$k] = $v;
} else if ($autoQuote && /*!is_numeric($v) /*and strncmp($v,"'",1) !== 0 -- sql injection risk*/ strcasecmp($v,$zthis->null2null)!=0) {
$v = $zthis->qstr($v);
$fieldArray[$k] = $v;
}
if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
if ($first) {
$first = false;
$uSet = "$k=$v";
} else
$uSet .= ",$k=$v";
}
$where = false;
foreach ($keyCol as $v) {
if (isset($fieldArray[$v])) {
if ($where) $where .= ' and '.$v.'='.$fieldArray[$v];
else $where = $v.'='.$fieldArray[$v];
}
}
if ($uSet && $where) {
$update = "UPDATE $table SET $uSet WHERE $where";
$rs = $zthis->Execute($update);
if ($rs) {
if ($zthis->poorAffectedRows) {
/*
The Select count(*) wipes out any errors that the update would have returned.
http://phplens.com/lens/lensforum/msgs.php?id=5696
*/
if ($zthis->ErrorNo()<>0) return 0;
# affected_rows == 0 if update field values identical to old values
# for mysql - which is silly.
$cnt = $zthis->GetOne("select count(*) from $table where $where");
if ($cnt > 0) return 1; // record already exists
} else {
if (($zthis->Affected_Rows()>0)) return 1;
}
} else
return 0;
}
// print "<p>Error=".$this->ErrorNo().'<p>';
$first = true;
foreach($fieldArray as $k => $v) {
if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
if ($first) {
$first = false;
$iCols = "$k";
$iVals = "$v";
} else {
$iCols .= ",$k";
$iVals .= ",$v";
}
}
$insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
$rs = $zthis->Execute($insert);
return ($rs) ? 2 : 0;
}
// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
$size=0, $selectAttr='',$compareFields0=true)
{
$hasvalue = false;
if ($multiple or is_array($defstr)) {
if ($size==0) $size=5;
$attr = ' multiple size="'.$size.'"';
if (!strpos($name,'[]')) $name .= '[]';
} else if ($size) $attr = ' size="'.$size.'"';
else $attr ='';
$s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
if ($blank1stItem)
if (is_string($blank1stItem)) {
$barr = explode(':',$blank1stItem);
if (sizeof($barr) == 1) $barr[] = '';
$s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
} else $s .= "\n<option></option>";
if ($zthis->FieldCount() > 1) $hasvalue=true;
else $compareFields0 = true;
$value = '';
$optgroup = null;
$firstgroup = true;
$fieldsize = $zthis->FieldCount();
while(!$zthis->EOF) {
$zval = rtrim(reset($zthis->fields));
if ($blank1stItem && $zval=="") {
$zthis->MoveNext();
continue;
}
if ($fieldsize > 1) {
if (isset($zthis->fields[1]))
$zval2 = rtrim($zthis->fields[1]);
else
$zval2 = rtrim(next($zthis->fields));
}
$selected = ($compareFields0) ? $zval : $zval2;
$group = '';
if ($fieldsize > 2) {
$group = rtrim($zthis->fields[2]);
}
/*
if ($optgroup != $group) {
$optgroup = $group;
if ($firstgroup) {
$firstgroup = false;
$s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
} else {
$s .="\n</optgroup>";
$s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
}
}
*/
if ($hasvalue)
$value = " value='".htmlspecialchars($zval2)."'";
if (is_array($defstr)) {
if (in_array($selected,$defstr))
$s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
else
$s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
}
else {
if (strcasecmp($selected,$defstr)==0)
$s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
else
$s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
}
$zthis->MoveNext();
} // while
// closing last optgroup
if($optgroup != null) {
$s .= "\n</optgroup>";
}
return $s ."\n</select>\n";
}
// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
$size=0, $selectAttr='',$compareFields0=true)
{
$hasvalue = false;
if ($multiple or is_array($defstr)) {
if ($size==0) $size=5;
$attr = ' multiple size="'.$size.'"';
if (!strpos($name,'[]')) $name .= '[]';
} else if ($size) $attr = ' size="'.$size.'"';
else $attr ='';
$s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
if ($blank1stItem)
if (is_string($blank1stItem)) {
$barr = explode(':',$blank1stItem);
if (sizeof($barr) == 1) $barr[] = '';
$s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
} else $s .= "\n<option></option>";
if ($zthis->FieldCount() > 1) $hasvalue=true;
else $compareFields0 = true;
$value = '';
$optgroup = null;
$firstgroup = true;
$fieldsize = sizeof($zthis->fields);
while(!$zthis->EOF) {
$zval = rtrim(reset($zthis->fields));
if ($blank1stItem && $zval=="") {
$zthis->MoveNext();
continue;
}
if ($fieldsize > 1) {
if (isset($zthis->fields[1]))
$zval2 = rtrim($zthis->fields[1]);
else
$zval2 = rtrim(next($zthis->fields));
}
$selected = ($compareFields0) ? $zval : $zval2;
$group = '';
if (isset($zthis->fields[2])) {
$group = rtrim($zthis->fields[2]);
}
if ($optgroup != $group) {
$optgroup = $group;
if ($firstgroup) {
$firstgroup = false;
$s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
} else {
$s .="\n</optgroup>";
$s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
}
}
if ($hasvalue)
$value = " value='".htmlspecialchars($zval2)."'";
if (is_array($defstr)) {
if (in_array($selected,$defstr))
$s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
else
$s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
}
else {
if (strcasecmp($selected,$defstr)==0)
$s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
else
$s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
}
$zthis->MoveNext();
} // while
// closing last optgroup
if($optgroup != null) {
$s .= "\n</optgroup>";
}
return $s ."\n</select>\n";
}
/*
Count the number of records this sql statement will return by using
query rewriting heuristics...
Does not work with UNIONs, except with postgresql and oracle.
Usage:
$conn->Connect(...);
$cnt = _adodb_getcount($conn, $sql);
*/
function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
{
$qryRecs = 0;
if (!empty($zthis->_nestedSQL) || preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) ||
preg_match('/\s+GROUP\s+BY\s+/is',$sql) ||
preg_match('/\s+UNION\s+/is',$sql)) {
$rewritesql = adodb_strip_order_by($sql);
// ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
// but this is only supported by oracle and postgresql...
if ($zthis->dataProvider == 'oci8') {
// Allow Oracle hints to be used for query optimization, Chris Wrye
if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
$rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")";
} else
$rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")";
} else if (strncmp($zthis->databaseType,'postgres',8) == 0 || strncmp($zthis->databaseType,'mysql',5) == 0) {
$rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
} else {
$rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
}
} else {
// now replace SELECT ... FROM with SELECT COUNT(*) FROM
if ( strpos($sql, '_ADODB_COUNT') !== FALSE ) {
$rewritesql = preg_replace('/^\s*?SELECT\s+_ADODB_COUNT(.*)_ADODB_COUNT\s/is','SELECT COUNT(*) ',$sql);
} else {
$rewritesql = preg_replace('/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
}
// fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
// with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
// also see http://phplens.com/lens/lensforum/msgs.php?id=12752
$rewritesql = adodb_strip_order_by($rewritesql);
}
if (isset($rewritesql) && $rewritesql != $sql) {
if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
if ($secs2cache) {
// we only use half the time of secs2cache because the count can quickly
// become inaccurate if new records are added
$qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
} else {
$qryRecs = $zthis->GetOne($rewritesql,$inputarr);
}
if ($qryRecs !== false) return $qryRecs;
}
//--------------------------------------------
// query rewrite failed - so try slower way...
// strip off unneeded ORDER BY if no UNION
if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
else $rewritesql = $rewritesql = adodb_strip_order_by($sql);
if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
if ($secs2cache) {
$rstest = $zthis->CacheExecute($secs2cache,$rewritesql,$inputarr);
if (!$rstest) $rstest = $zthis->CacheExecute($secs2cache,$sql,$inputarr);
} else {
$rstest = $zthis->Execute($rewritesql,$inputarr);
if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
}
if ($rstest) {
$qryRecs = $rstest->RecordCount();
if ($qryRecs == -1) {
global $ADODB_EXTENSION;
// some databases will return -1 on MoveLast() - change to MoveNext()
if ($ADODB_EXTENSION) {
while(!$rstest->EOF) {
adodb_movenext($rstest);
}
} else {
while(!$rstest->EOF) {
$rstest->MoveNext();
}
}
$qryRecs = $rstest->_currentRow;
}
$rstest->Close();
if ($qryRecs == -1) return 0;
}
return $qryRecs;
}
/*
Code originally from "Cornel G" <conyg@fx.ro>
This code might not work with SQL that has UNION in it
Also if you are using CachePageExecute(), there is a strong possibility that
data will get out of synch. use CachePageExecute() only with tables that
rarely change.
*/
function _adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
$inputarr=false, $secs2cache=0)
{
$atfirstpage = false;
$atlastpage = false;
$lastpageno=1;
// If an invalid nrows is supplied,
// we assume a default value of 10 rows per page
if (!isset($nrows) || $nrows <= 0) $nrows = 10;
$qryRecs = false; //count records for no offset
$qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
$lastpageno = (int) ceil($qryRecs / $nrows);
$zthis->_maxRecordCount = $qryRecs;
// ***** Here we check whether $page is the last page or
// whether we are trying to retrieve
// a page number greater than the last page number.
if ($page >= $lastpageno) {
$page = $lastpageno;
$atlastpage = true;
}
// If page number <= 1, then we are at the first page
if (empty($page) || $page <= 1) {
$page = 1;
$atfirstpage = true;
}
// We get the data we want
$offset = $nrows * ($page-1);
if ($secs2cache > 0)
$rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
else
$rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
// Before returning the RecordSet, we set the pagination properties we need
if ($rsreturn) {
$rsreturn->_maxRecordCount = $qryRecs;
$rsreturn->rowsPerPage = $nrows;
$rsreturn->AbsolutePage($page);
$rsreturn->AtFirstPage($atfirstpage);
$rsreturn->AtLastPage($atlastpage);
$rsreturn->LastPageNo($lastpageno);
}
return $rsreturn;
}
// Iván Oliva version
function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
{
$atfirstpage = false;
$atlastpage = false;
if (!isset($page) || $page <= 1) {
// If page number <= 1, then we are at the first page
$page = 1;
$atfirstpage = true;
}
if ($nrows <= 0) {
// If an invalid nrows is supplied, we assume a default value of 10 rows per page
$nrows = 10;
}
$pagecounteroffset = ($page * $nrows) - $nrows;
// To find out if there are more pages of rows, simply increase the limit or
// nrows by 1 and see if that number of records was returned. If it was,
// then we know there is at least one more page left, otherwise we are on
// the last page. Therefore allow non-Count() paging with single queries
// rather than three queries as was done before.
$test_nrows = $nrows + 1;
if ($secs2cache > 0) {
$rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
} else {
$rsreturn = $zthis->SelectLimit($sql, $test_nrows, $pagecounteroffset, $inputarr, $secs2cache);
}
// Now check to see if the number of rows returned was the higher value we asked for or not.
if ( $rsreturn->_numOfRows == $test_nrows ) {
// Still at least 1 more row, so we are not on last page yet...
// Remove the last row from the RS.
$rsreturn->_numOfRows = ( $rsreturn->_numOfRows - 1 );
} elseif ( $rsreturn->_numOfRows == 0 && $page > 1 ) {
// Likely requested a page that doesn't exist, so need to find the last
// page and return it. Revert to original method and loop through pages
// until we find some data...
$pagecounter = $page + 1;
$pagecounteroffset = ($pagecounter * $nrows) - $nrows;
$rstest = $rsreturn;
if ($rstest) {
while ($rstest && $rstest->EOF && $pagecounter > 0) {
$atlastpage = true;
$pagecounter--;
$pagecounteroffset = $nrows * ($pagecounter - 1);
$rstest->Close();
if ($secs2cache>0) {
$rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
}
else {
$rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
}
}
if ($rstest) $rstest->Close();
}
if ($atlastpage) {
// If we are at the last page or beyond it, we are going to retrieve it
$page = $pagecounter;
if ($page == 1) {
// We have to do this again in case the last page is the same as
// the first page, that is, the recordset has only 1 page.
$atfirstpage = true;
}
}
// We get the data we want
$offset = $nrows * ($page-1);
if ($secs2cache > 0) {
$rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
}
else {
$rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
}
} elseif ( $rsreturn->_numOfRows < $test_nrows ) {
// Rows is less than what we asked for, so must be at the last page.
$atlastpage = true;
}
// Before returning the RecordSet, we set the pagination properties we need
if ($rsreturn) {
$rsreturn->rowsPerPage = $nrows;
$rsreturn->AbsolutePage($page);
$rsreturn->AtFirstPage($atfirstpage);
$rsreturn->AtLastPage($atlastpage);
}
return $rsreturn;
}
function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
{
global $ADODB_QUOTE_FIELDNAMES;
if (!$rs) {
printf(ADODB_BAD_RS,'GetUpdateSQL');
return false;
}
$fieldUpdatedCount = 0;
$arrFields = _array_change_key_case($arrFields);
$hasnumeric = isset($rs->fields[0]);
$setFields = '';
// Loop through all of the fields in the recordset
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
// Get the field from the recordset
$field = $rs->FetchField($i);
// If the recordset field is one
// of the fields passed in then process.
$upperfname = strtoupper($field->name);
if (adodb_key_exists($upperfname,$arrFields,$force)) {
// If the existing field value in the recordset
// is different from the value passed in then
// go ahead and append the field name and new value to
// the update query.
if ($hasnumeric) $val = $rs->fields[$i];
else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname];
else if (isset($rs->fields[$field->name])) $val = $rs->fields[$field->name];
else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)];
else $val = '';
if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
// Set the counter for the number of fields that will be updated.
$fieldUpdatedCount++;
// Based on the datatype of the field
// Format the value properly for the database
$type = $rs->MetaType($field->type);
if ($type == 'null') {
$type = 'C';
}
if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
switch ($ADODB_QUOTE_FIELDNAMES) {
case 'LOWER':
$fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
case 'NATIVE':
$fnameq = $zthis->nameQuote.$field->name.$zthis->nameQuote;break;
case 'UPPER':
default:
$fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;break;
}
} else
$fnameq = $upperfname;
//********************************************************//
if (is_null($arrFields[$upperfname])
|| (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
|| $arrFields[$upperfname] === $zthis->null2null
)
{
switch ($force) {
//case 0:
// //Ignore empty values. This is allready handled in "adodb_key_exists" function.
//break;
case 1:
//Set null
$setFields .= $field->name . " = null, ";
break;
case 2:
//Set empty
$arrFields[$upperfname] = "";
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
break;
default:
case 3:
//Set the value that was given in array, so you can give both null and empty values
if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
$setFields .= $field->name . " = null, ";
} else {
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
}
break;
}
//********************************************************//
} else {
//we do this so each driver can customize the sql for
//DB specific column types.
//Oracle needs BLOB types to be handled with a returning clause
//postgres has special needs as well
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
$arrFields, $magicq);
}
}
}
}
// If there were any modified fields then build the rest of the update query.
if ($fieldUpdatedCount > 0 || $forceUpdate) {
// Get the table name from the existing query.
if (!empty($rs->tableName)) $tableName = $rs->tableName;
else {
preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
$tableName = $tableName[1];
}
// Get the full where clause excluding the word "WHERE" from
// the existing query.
preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
$discard = false;
// not a good hack, improvements?
if ($whereClause) {
#var_dump($whereClause);
if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
else preg_match('/\s.*(\) WHERE .*)/is', $whereClause[1], $discard); # see http://sourceforge.net/tracker/index.php?func=detail&aid=1379638&group_id=42718&atid=433976
} else
$whereClause = array(false,false);
if ($discard)
$whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
$sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
if (strlen($whereClause[1]) > 0)
$sql .= ' WHERE '.$whereClause[1];
return $sql;
} else {
return false;
}
}
function adodb_key_exists($key, &$arr,$force=2)
{
if ($force<=0) {
// the following is the old behaviour where null or empty fields are ignored
return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
}
if (isset($arr[$key])) return true;
## null check below
if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
return false;
}
/**
* There is a special case of this function for the oci8 driver.
* The proper way to handle an insert w/ a blob in oracle requires
* a returning clause with bind variables and a descriptor blob.
*
*
*/
function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
{
static $cacheRS = false;
static $cacheSig = 0;
static $cacheCols;
global $ADODB_QUOTE_FIELDNAMES;
$tableName = '';
$values = '';
$fields = '';
$recordSet = null;
$arrFields = _array_change_key_case($arrFields);
$fieldInsertedCount = 0;
if (is_string($rs)) {
//ok we have a table name
//try and get the column info ourself.
$tableName = $rs;
//we need an object for the recordSet
//because we have to call MetaType.
//php can't do a $rsclass::MetaType()
$rsclass = $zthis->rsPrefix.$zthis->databaseType;
$recordSet = new $rsclass(-1,$zthis->fetchMode);
$recordSet->connection = $zthis;
if (is_string($cacheRS) && $cacheRS == $rs) {
$columns = $cacheCols;
} else {
$columns = $zthis->MetaColumns( $tableName );
$cacheRS = $tableName;
$cacheCols = $columns;
}
} else if (is_subclass_of($rs, 'adorecordset')) {
if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
$columns = $cacheCols;
} else {
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
$columns[] = $rs->FetchField($i);
$cacheRS = $cacheSig;
$cacheCols = $columns;
$rs->insertSig = $cacheSig++;
}
$recordSet = $rs;
} else {
printf(ADODB_BAD_RS,'GetInsertSQL');
return false;
}
// Loop through all of the fields in the recordset
foreach( $columns as $field ) {
$upperfname = strtoupper($field->name);
if (adodb_key_exists($upperfname,$arrFields,$force)) {
$bad = false;
if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
switch ($ADODB_QUOTE_FIELDNAMES) {
case 'LOWER':
$fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
case 'NATIVE':
$fnameq = $zthis->nameQuote.$field->name.$zthis->nameQuote;break;
case 'UPPER':
default:
$fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;break;
}
} else
$fnameq = $upperfname;
$type = $recordSet->MetaType($field->type);
/********************************************************/
if (is_null($arrFields[$upperfname])
|| (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
|| $arrFields[$upperfname] === $zthis->null2null
)
{
switch ($force) {
case 0: // we must always set null if missing
$bad = true;
break;
case 1:
$values .= "null, ";
break;
case 2:
//Set empty
$arrFields[$upperfname] = "";
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
break;
default:
case 3:
//Set the value that was given in array, so you can give both null and empty values
if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
$values .= "null, ";
} else {
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
}
break;
} // switch
/*********************************************************/
} else {
//we do this so each driver can customize the sql for
//DB specific column types.
//Oracle needs BLOB types to be handled with a returning clause
//postgres has special needs as well
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
$arrFields, $magicq);
}
if ($bad) continue;
// Set the counter for the number of fields that will be inserted.
$fieldInsertedCount++;
// Get the name of the fields to insert
$fields .= $fnameq . ", ";
}
}
// If there were any inserted fields then build the rest of the insert query.
if ($fieldInsertedCount <= 0) return false;
// Get the table name from the existing query.
if (!$tableName) {
if (!empty($rs->tableName)) $tableName = $rs->tableName;
else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
$tableName = $tableName[1];
else
return false;
}
// Strip off the comma and space on the end of both the fields
// and their values.
$fields = substr($fields, 0, -2);
$values = substr($values, 0, -2);
// Append the fields and their values to the insert query.
return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
}
/**
* This private method is used to help construct
* the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
* It handles the string construction of 1 column -> sql string based on
* the column type. We want to do 'safe' handling of BLOBs
*
* @param string the type of sql we are trying to create
* 'I' or 'U'.
* @param string column data type from the db::MetaType() method
* @param string the column name
* @param array the column value
*
* @return string
*
*/
function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
{
$sql = '';
// Based on the datatype of the field
// Format the value properly for the database
switch($type) {
case 'B':
//in order to handle Blobs correctly, we need
//to do some magic for Oracle
//we need to create a new descriptor to handle
//this properly
if (!empty($zthis->hasReturningInto)) {
if ($action == 'I') {
$sql = 'empty_blob(), ';
} else {
$sql = $fnameq. '=empty_blob(), ';
}
//add the variable to the returning clause array
//so the user can build this later in
//case they want to add more to it
$zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
} else if (empty($arrFields[$fname])){
if ($action == 'I') {
$sql = 'empty_blob(), ';
} else {
$sql = $fnameq. '=empty_blob(), ';
}
} else {
//this is to maintain compatibility
//with older adodb versions.
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
}
break;
case "X":
//we need to do some more magic here for long variables
//to handle these correctly in oracle.
//create a safe bind var name
//to avoid conflicts w/ dupes.
if (!empty($zthis->hasReturningInto)) {
if ($action == 'I') {
$sql = ':xx'.$fname.'xx, ';
} else {
$sql = $fnameq.'=:xx'.$fname.'xx, ';
}
//add the variable to the returning clause array
//so the user can build this later in
//case they want to add more to it
$zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
} else {
//this is to maintain compatibility
//with older adodb versions.
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
}
break;
default:
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
break;
}
return $sql;
}
function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
{
if ($recurse) {
switch($zthis->dataProvider) {
case 'postgres':
if ($type == 'L') $type = 'C';
break;
case 'oci8':
return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
}
}
switch($type) {
case "C":
case "X":
case 'B':
$val = $zthis->qstr($arrFields[$fname],$magicq);
break;
case "D":
$val = $zthis->DBDate($arrFields[$fname]);
break;
case "T":
$val = $zthis->DBTimeStamp($arrFields[$fname]);
break;
case "N":
$val = $arrFields[$fname];
if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val);
break;
case "I":
case "R":
$val = $arrFields[$fname];
if (!is_numeric($val)) $val = (integer) $val;
break;
default:
$val = str_replace(array("'"," ","("),"",$arrFields[$fname]); // basic sql injection defence
if (empty($val)) $val = '0';
break;
}
if ($action == 'I') return $val . ", ";
return $fnameq . "=" . $val . ", ";
}
function _adodb_debug_execute(&$zthis, $sql, $inputarr)
{
$ss = '';
if ($inputarr) {
foreach($inputarr as $kk=>$vv) {
if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
if (is_null($vv)) $ss .= "($kk=>null) ";
else $ss .= "($kk=>'$vv') ";
}
$ss = "[ $ss ]";
}
$sqlTxt = is_array($sql) ? $sql[0] : $sql;
/*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
$sqlTxt = str_replace(',',', ',$sqlTxt);
$sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
*/
// check if running from browser or command-line
$inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
$dbt = $zthis->databaseType;
if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType;
if ($inBrowser) {
if ($ss) {
$ss = '<code>'.htmlspecialchars($ss).'</code>';
}
if ($zthis->debug === -1)
ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<br>\n",false);
else if ($zthis->debug !== -99)
ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
} else {
$ss = "\n ".$ss;
if ($zthis->debug !== -99)
ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt." $ss\n-----<hr>\n",false);
}
$qID = $zthis->_query($sql,$inputarr);
/*
Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
*/
if ($zthis->databaseType == 'mssql') {
// ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
if($emsg = $zthis->ErrorMsg()) {
if ($err = $zthis->ErrorNo()) {
if ($zthis->debug === -99)
ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
ADOConnection::outp($err.': '.$emsg);
}
}
} else if (!$qID) {
if ($zthis->debug === -99)
if ($inBrowser) ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
else ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt."$ss\n-----<hr>\n",false);
ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
}
if ($zthis->debug === 99) _adodb_backtrace(true,9999,2);
return $qID;
}
# pretty print the debug_backtrace function
function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0,$ishtml=null)
{
if (!function_exists('debug_backtrace')) return '';
if ($ishtml === null) $html = (isset($_SERVER['HTTP_USER_AGENT']));
else $html = $ishtml;
$fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
$MAXSTRLEN = 128;
$s = ($html) ? '<pre align=left>' : '';
if (is_array($printOrArr)) $traceArr = $printOrArr;
else $traceArr = debug_backtrace();
array_shift($traceArr);
array_shift($traceArr);
$tabs = sizeof($traceArr)-2;
foreach ($traceArr as $arr) {
if ($skippy) {$skippy -= 1; continue;}
$levels -= 1;
if ($levels < 0) break;
$args = array();
for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' &nbsp; ' : "\t";
$tabs -= 1;
if ($html) $s .= '<font face="Courier New,Courier">';
if (isset($arr['class'])) $s .= $arr['class'].'.';
if (isset($arr['args']))
foreach($arr['args'] as $v) {
if (is_null($v)) $args[] = 'null';
else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
else if (is_object($v)) $args[] = 'Object:'.get_class($v);
else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
else {
$v = (string) @$v;
$str = htmlspecialchars(str_replace(array("\r","\n"),' ',substr($v,0,$MAXSTRLEN)));
if (strlen($v) > $MAXSTRLEN) $str .= '...';
$args[] = $str;
}
}
$s .= $arr['function'].'('.implode(', ',$args).')';
$s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
$s .= "\n";
}
if ($html) $s .= '</pre>';
if ($printOrArr) print $s;
return $s;
}
/*
function _adodb_find_from($sql)
{
$sql = str_replace(array("\n","\r"), ' ', $sql);
$charCount = strlen($sql);
$inString = false;
$quote = '';
$parentheseCount = 0;
$prevChars = '';
$nextChars = '';
for($i = 0; $i < $charCount; $i++) {
$char = substr($sql,$i,1);
$prevChars = substr($sql,0,$i);
$nextChars = substr($sql,$i+1);
if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) {
$quote = $char;
$inString = true;
}
elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) {
$quote = "";
$inString = false;
}
elseif($char == "(" && $inString === false)
$parentheseCount++;
elseif($char == ")" && $inString === false && $parentheseCount > 0)
$parentheseCount--;
elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM")
return $i;
}
}
*/
-190
View File
@@ -1,190 +0,0 @@
<?php
// security - hide paths
if (!defined('ADODB_DIR')) die();
global $ADODB_INCLUDED_MEMCACHE;
$ADODB_INCLUDED_MEMCACHE = 1;
global $ADODB_INCLUDED_CSV;
if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Usage:
$db = NewADOConnection($driver);
$db->memCache = true; /// should we use memCache instead of caching in files
$db->memCacheHost = array($ip1, $ip2, $ip3);
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)
$db->Connect(...);
$db->CacheExecute($sql);
Note the memcache class is shared by all connections, is created during the first call to Connect/PConnect.
Class instance is stored in $ADODB_CACHE
*/
class ADODB_Cache_MemCache {
var $createdir = false; // create caching directory structure?
//-----------------------------
// memcache specific variables
var $hosts; // array of hosts
var $port = 11211;
var $compress = false; // memcache compression with zlib
var $_connected = false;
var $_memcache = false;
function __construct(&$obj)
{
$this->hosts = $obj->memCacheHost;
$this->port = $obj->memCachePort;
$this->compress = $obj->memCacheCompress;
}
// implement as lazy connection. The connection only occurs on CacheExecute call
function connect(&$err)
{
if (!function_exists('memcache_pconnect')) {
$err = 'Memcache module PECL extension not found!';
return false;
}
$memcache = new MemCache;
if (!is_array($this->hosts)) $this->hosts = array($this->hosts);
$failcnt = 0;
foreach($this->hosts as $host) {
if (!@$memcache->addServer($host,$this->port,true)) {
$failcnt += 1;
}
}
if ($failcnt == sizeof($this->hosts)) {
$err = 'Can\'t connect to any memcache server';
return false;
}
$this->_connected = true;
$this->_memcache = $memcache;
return true;
}
// returns true or false. true if successful save
function writecache($filename, $contents, $debug, $secs2cache)
{
if (!$this->_connected) {
$err = '';
if (!$this->connect($err) && $debug) ADOConnection::outp($err);
}
if (!$this->_memcache) return false;
if (!$this->_memcache->set($filename, $contents, $this->compress ? MEMCACHE_COMPRESSED : 0, $secs2cache)) {
if ($debug) ADOConnection::outp(" Failed to save data at the memcached server!<br>\n");
return false;
}
return true;
}
// returns a recordset
function readcache($filename, &$err, $secs2cache, $rsClass)
{
$false = false;
if (!$this->_connected) $this->connect($err);
if (!$this->_memcache) return $false;
$rs = $this->_memcache->get($filename);
if (!$rs) {
$err = 'Item with such key doesn\'t exists on the memcached server.';
return $false;
}
// hack, should actually use _csv2rs
$rs = explode("\n", $rs);
unset($rs[0]);
$rs = join("\n", $rs);
$rs = unserialize($rs);
if (! is_object($rs)) {
$err = 'Unable to unserialize $rs';
return $false;
}
if ($rs->timeCreated == 0) return $rs; // apparently have been reports that timeCreated was set to 0 somewhere
$tdiff = intval($rs->timeCreated+$secs2cache - time());
if ($tdiff <= 2) {
switch($tdiff) {
case 2:
if ((rand() & 15) == 0) {
$err = "Timeout 2";
return $false;
}
break;
case 1:
if ((rand() & 3) == 0) {
$err = "Timeout 1";
return $false;
}
break;
default:
$err = "Timeout 0";
return $false;
}
}
return $rs;
}
function flushall($debug=false)
{
if (!$this->_connected) {
$err = '';
if (!$this->connect($err) && $debug) ADOConnection::outp($err);
}
if (!$this->_memcache) return false;
$del = $this->_memcache->flush();
if ($debug)
if (!$del) ADOConnection::outp("flushall: failed!<br>\n");
else ADOConnection::outp("flushall: succeeded!<br>\n");
return $del;
}
function flushcache($filename, $debug=false)
{
if (!$this->_connected) {
$err = '';
if (!$this->connect($err) && $debug) ADOConnection::outp($err);
}
if (!$this->_memcache) return false;
$del = $this->_memcache->delete($filename);
if ($debug)
if (!$del) ADOConnection::outp("flushcache: $key entry doesn't exist on memcached server!<br>\n");
else ADOConnection::outp("flushcache: $key entry flushed from memcached server!<br>\n");
return $del;
}
// not used for memcache
function createdir($dir, $hash)
{
return true;
}
}
-289
View File
@@ -1,289 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
This class provides recordset pagination with
First/Prev/Next/Last links.
Feel free to modify this class for your own use as
it is very basic. To learn how to use it, see the
example in adodb/tests/testpaging.php.
"Pablo Costa" <pablo@cbsp.com.br> implemented Render_PageLinks().
Please note, this class is entirely unsupported,
and no free support requests except for bug reports
will be entertained by the author.
*/
class ADODB_Pager {
var $id; // unique id for pager (defaults to 'adodb')
var $db; // ADODB connection object
var $sql; // sql used
var $rs; // recordset generated
var $curr_page; // current page number before Render() called, calculated in constructor
var $rows; // number of rows per page
var $linksPerPage=10; // number of links per page in navigation bar
var $showPageLinks;
var $gridAttributes = 'width=100% border=1 bgcolor=white';
// Localize text strings here
var $first = '<code>|&lt;</code>';
var $prev = '<code>&lt;&lt;</code>';
var $next = '<code>>></code>';
var $last = '<code>>|</code>';
var $moreLinks = '...';
var $startLinks = '...';
var $gridHeader = false;
var $htmlSpecialChars = true;
var $page = 'Page';
var $linkSelectedColor = 'red';
var $cache = 0; #secs to cache with CachePageExecute()
//----------------------------------------------
// constructor
//
// $db adodb connection object
// $sql sql statement
// $id optional id to identify which pager,
// if you have multiple on 1 page.
// $id should be only be [a-z0-9]*
//
function __construct(&$db,$sql,$id = 'adodb', $showPageLinks = false)
{
global $PHP_SELF;
$curr_page = $id.'_curr_page';
if (!empty($PHP_SELF)) $PHP_SELF = htmlspecialchars($_SERVER['PHP_SELF']); // htmlspecialchars() to prevent XSS attacks
$this->sql = $sql;
$this->id = $id;
$this->db = $db;
$this->showPageLinks = $showPageLinks;
$next_page = $id.'_next_page';
if (isset($_GET[$next_page])) {
$_SESSION[$curr_page] = (integer) $_GET[$next_page];
}
if (empty($_SESSION[$curr_page])) $_SESSION[$curr_page] = 1; ## at first page
$this->curr_page = $_SESSION[$curr_page];
}
//---------------------------
// Display link to first page
function Render_First($anchor=true)
{
global $PHP_SELF;
if ($anchor) {
?>
<a href="<?php echo $PHP_SELF,'?',$this->id;?>_next_page=1"><?php echo $this->first;?></a> &nbsp;
<?php
} else {
print "$this->first &nbsp; ";
}
}
//--------------------------
// Display link to next page
function render_next($anchor=true)
{
global $PHP_SELF;
if ($anchor) {
?>
<a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->AbsolutePage() + 1 ?>"><?php echo $this->next;?></a> &nbsp;
<?php
} else {
print "$this->next &nbsp; ";
}
}
//------------------
// Link to last page
//
// for better performance with large recordsets, you can set
// $this->db->pageExecuteCountRows = false, which disables
// last page counting.
function render_last($anchor=true)
{
global $PHP_SELF;
if (!$this->db->pageExecuteCountRows) return;
if ($anchor) {
?>
<a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->LastPageNo() ?>"><?php echo $this->last;?></a> &nbsp;
<?php
} else {
print "$this->last &nbsp; ";
}
}
//---------------------------------------------------
// original code by "Pablo Costa" <pablo@cbsp.com.br>
function render_pagelinks()
{
global $PHP_SELF;
$pages = $this->rs->LastPageNo();
$linksperpage = $this->linksPerPage ? $this->linksPerPage : $pages;
for($i=1; $i <= $pages; $i+=$linksperpage)
{
if($this->rs->AbsolutePage() >= $i)
{
$start = $i;
}
}
$numbers = '';
$end = $start+$linksperpage-1;
$link = $this->id . "_next_page";
if($end > $pages) $end = $pages;
if ($this->startLinks && $start > 1) {
$pos = $start - 1;
$numbers .= "<a href=$PHP_SELF?$link=$pos>$this->startLinks</a> ";
}
for($i=$start; $i <= $end; $i++) {
if ($this->rs->AbsolutePage() == $i)
$numbers .= "<font color=$this->linkSelectedColor><b>$i</b></font> ";
else
$numbers .= "<a href=$PHP_SELF?$link=$i>$i</a> ";
}
if ($this->moreLinks && $end < $pages)
$numbers .= "<a href=$PHP_SELF?$link=$i>$this->moreLinks</a> ";
print $numbers . ' &nbsp; ';
}
// Link to previous page
function render_prev($anchor=true)
{
global $PHP_SELF;
if ($anchor) {
?>
<a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->AbsolutePage() - 1 ?>"><?php echo $this->prev;?></a> &nbsp;
<?php
} else {
print "$this->prev &nbsp; ";
}
}
//--------------------------------------------------------
// Simply rendering of grid. You should override this for
// better control over the format of the grid
//
// We use output buffering to keep code clean and readable.
function RenderGrid()
{
global $gSQLBlockRows; // used by rs2html to indicate how many rows to display
include_once(ADODB_DIR.'/tohtml.inc.php');
ob_start();
$gSQLBlockRows = $this->rows;
rs2html($this->rs,$this->gridAttributes,$this->gridHeader,$this->htmlSpecialChars);
$s = ob_get_contents();
ob_end_clean();
return $s;
}
//-------------------------------------------------------
// Navigation bar
//
// we use output buffering to keep the code easy to read.
function RenderNav()
{
ob_start();
if (!$this->rs->AtFirstPage()) {
$this->Render_First();
$this->Render_Prev();
} else {
$this->Render_First(false);
$this->Render_Prev(false);
}
if ($this->showPageLinks){
$this->Render_PageLinks();
}
if (!$this->rs->AtLastPage()) {
$this->Render_Next();
$this->Render_Last();
} else {
$this->Render_Next(false);
$this->Render_Last(false);
}
$s = ob_get_contents();
ob_end_clean();
return $s;
}
//-------------------
// This is the footer
function RenderPageCount()
{
if (!$this->db->pageExecuteCountRows) return '';
$lastPage = $this->rs->LastPageNo();
if ($lastPage == -1) $lastPage = 1; // check for empty rs.
if ($this->curr_page > $lastPage) $this->curr_page = 1;
return "<font size=-1>$this->page ".$this->curr_page."/".$lastPage."</font>";
}
//-----------------------------------
// Call this class to draw everything.
function Render($rows=10)
{
global $ADODB_COUNTRECS;
$this->rows = $rows;
if ($this->db->dataProvider == 'informix') $this->db->cursorType = IFX_SCROLL;
$savec = $ADODB_COUNTRECS;
if ($this->db->pageExecuteCountRows) $ADODB_COUNTRECS = true;
if ($this->cache)
$rs = $this->db->CachePageExecute($this->cache,$this->sql,$rows,$this->curr_page);
else
$rs = $this->db->PageExecute($this->sql,$rows,$this->curr_page);
$ADODB_COUNTRECS = $savec;
$this->rs = $rs;
if (!$rs) {
print "<h3>Query failed: $this->sql</h3>";
return;
}
if (!$rs->EOF && (!$rs->AtFirstPage() || !$rs->AtLastPage()))
$header = $this->RenderNav();
else
$header = "&nbsp;";
$grid = $this->RenderGrid();
$footer = $this->RenderPageCount();
$this->RenderLayout($header,$grid,$footer);
$rs->Close();
$this->rs = false;
}
//------------------------------------------------------
// override this to control overall layout and formating
function RenderLayout($header,$grid,$footer,$attributes='border=1 bgcolor=beige')
{
echo "<table ".$attributes."><tr><td>",
$header,
"</td></tr><tr><td>",
$grid,
"</td></tr><tr><td>",
$footer,
"</td></tr></table>";
}
}
-370
View File
@@ -1,370 +0,0 @@
<?php
/**
* @version v5.20.9 21-Dec-2016
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
* PEAR DB Emulation Layer for ADODB.
*
* The following code is modelled on PEAR DB code by Stig Bakken <ssb@fast.no> |
* and Tomas V.V.Cox <cox@idecnet.com>. Portions (c)1997-2002 The PHP Group.
*/
/*
We support:
DB_Common
---------
query - returns PEAR_Error on error
limitQuery - return PEAR_Error on error
prepare - does not return PEAR_Error on error
execute - does not return PEAR_Error on error
setFetchMode - supports ASSOC and ORDERED
errorNative
quote
nextID
disconnect
getOne
getAssoc
getRow
getCol
getAll
DB_Result
---------
numRows - returns -1 if not supported
numCols
fetchInto - does not support passing of fetchmode
fetchRows - does not support passing of fetchmode
free
*/
define('ADODB_PEAR',dirname(__FILE__));
include_once "PEAR.php";
include_once ADODB_PEAR."/adodb-errorpear.inc.php";
include_once ADODB_PEAR."/adodb.inc.php";
if (!defined('DB_OK')) {
define("DB_OK", 1);
define("DB_ERROR",-1);
/**
* This is a special constant that tells DB the user hasn't specified
* any particular get mode, so the default should be used.
*/
define('DB_FETCHMODE_DEFAULT', 0);
/**
* Column data indexed by numbers, ordered from 0 and up
*/
define('DB_FETCHMODE_ORDERED', 1);
/**
* Column data indexed by column names
*/
define('DB_FETCHMODE_ASSOC', 2);
/* for compatibility */
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
/**
* these are constants for the tableInfo-function
* they are bitwised or'ed. so if there are more constants to be defined
* in the future, adjust DB_TABLEINFO_FULL accordingly
*/
define('DB_TABLEINFO_ORDER', 1);
define('DB_TABLEINFO_ORDERTABLE', 2);
define('DB_TABLEINFO_FULL', 3);
}
/**
* The main "DB" class is simply a container class with some static
* methods for creating DB objects as well as some utility functions
* common to all parts of DB.
*
*/
class DB
{
/**
* Create a new DB object for the specified database type
*
* @param $type string database type, for example "mysql"
*
* @return object a newly created DB object, or a DB error code on
* error
*/
function factory($type)
{
include_once(ADODB_DIR."/drivers/adodb-$type.inc.php");
$obj = NewADOConnection($type);
if (!is_object($obj)) $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
return $obj;
}
/**
* Create a new DB object and connect to the specified database
*
* @param $dsn mixed "data source name", see the DB::parseDSN
* method for a description of the dsn format. Can also be
* specified as an array of the format returned by DB::parseDSN.
*
* @param $options mixed if boolean (or scalar), tells whether
* this connection should be persistent (for backends that support
* this). This parameter can also be an array of options, see
* DB_common::setOption for more information on connection
* options.
*
* @return object a newly created DB connection object, or a DB
* error object on error
*
* @see DB::parseDSN
* @see DB::isError
*/
function connect($dsn, $options = false)
{
if (is_array($dsn)) {
$dsninfo = $dsn;
} else {
$dsninfo = DB::parseDSN($dsn);
}
switch ($dsninfo["phptype"]) {
case 'pgsql': $type = 'postgres7'; break;
case 'ifx': $type = 'informix9'; break;
default: $type = $dsninfo["phptype"]; break;
}
if (is_array($options) && isset($options["debug"]) &&
$options["debug"] >= 2) {
// expose php errors with sufficient debug level
@include_once("adodb-$type.inc.php");
} else {
@include_once("adodb-$type.inc.php");
}
@$obj = NewADOConnection($type);
if (!is_object($obj)) {
$obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
return $obj;
}
if (is_array($options)) {
foreach($options as $k => $v) {
switch(strtolower($k)) {
case 'persist':
case 'persistent': $persist = $v; break;
#ibase
case 'dialect': $obj->dialect = $v; break;
case 'charset': $obj->charset = $v; break;
case 'buffers': $obj->buffers = $v; break;
#ado
case 'charpage': $obj->charPage = $v; break;
#mysql
case 'clientflags': $obj->clientFlags = $v; break;
}
}
} else {
$persist = false;
}
if (isset($dsninfo['socket'])) $dsninfo['hostspec'] .= ':'.$dsninfo['socket'];
else if (isset($dsninfo['port'])) $dsninfo['hostspec'] .= ':'.$dsninfo['port'];
if($persist) $ok = $obj->PConnect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']);
else $ok = $obj->Connect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']);
if (!$ok) $obj = ADODB_PEAR_Error();
return $obj;
}
/**
* Return the DB API version
*
* @return int the DB API version number
*/
function apiVersion()
{
return 2;
}
/**
* Tell whether a result code from a DB method is an error
*
* @param $value int result code
*
* @return bool whether $value is an error
*/
function isError($value)
{
if (!is_object($value)) return false;
$class = strtolower(get_class($value));
return $class == 'pear_error' || is_subclass_of($value, 'pear_error') ||
$class == 'db_error' || is_subclass_of($value, 'db_error');
}
/**
* Tell whether a result code from a DB method is a warning.
* Warnings differ from errors in that they are generated by DB,
* and are not fatal.
*
* @param $value mixed result value
*
* @return bool whether $value is a warning
*/
function isWarning($value)
{
return false;
/*
return is_object($value) &&
(get_class( $value ) == "db_warning" ||
is_subclass_of($value, "db_warning"));*/
}
/**
* Parse a data source name
*
* @param $dsn string Data Source Name to be parsed
*
* @return array an associative array with the following keys:
*
* phptype: Database backend used in PHP (mysql, odbc etc.)
* dbsyntax: Database used with regards to SQL syntax etc.
* protocol: Communication protocol to use (tcp, unix etc.)
* hostspec: Host specification (hostname[:port])
* database: Database to use on the DBMS server
* username: User name for login
* password: Password for login
*
* The format of the supplied DSN is in its fullest form:
*
* phptype(dbsyntax)://username:password@protocol+hostspec/database
*
* Most variations are allowed:
*
* phptype://username:password@protocol+hostspec:110//usr/db_file.db
* phptype://username:password@hostspec/database_name
* phptype://username:password@hostspec
* phptype://username@hostspec
* phptype://hostspec/database
* phptype://hostspec
* phptype(dbsyntax)
* phptype
*
* @author Tomas V.V.Cox <cox@idecnet.com>
*/
function parseDSN($dsn)
{
if (is_array($dsn)) {
return $dsn;
}
$parsed = array(
'phptype' => false,
'dbsyntax' => false,
'protocol' => false,
'hostspec' => false,
'database' => false,
'username' => false,
'password' => false
);
// Find phptype and dbsyntax
if (($pos = strpos($dsn, '://')) !== false) {
$str = substr($dsn, 0, $pos);
$dsn = substr($dsn, $pos + 3);
} else {
$str = $dsn;
$dsn = NULL;
}
// Get phptype and dbsyntax
// $str => phptype(dbsyntax)
if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
$parsed['phptype'] = $arr[1];
$parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2];
} else {
$parsed['phptype'] = $str;
$parsed['dbsyntax'] = $str;
}
if (empty($dsn)) {
return $parsed;
}
// Get (if found): username and password
// $dsn => username:password@protocol+hostspec/database
if (($at = strpos($dsn,'@')) !== false) {
$str = substr($dsn, 0, $at);
$dsn = substr($dsn, $at + 1);
if (($pos = strpos($str, ':')) !== false) {
$parsed['username'] = urldecode(substr($str, 0, $pos));
$parsed['password'] = urldecode(substr($str, $pos + 1));
} else {
$parsed['username'] = urldecode($str);
}
}
// Find protocol and hostspec
// $dsn => protocol+hostspec/database
if (($pos=strpos($dsn, '/')) !== false) {
$str = substr($dsn, 0, $pos);
$dsn = substr($dsn, $pos + 1);
} else {
$str = $dsn;
$dsn = NULL;
}
// Get protocol + hostspec
// $str => protocol+hostspec
if (($pos=strpos($str, '+')) !== false) {
$parsed['protocol'] = substr($str, 0, $pos);
$parsed['hostspec'] = urldecode(substr($str, $pos + 1));
} else {
$parsed['hostspec'] = urldecode($str);
}
// Get dabase if any
// $dsn => database
if (!empty($dsn)) {
$parsed['database'] = $dsn;
}
return $parsed;
}
/**
* Load a PHP database extension if it is not loaded already.
*
* @access public
*
* @param $name the base name of the extension (without the .so or
* .dll suffix)
*
* @return bool true if the extension was already or successfully
* loaded, false if it could not be loaded
*/
function assertExtension($name)
{
if (!extension_loaded($name)) {
$dlext = (strncmp(PHP_OS,'WIN',3) === 0) ? '.dll' : '.so';
@dl($name . $dlext);
}
if (!extension_loaded($name)) {
return false;
}
return true;
}
}
-1099
View File
@@ -1,1099 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Library for basic performance monitoring and tuning.
My apologies if you see code mixed with presentation. The presentation suits
my needs. If you want to separate code from presentation, be my guest. Patches
are welcome.
*/
if (!defined('ADODB_DIR')) include_once(dirname(__FILE__).'/adodb.inc.php');
include_once(ADODB_DIR.'/tohtml.inc.php');
define( 'ADODB_OPT_HIGH', 2);
define( 'ADODB_OPT_LOW', 1);
global $ADODB_PERF_MIN;
$ADODB_PERF_MIN = 0.05; // log only if >= minimum number of secs to run
// returns in K the memory of current process, or 0 if not known
function adodb_getmem()
{
if (function_exists('memory_get_usage'))
return (integer) ((memory_get_usage()+512)/1024);
$pid = getmypid();
if ( strncmp(strtoupper(PHP_OS),'WIN',3)==0) {
$output = array();
exec('tasklist /FI "PID eq ' . $pid. '" /FO LIST', $output);
return substr($output[5], strpos($output[5], ':') + 1);
}
/* Hopefully UNIX */
exec("ps --pid $pid --no-headers -o%mem,size", $output);
if (sizeof($output) == 0) return 0;
$memarr = explode(' ',$output[0]);
if (sizeof($memarr)>=2) return (integer) $memarr[1];
return 0;
}
// avoids localization problems where , is used instead of .
function adodb_round($n,$prec)
{
return number_format($n, $prec, '.', '');
}
/* obsolete: return microtime value as a float. Retained for backward compat */
function adodb_microtime()
{
return microtime(true);
}
/* sql code timing */
function adodb_log_sql(&$connx,$sql,$inputarr)
{
$perf_table = adodb_perf::table();
$connx->fnExecute = false;
$a0 = microtime(true);
$rs = $connx->Execute($sql,$inputarr);
$a1 = microtime(true);
if (!empty($connx->_logsql) && (empty($connx->_logsqlErrors) || !$rs)) {
global $ADODB_LOG_CONN;
if (!empty($ADODB_LOG_CONN)) {
$conn = $ADODB_LOG_CONN;
if ($conn->databaseType != $connx->databaseType)
$prefix = '/*dbx='.$connx->databaseType .'*/ ';
else
$prefix = '';
} else {
$conn = $connx;
$prefix = '';
}
$conn->_logsql = false; // disable logsql error simulation
$dbT = $conn->databaseType;
$time = $a1 - $a0;
if (!$rs) {
$errM = $connx->ErrorMsg();
$errN = $connx->ErrorNo();
$conn->lastInsID = 0;
$tracer = substr('ERROR: '.htmlspecialchars($errM),0,250);
} else {
$tracer = '';
$errM = '';
$errN = 0;
$dbg = $conn->debug;
$conn->debug = false;
if (!is_object($rs) || $rs->dataProvider == 'empty')
$conn->_affected = $conn->affected_rows(true);
$conn->lastInsID = @$conn->Insert_ID();
$conn->debug = $dbg;
}
if (isset($_SERVER['HTTP_HOST'])) {
$tracer .= '<br>'.$_SERVER['HTTP_HOST'];
if (isset($_SERVER['PHP_SELF'])) $tracer .= htmlspecialchars($_SERVER['PHP_SELF']);
} else
if (isset($_SERVER['PHP_SELF'])) $tracer .= '<br>'.htmlspecialchars($_SERVER['PHP_SELF']);
//$tracer .= (string) adodb_backtrace(false);
$tracer = (string) substr($tracer,0,500);
if (is_array($inputarr)) {
if (is_array(reset($inputarr))) $params = 'Array sizeof='.sizeof($inputarr);
else {
// Quote string parameters so we can see them in the
// performance stats. This helps spot disabled indexes.
$xar_params = $inputarr;
foreach ($xar_params as $xar_param_key => $xar_param) {
if (gettype($xar_param) == 'string')
$xar_params[$xar_param_key] = '"' . $xar_param . '"';
}
$params = implode(', ', $xar_params);
if (strlen($params) >= 3000) $params = substr($params, 0, 3000);
}
} else {
$params = '';
}
if (is_array($sql)) $sql = $sql[0];
if ($prefix) $sql = $prefix.$sql;
$arr = array('b'=>strlen($sql).'.'.crc32($sql),
'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>adodb_round($time,6));
//var_dump($arr);
$saved = $conn->debug;
$conn->debug = 0;
$d = $conn->sysTimeStamp;
if (empty($d)) $d = date("'Y-m-d H:i:s'");
if ($conn->dataProvider == 'oci8' && $dbT != 'oci8po') {
$isql = "insert into $perf_table values($d,:b,:c,:d,:e,:f)";
} else if ($dbT == 'odbc_mssql' || $dbT == 'informix' || strncmp($dbT,'odbtp',4)==0) {
$timer = $arr['f'];
if ($dbT == 'informix') $sql2 = substr($sql2,0,230);
$sql1 = $conn->qstr($arr['b']);
$sql2 = $conn->qstr($arr['c']);
$params = $conn->qstr($arr['d']);
$tracer = $conn->qstr($arr['e']);
$isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values($d,$sql1,$sql2,$params,$tracer,$timer)";
if ($dbT == 'informix') $isql = str_replace(chr(10),' ',$isql);
$arr = false;
} else {
if ($dbT == 'db2') $arr['f'] = (float) $arr['f'];
$isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $d,?,?,?,?,?)";
}
global $ADODB_PERF_MIN;
if ($errN != 0 || $time >= $ADODB_PERF_MIN) {
$ok = $conn->Execute($isql,$arr);
} else
$ok = true;
$conn->debug = $saved;
if ($ok) {
$conn->_logsql = true;
} else {
$err2 = $conn->ErrorMsg();
$conn->_logsql = true; // enable logsql error simulation
$perf = NewPerfMonitor($conn);
if ($perf) {
if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr);
} else {
$ok = $conn->Execute("create table $perf_table (
created varchar(50),
sql0 varchar(250),
sql1 varchar(4000),
params varchar(3000),
tracer varchar(500),
timer decimal(16,6))");
}
if (!$ok) {
ADOConnection::outp( "<p><b>LOGSQL Insert Failed</b>: $isql<br>$err2</p>");
$conn->_logsql = false;
}
}
$connx->_errorMsg = $errM;
$connx->_errorCode = $errN;
}
$connx->fnExecute = 'adodb_log_sql';
return $rs;
}
/*
The settings data structure is an associative array that database parameter per element.
Each database parameter element in the array is itself an array consisting of:
0: category code, used to group related db parameters
1: either
a. sql string to retrieve value, eg. "select value from v\$parameter where name='db_block_size'",
b. array holding sql string and field to look for, e.g. array('show variables','table_cache'),
c. a string prefixed by =, then a PHP method of the class is invoked,
e.g. to invoke $this->GetIndexValue(), set this array element to '=GetIndexValue',
2: description of the database parameter
*/
class adodb_perf {
var $conn;
var $color = '#F0F0F0';
var $table = '<table border=1 bgcolor=white>';
var $titles = '<tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Description</b></td></tr>';
var $warnRatio = 90;
var $tablesSQL = false;
var $cliFormat = "%32s => %s \r\n";
var $sql1 = 'sql1'; // used for casting sql1 to text for mssql
var $explain = true;
var $helpurl = '<a href="http://adodb.sourceforge.net/docs-adodb.htm#logsql">LogSQL help</a>';
var $createTableSQL = false;
var $maxLength = 2000;
// Sets the tablename to be used
static function table($newtable = false)
{
static $_table;
if (!empty($newtable)) $_table = $newtable;
if (empty($_table)) $_table = 'adodb_logsql';
return $_table;
}
// returns array with info to calculate CPU Load
function _CPULoad()
{
/*
cpu 524152 2662 2515228 336057010
cpu0 264339 1408 1257951 168025827
cpu1 259813 1254 1257277 168031181
page 622307 25475680
swap 24 1891
intr 890153570 868093576 6 0 4 4 0 6 1 2 0 0 0 124 0 8098760 2 13961053 0 0 0 0 0 0 0 0 0 0 0 0 0 16 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
disk_io: (3,0):(3144904,54369,610378,3090535,50936192) (3,1):(3630212,54097,633016,3576115,50951320)
ctxt 66155838
btime 1062315585
processes 69293
*/
// Algorithm is taken from
// http://social.technet.microsoft.com/Forums/en-US/winservergen/thread/414b0e1b-499c-411e-8a02-6a12e339c0f1/
if (strncmp(PHP_OS,'WIN',3)==0) {
if (PHP_VERSION == '5.0.0') return false;
if (PHP_VERSION == '5.0.1') return false;
if (PHP_VERSION == '5.0.2') return false;
if (PHP_VERSION == '5.0.3') return false;
if (PHP_VERSION == '4.3.10') return false; # see http://bugs.php.net/bug.php?id=31737
static $FAIL = false;
if ($FAIL) return false;
$objName = "winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\CIMV2";
$myQuery = "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name = '_Total'";
try {
@$objWMIService = new COM($objName);
if (!$objWMIService) {
$FAIL = true;
return false;
}
$info[0] = -1;
$info[1] = 0;
$info[2] = 0;
$info[3] = 0;
foreach($objWMIService->ExecQuery($myQuery) as $objItem) {
$info[0] = $objItem->PercentProcessorTime();
}
} catch(Exception $e) {
$FAIL = true;
echo $e->getMessage();
return false;
}
return $info;
}
// Algorithm - Steve Blinch (BlitzAffe Online, http://www.blitzaffe.com)
$statfile = '/proc/stat';
if (!file_exists($statfile)) return false;
$fd = fopen($statfile,"r");
if (!$fd) return false;
$statinfo = explode("\n",fgets($fd, 1024));
fclose($fd);
foreach($statinfo as $line) {
$info = explode(" ",$line);
if($info[0]=="cpu") {
array_shift($info); // pop off "cpu"
if(!$info[0]) array_shift($info); // pop off blank space (if any)
return $info;
}
}
return false;
}
/* NOT IMPLEMENTED */
function MemInfo()
{
/*
total: used: free: shared: buffers: cached:
Mem: 1055289344 917299200 137990144 0 165437440 599773184
Swap: 2146775040 11055104 2135719936
MemTotal: 1030556 kB
MemFree: 134756 kB
MemShared: 0 kB
Buffers: 161560 kB
Cached: 581384 kB
SwapCached: 4332 kB
Active: 494468 kB
Inact_dirty: 322856 kB
Inact_clean: 24256 kB
Inact_target: 168316 kB
HighTotal: 131064 kB
HighFree: 1024 kB
LowTotal: 899492 kB
LowFree: 133732 kB
SwapTotal: 2096460 kB
SwapFree: 2085664 kB
Committed_AS: 348732 kB
*/
}
/*
Remember that this is client load, not db server load!
*/
var $_lastLoad;
function CPULoad()
{
$info = $this->_CPULoad();
if (!$info) return false;
if (strncmp(PHP_OS,'WIN',3)==0) {
return (integer) $info[0];
}else {
if (empty($this->_lastLoad)) {
sleep(1);
$this->_lastLoad = $info;
$info = $this->_CPULoad();
}
$last = $this->_lastLoad;
$this->_lastLoad = $info;
$d_user = $info[0] - $last[0];
$d_nice = $info[1] - $last[1];
$d_system = $info[2] - $last[2];
$d_idle = $info[3] - $last[3];
//printf("Delta - User: %f Nice: %f System: %f Idle: %f<br>",$d_user,$d_nice,$d_system,$d_idle);
$total=$d_user+$d_nice+$d_system+$d_idle;
if ($total<1) $total=1;
return 100*($d_user+$d_nice+$d_system)/$total;
}
}
function Tracer($sql)
{
$perf_table = adodb_perf::table();
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
$sqlq = $this->conn->qstr($sql);
$arr = $this->conn->GetArray(
"select count(*),tracer
from $perf_table where sql1=$sqlq
group by tracer
order by 1 desc");
$s = '';
if ($arr) {
$s .= '<h3>Scripts Affected</h3>';
foreach($arr as $k) {
$s .= sprintf("%4d",$k[0]).' &nbsp; '.strip_tags($k[1]).'<br>';
}
}
if (isset($savem)) $this->conn->SetFetchMode($savem);
$ADODB_CACHE_MODE = $save;
$this->conn->fnExecute = $saveE;
return $s;
}
/*
Explain Plan for $sql.
If only a snippet of the $sql is passed in, then $partial will hold the crc32 of the
actual sql.
*/
function Explain($sql,$partial=false)
{
return false;
}
function InvalidSQL($numsql = 10)
{
if (isset($_GET['sql'])) return;
$s = '<h3>Invalid SQL</h3>';
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
$perf_table = adodb_perf::table();
$rs = $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
$this->conn->fnExecute = $saveE;
if ($rs) {
$s .= rs2html($rs,false,false,false,false);
} else
return "<p>$this->helpurl. ".$this->conn->ErrorMsg()."</p>";
return $s;
}
/*
This script identifies the longest running SQL
*/
function _SuspiciousSQL($numsql = 10)
{
global $ADODB_FETCH_MODE;
$perf_table = adodb_perf::table();
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
if (isset($_GET['exps']) && isset($_GET['sql'])) {
$partial = !empty($_GET['part']);
echo "<a name=explain></a>".$this->Explain($_GET['sql'],$partial)."\n";
}
if (isset($_GET['sql'])) return;
$sql1 = $this->sql1;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
//$this->conn->debug=1;
$rs = $this->conn->SelectLimit(
"select avg(timer) as avg_timer,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
from $perf_table
where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
and (tracer is null or tracer not like 'ERROR:%')
group by sql1
order by 1 desc",$numsql);
if (isset($savem)) $this->conn->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
$this->conn->fnExecute = $saveE;
if (!$rs) return "<p>$this->helpurl. ".$this->conn->ErrorMsg()."</p>";
$s = "<h3>Suspicious SQL</h3>
<font size=1>The following SQL have high average execution times</font><br>
<table border=1 bgcolor=white><tr><td><b>Avg Time</b><td><b>Count</b><td><b>SQL</b><td><b>Max</b><td><b>Min</b></tr>\n";
$max = $this->maxLength;
while (!$rs->EOF) {
$sql = $rs->fields[1];
$raw = urlencode($sql);
if (strlen($raw)>$max-100) {
$sql2 = substr($sql,0,$max-500);
$raw = urlencode($sql2).'&part='.crc32($sql);
}
$prefix = "<a target=sql".rand()." href=\"?hidem=1&exps=1&sql=".$raw."&x#explain\">";
$suffix = "</a>";
if ($this->explain == false || strlen($prefix)>$max) {
$suffix = ' ... <i>String too long for GET parameter: '.strlen($prefix).'</i>';
$prefix = '';
}
$s .= "<tr><td>".adodb_round($rs->fields[0],6)."<td align=right>".$rs->fields[2]."<td><font size=-1>".$prefix.htmlspecialchars($sql).$suffix."</font>".
"<td>".$rs->fields[3]."<td>".$rs->fields[4]."</tr>";
$rs->MoveNext();
}
return $s."</table>";
}
function CheckMemory()
{
return '';
}
function SuspiciousSQL($numsql=10)
{
return adodb_perf::_SuspiciousSQL($numsql);
}
function ExpensiveSQL($numsql=10)
{
return adodb_perf::_ExpensiveSQL($numsql);
}
/*
This reports the percentage of load on the instance due to the most
expensive few SQL statements. Tuning these statements can often
make huge improvements in overall system performance.
*/
function _ExpensiveSQL($numsql = 10)
{
global $ADODB_FETCH_MODE;
$perf_table = adodb_perf::table();
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
if (isset($_GET['expe']) && isset($_GET['sql'])) {
$partial = !empty($_GET['part']);
echo "<a name=explain></a>".$this->Explain($_GET['sql'],$partial)."\n";
}
if (isset($_GET['sql'])) return;
$sql1 = $this->sql1;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
$rs = $this->conn->SelectLimit(
"select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
from $perf_table
where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
and (tracer is null or tracer not like 'ERROR:%')
group by sql1
having count(*)>1
order by 1 desc",$numsql);
if (isset($savem)) $this->conn->SetFetchMode($savem);
$this->conn->fnExecute = $saveE;
$ADODB_FETCH_MODE = $save;
if (!$rs) return "<p>$this->helpurl. ".$this->conn->ErrorMsg()."</p>";
$s = "<h3>Expensive SQL</h3>
<font size=1>Tuning the following SQL could reduce the server load substantially</font><br>
<table border=1 bgcolor=white><tr><td><b>Load</b><td><b>Count</b><td><b>SQL</b><td><b>Max</b><td><b>Min</b></tr>\n";
$max = $this->maxLength;
while (!$rs->EOF) {
$sql = $rs->fields[1];
$raw = urlencode($sql);
if (strlen($raw)>$max-100) {
$sql2 = substr($sql,0,$max-500);
$raw = urlencode($sql2).'&part='.crc32($sql);
}
$prefix = "<a target=sqle".rand()." href=\"?hidem=1&expe=1&sql=".$raw."&x#explain\">";
$suffix = "</a>";
if($this->explain == false || strlen($prefix>$max)) {
$prefix = '';
$suffix = '';
}
$s .= "<tr><td>".adodb_round($rs->fields[0],6)."<td align=right>".$rs->fields[2]."<td><font size=-1>".$prefix.htmlspecialchars($sql).$suffix."</font>".
"<td>".$rs->fields[3]."<td>".$rs->fields[4]."</tr>";
$rs->MoveNext();
}
return $s."</table>";
}
/*
Raw function to return parameter value from $settings.
*/
function DBParameter($param)
{
if (empty($this->settings[$param])) return false;
$sql = $this->settings[$param][1];
return $this->_DBParameter($sql);
}
/*
Raw function returning array of poll paramters
*/
function PollParameters()
{
$arr[0] = (float)$this->DBParameter('data cache hit ratio');
$arr[1] = (float)$this->DBParameter('data reads');
$arr[2] = (float)$this->DBParameter('data writes');
$arr[3] = (integer) $this->DBParameter('current connections');
return $arr;
}
/*
Low-level Get Database Parameter
*/
function _DBParameter($sql)
{
$savelog = $this->conn->LogSQL(false);
if (is_array($sql)) {
global $ADODB_FETCH_MODE;
$sql1 = $sql[0];
$key = $sql[1];
if (sizeof($sql)>2) $pos = $sql[2];
else $pos = 1;
if (sizeof($sql)>3) $coef = $sql[3];
else $coef = false;
$ret = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
$rs = $this->conn->Execute($sql1);
if (isset($savem)) $this->conn->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ($rs) {
while (!$rs->EOF) {
$keyf = reset($rs->fields);
if (trim($keyf) == $key) {
$ret = $rs->fields[$pos];
if ($coef) $ret *= $coef;
break;
}
$rs->MoveNext();
}
$rs->Close();
}
$this->conn->LogSQL($savelog);
return $ret;
} else {
if (strncmp($sql,'=',1) == 0) {
$fn = substr($sql,1);
return $this->$fn();
}
$sql = str_replace('$DATABASE',$this->conn->database,$sql);
$ret = $this->conn->GetOne($sql);
$this->conn->LogSQL($savelog);
return $ret;
}
}
/*
Warn if cache ratio falls below threshold. Displayed in "Description" column.
*/
function WarnCacheRatio($val)
{
if ($val < $this->warnRatio)
return '<font color=red><b>Cache ratio should be at least '.$this->warnRatio.'%</b></font>';
else return '';
}
function clearsql()
{
$perf_table = adodb_perf::table();
$this->conn->Execute("delete from $perf_table where created<".$this->conn->sysTimeStamp);
}
/***********************************************************************************************/
// HIGH LEVEL UI FUNCTIONS
/***********************************************************************************************/
function UI($pollsecs=5)
{
global $ADODB_LOG_CONN;
$perf_table = adodb_perf::table();
$conn = $this->conn;
$app = $conn->host;
if ($conn->host && $conn->database) $app .= ', db=';
$app .= $conn->database;
if ($app) $app .= ', ';
$savelog = $this->conn->LogSQL(false);
$info = $conn->ServerInfo();
if (isset($_GET['clearsql'])) {
$this->clearsql();
}
$this->conn->LogSQL($savelog);
// magic quotes
if (isset($_GET['sql']) && get_magic_quotes_gpc()) {
$_GET['sql'] = $_GET['sql'] = str_replace(array("\\'",'\"'),array("'",'"'),$_GET['sql']);
}
if (!isset($_SESSION['ADODB_PERF_SQL'])) $nsql = $_SESSION['ADODB_PERF_SQL'] = 10;
else $nsql = $_SESSION['ADODB_PERF_SQL'];
$app .= $info['description'];
if (isset($_GET['do'])) $do = $_GET['do'];
else if (isset($_POST['do'])) $do = $_POST['do'];
else if (isset($_GET['sql'])) $do = 'viewsql';
else $do = 'stats';
if (isset($_GET['nsql'])) {
if ($_GET['nsql'] > 0) $nsql = $_SESSION['ADODB_PERF_SQL'] = (integer) $_GET['nsql'];
}
echo "<title>ADOdb Performance Monitor on $app</title><body bgcolor=white>";
if ($do == 'viewsql') $form = "<td><form># SQL:<input type=hidden value=viewsql name=do> <input type=text size=4 name=nsql value=$nsql><input type=submit value=Go></td></form>";
else $form = "<td>&nbsp;</td>";
$allowsql = !defined('ADODB_PERF_NO_RUN_SQL');
global $ADODB_PERF_MIN;
$app .= " (Min sql timing \$ADODB_PERF_MIN=$ADODB_PERF_MIN secs)";
if (empty($_GET['hidem']))
echo "<table border=1 width=100% bgcolor=lightyellow><tr><td colspan=2>
<b><a href=http://adodb.sourceforge.net/?perf=1>ADOdb</a> Performance Monitor</b> <font size=1>for $app</font></tr><tr><td>
<a href=?do=stats><b>Performance Stats</b></a> &nbsp; <a href=?do=viewsql><b>View SQL</b></a>
&nbsp; <a href=?do=tables><b>View Tables</b></a> &nbsp; <a href=?do=poll><b>Poll Stats</b></a>",
$allowsql ? ' &nbsp; <a href=?do=dosql><b>Run SQL</b></a>' : '',
"$form",
"</tr></table>";
switch ($do) {
default:
case 'stats':
if (empty($ADODB_LOG_CONN))
echo "<p>&nbsp; <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br>";
echo $this->HealthCheck();
//$this->conn->debug=1;
echo $this->CheckMemory();
break;
case 'poll':
$self = htmlspecialchars($_SERVER['PHP_SELF']);
echo "<iframe width=720 height=80%
src=\"{$self}?do=poll2&hidem=1\"></iframe>";
break;
case 'poll2':
echo "<pre>";
$this->Poll($pollsecs);
break;
case 'dosql':
if (!$allowsql) break;
$this->DoSQLForm();
break;
case 'viewsql':
if (empty($_GET['hidem']))
echo "&nbsp; <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br>";
echo($this->SuspiciousSQL($nsql));
echo($this->ExpensiveSQL($nsql));
echo($this->InvalidSQL($nsql));
break;
case 'tables':
echo $this->Tables(); break;
}
global $ADODB_vers;
echo "<p><div align=center><font size=1>$ADODB_vers Sponsored by <a href=http://phplens.com/>phpLens</a></font></div>";
}
/*
Runs in infinite loop, returning real-time statistics
*/
function Poll($secs=5)
{
$this->conn->fnExecute = false;
//$this->conn->debug=1;
if ($secs <= 1) $secs = 1;
echo "Accumulating statistics, every $secs seconds...\n";flush();
$arro = $this->PollParameters();
$cnt = 0;
set_time_limit(0);
sleep($secs);
while (1) {
$arr = $this->PollParameters();
$hits = sprintf('%2.2f',$arr[0]);
$reads = sprintf('%12.4f',($arr[1]-$arro[1])/$secs);
$writes = sprintf('%12.4f',($arr[2]-$arro[2])/$secs);
$sess = sprintf('%5d',$arr[3]);
$load = $this->CPULoad();
if ($load !== false) {
$oslabel = 'WS-CPU%';
$osval = sprintf(" %2.1f ",(float) $load);
}else {
$oslabel = '';
$osval = '';
}
if ($cnt % 10 == 0) echo " Time ".$oslabel." Hit% Sess Reads/s Writes/s\n";
$cnt += 1;
echo date('H:i:s').' '.$osval."$hits $sess $reads $writes\n";
flush();
if (connection_aborted()) return;
sleep($secs);
$arro = $arr;
}
}
/*
Returns basic health check in a command line interface
*/
function HealthCheckCLI()
{
return $this->HealthCheck(true);
}
/*
Returns basic health check as HTML
*/
function HealthCheck($cli=false)
{
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
if ($cli) $html = '';
else $html = $this->table.'<tr><td colspan=3><h3>'.$this->conn->databaseType.'</h3></td></tr>'.$this->titles;
$oldc = false;
$bgc = '';
foreach($this->settings as $name => $arr) {
if ($arr === false) break;
if (!is_string($name)) {
if ($cli) $html .= " -- $arr -- \n";
else $html .= "<tr bgcolor=$this->color><td colspan=3><i>$arr</i> &nbsp;</td></tr>";
continue;
}
if (!is_array($arr)) break;
$category = $arr[0];
$how = $arr[1];
if (sizeof($arr)>2) $desc = $arr[2];
else $desc = ' &nbsp; ';
if ($category == 'HIDE') continue;
$val = $this->_DBParameter($how);
if ($desc && strncmp($desc,"=",1) === 0) {
$fn = substr($desc,1);
$desc = $this->$fn($val);
}
if ($val === false) {
$m = $this->conn->ErrorMsg();
$val = "Error: $m";
} else {
if (is_numeric($val) && $val >= 256*1024) {
if ($val % (1024*1024) == 0) {
$val /= (1024*1024);
$val .= 'M';
} else if ($val % 1024 == 0) {
$val /= 1024;
$val .= 'K';
}
//$val = htmlspecialchars($val);
}
}
if ($category != $oldc) {
$oldc = $category;
//$bgc = ($bgc == ' bgcolor='.$this->color) ? ' bgcolor=white' : ' bgcolor='.$this->color;
}
if (strlen($desc)==0) $desc = '&nbsp;';
if (strlen($val)==0) $val = '&nbsp;';
if ($cli) {
$html .= str_replace('&nbsp;','',sprintf($this->cliFormat,strip_tags($name),strip_tags($val),strip_tags($desc)));
}else {
$html .= "<tr$bgc><td>".$name.'</td><td>'.$val.'</td><td>'.$desc."</td></tr>\n";
}
}
if (!$cli) $html .= "</table>\n";
$this->conn->fnExecute = $saveE;
return $html;
}
function Tables($orderby='1')
{
if (!$this->tablesSQL) return false;
$savelog = $this->conn->LogSQL(false);
$rs = $this->conn->Execute($this->tablesSQL.' order by '.$orderby);
$this->conn->LogSQL($savelog);
$html = rs2html($rs,false,false,false,false);
return $html;
}
function CreateLogTable()
{
if (!$this->createTableSQL) return false;
$table = $this->table();
$sql = str_replace('adodb_logsql',$table,$this->createTableSQL);
$savelog = $this->conn->LogSQL(false);
$ok = $this->conn->Execute($sql);
$this->conn->LogSQL($savelog);
return ($ok) ? true : false;
}
function DoSQLForm()
{
$PHP_SELF = htmlspecialchars($_SERVER['PHP_SELF']);
$sql = isset($_REQUEST['sql']) ? $_REQUEST['sql'] : '';
if (isset($_SESSION['phplens_sqlrows'])) $rows = $_SESSION['phplens_sqlrows'];
else $rows = 3;
if (isset($_REQUEST['SMALLER'])) {
$rows /= 2;
if ($rows < 3) $rows = 3;
$_SESSION['phplens_sqlrows'] = $rows;
}
if (isset($_REQUEST['BIGGER'])) {
$rows *= 2;
$_SESSION['phplens_sqlrows'] = $rows;
}
?>
<form method="POST" action="<?php echo $PHP_SELF ?>">
<table><tr>
<td> Form size: <input type="submit" value=" &lt; " name="SMALLER"><input type="submit" value=" &gt; &gt; " name="BIGGER">
</td>
<td align=right>
<input type="submit" value=" Run SQL Below " name="RUN"><input type=hidden name=do value=dosql>
</td></tr>
<tr>
<td colspan=2><textarea rows=<?php print $rows; ?> name="sql" cols="80"><?php print htmlspecialchars($sql) ?></textarea>
</td>
</tr>
</table>
</form>
<?php
if (!isset($_REQUEST['sql'])) return;
$sql = $this->undomq(trim($sql));
if (substr($sql,strlen($sql)-1) === ';') {
$print = true;
$sqla = $this->SplitSQL($sql);
} else {
$print = false;
$sqla = array($sql);
}
foreach($sqla as $sqls) {
if (!$sqls) continue;
if ($print) {
print "<p>".htmlspecialchars($sqls)."</p>";
flush();
}
$savelog = $this->conn->LogSQL(false);
$rs = $this->conn->Execute($sqls);
$this->conn->LogSQL($savelog);
if ($rs && is_object($rs) && !$rs->EOF) {
rs2html($rs);
while ($rs->NextRecordSet()) {
print "<table width=98% bgcolor=#C0C0FF><tr><td>&nbsp;</td></tr></table>";
rs2html($rs);
}
} else {
$e1 = (integer) $this->conn->ErrorNo();
$e2 = $this->conn->ErrorMsg();
if (($e1) || ($e2)) {
if (empty($e1)) $e1 = '-1'; // postgresql fix
print ' &nbsp; '.$e1.': '.$e2;
} else {
print "<p>No Recordset returned<br></p>";
}
}
} // foreach
}
function SplitSQL($sql)
{
$arr = explode(';',$sql);
return $arr;
}
function undomq($m)
{
if (get_magic_quotes_gpc()) {
// undo the damage
$m = str_replace('\\\\','\\',$m);
$m = str_replace('\"','"',$m);
$m = str_replace('\\\'','\'',$m);
}
return $m;
}
/************************************************************************/
/**
* Reorganise multiple table-indices/statistics/..
* OptimizeMode could be given by last Parameter
*
* @example
* <pre>
* optimizeTables( 'tableA');
* </pre>
* <pre>
* optimizeTables( 'tableA', 'tableB', 'tableC');
* </pre>
* <pre>
* optimizeTables( 'tableA', 'tableB', ADODB_OPT_LOW);
* </pre>
*
* @param string table name of the table to optimize
* @param int mode optimization-mode
* <code>ADODB_OPT_HIGH</code> for full optimization
* <code>ADODB_OPT_LOW</code> for CPU-less optimization
* Default is LOW <code>ADODB_OPT_LOW</code>
* @author Markus Staab
* @return Returns <code>true</code> on success and <code>false</code> on error
*/
function OptimizeTables()
{
$args = func_get_args();
$numArgs = func_num_args();
if ( $numArgs == 0) return false;
$mode = ADODB_OPT_LOW;
$lastArg = $args[ $numArgs - 1];
if ( !is_string($lastArg)) {
$mode = $lastArg;
unset( $args[ $numArgs - 1]);
}
foreach( $args as $table) {
$this->optimizeTable( $table, $mode);
}
}
/**
* Reorganise the table-indices/statistics/.. depending on the given mode.
* Default Implementation throws an error.
*
* @param string table name of the table to optimize
* @param int mode optimization-mode
* <code>ADODB_OPT_HIGH</code> for full optimization
* <code>ADODB_OPT_LOW</code> for CPU-less optimization
* Default is LOW <code>ADODB_OPT_LOW</code>
* @author Markus Staab
* @return Returns <code>true</code> on success and <code>false</code> on error
*/
function OptimizeTable( $table, $mode = ADODB_OPT_LOW)
{
ADOConnection::outp( sprintf( "<p>%s: '%s' not implemented for driver '%s'</p>", __CLASS__, __FUNCTION__, $this->conn->databaseType));
return false;
}
/**
* Reorganise current database.
* Default implementation loops over all <code>MetaTables()</code> and
* optimize each using <code>optmizeTable()</code>
*
* @author Markus Staab
* @return Returns <code>true</code> on success and <code>false</code> on error
*/
function optimizeDatabase()
{
$conn = $this->conn;
if ( !$conn) return false;
$tables = $conn->MetaTables( 'TABLES');
if ( !$tables ) return false;
foreach( $tables as $table) {
if ( !$this->optimizeTable( $table)) {
return false;
}
}
return true;
}
// end hack
}
-16
View File
@@ -1,16 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4.
*/
class ADODB_BASE_RS {
}
-1462
View File
@@ -1,1462 +0,0 @@
<?php
/*
ADOdb Date Library, part of the ADOdb abstraction library
Download: http://adodb.sourceforge.net/#download
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
PHP native date functions use integer timestamps for computations.
Because of this, dates are restricted to the years 1901-2038 on Unix
and 1970-2038 on Windows due to integer overflow for dates beyond
those years. This library overcomes these limitations by replacing the
native function's signed integers (normally 32-bits) with PHP floating
point numbers (normally 64-bits).
Dates from 100 A.D. to 3000 A.D. and later
have been tested. The minimum is 100 A.D. as <100 will invoke the
2 => 4 digit year conversion. The maximum is billions of years in the
future, but this is a theoretical limit as the computation of that year
would take too long with the current implementation of adodb_mktime().
This library replaces native functions as follows:
<pre>
getdate() with adodb_getdate()
date() with adodb_date()
gmdate() with adodb_gmdate()
mktime() with adodb_mktime()
gmmktime() with adodb_gmmktime()
strftime() with adodb_strftime()
strftime() with adodb_gmstrftime()
</pre>
The parameters are identical, except that adodb_date() accepts a subset
of date()'s field formats. Mktime() will convert from local time to GMT,
and date() will convert from GMT to local time, but daylight savings is
not handled currently.
This library is independant of the rest of ADOdb, and can be used
as standalone code.
PERFORMANCE
For high speed, this library uses the native date functions where
possible, and only switches to PHP code when the dates fall outside
the 32-bit signed integer range.
GREGORIAN CORRECTION
Pope Gregory shortened October of A.D. 1582 by ten days. Thursday,
October 4, 1582 (Julian) was followed immediately by Friday, October 15,
1582 (Gregorian).
Since 0.06, we handle this correctly, so:
adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)
== 24 * 3600 (1 day)
=============================================================================
COPYRIGHT
(c) 2003-2014 John Lim and released under BSD-style license except for code by
jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year
and originally found at http://www.php.net/manual/en/function.mktime.php
=============================================================================
BUG REPORTS
These should be posted to the ADOdb forums at
http://phplens.com/lens/lensforum/topics.php?id=4
=============================================================================
FUNCTION DESCRIPTIONS
** FUNCTION adodb_time()
Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) as an unsigned integer.
** FUNCTION adodb_getdate($date=false)
Returns an array containing date information, as getdate(), but supports
dates greater than 1901 to 2038. The local date/time format is derived from a
heuristic the first time adodb_getdate is called.
** FUNCTION adodb_date($fmt, $timestamp = false)
Convert a timestamp to a formatted local date. If $timestamp is not defined, the
current timestamp is used. Unlike the function date(), it supports dates
outside the 1901 to 2038 range.
The format fields that adodb_date supports:
<pre>
a - "am" or "pm"
A - "AM" or "PM"
d - day of the month, 2 digits with leading zeros; i.e. "01" to "31"
D - day of the week, textual, 3 letters; e.g. "Fri"
F - month, textual, long; e.g. "January"
g - hour, 12-hour format without leading zeros; i.e. "1" to "12"
G - hour, 24-hour format without leading zeros; i.e. "0" to "23"
h - hour, 12-hour format; i.e. "01" to "12"
H - hour, 24-hour format; i.e. "00" to "23"
i - minutes; i.e. "00" to "59"
j - day of the month without leading zeros; i.e. "1" to "31"
l (lowercase 'L') - day of the week, textual, long; e.g. "Friday"
L - boolean for whether it is a leap year; i.e. "0" or "1"
m - month; i.e. "01" to "12"
M - month, textual, 3 letters; e.g. "Jan"
n - month without leading zeros; i.e. "1" to "12"
O - Difference to Greenwich time in hours; e.g. "+0200"
Q - Quarter, as in 1, 2, 3, 4
r - RFC 2822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200"
s - seconds; i.e. "00" to "59"
S - English ordinal suffix for the day of the month, 2 characters;
i.e. "st", "nd", "rd" or "th"
t - number of days in the given month; i.e. "28" to "31"
T - Timezone setting of this machine; e.g. "EST" or "MDT"
U - seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
w - day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday)
Y - year, 4 digits; e.g. "1999"
y - year, 2 digits; e.g. "99"
z - day of the year; i.e. "0" to "365"
Z - timezone offset in seconds (i.e. "-43200" to "43200").
The offset for timezones west of UTC is always negative,
and for those east of UTC is always positive.
</pre>
Unsupported:
<pre>
B - Swatch Internet time
I (capital i) - "1" if Daylight Savings Time, "0" otherwise.
W - ISO-8601 week number of year, weeks starting on Monday
</pre>
** FUNCTION adodb_date2($fmt, $isoDateString = false)
Same as adodb_date, but 2nd parameter accepts iso date, eg.
adodb_date2('d-M-Y H:i','2003-12-25 13:01:34');
** FUNCTION adodb_gmdate($fmt, $timestamp = false)
Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the
current timestamp is used. Unlike the function date(), it supports dates
outside the 1901 to 2038 range.
** FUNCTION adodb_mktime($hr, $min, $sec[, $month, $day, $year])
Converts a local date to a unix timestamp. Unlike the function mktime(), it supports
dates outside the 1901 to 2038 range. All parameters are optional.
** FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year])
Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports
dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters
are currently compulsory.
** FUNCTION adodb_gmstrftime($fmt, $timestamp = false)
Convert a timestamp to a formatted GMT date.
** FUNCTION adodb_strftime($fmt, $timestamp = false)
Convert a timestamp to a formatted local date. Internally converts $fmt into
adodb_date format, then echo result.
For best results, you can define the local date format yourself. Define a global
variable $ADODB_DATE_LOCALE which is an array, 1st element is date format using
adodb_date syntax, and 2nd element is the time format, also in adodb_date syntax.
eg. $ADODB_DATE_LOCALE = array('d/m/Y','H:i:s');
Supported format codes:
<pre>
%a - abbreviated weekday name according to the current locale
%A - full weekday name according to the current locale
%b - abbreviated month name according to the current locale
%B - full month name according to the current locale
%c - preferred date and time representation for the current locale
%d - day of the month as a decimal number (range 01 to 31)
%D - same as %m/%d/%y
%e - day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31')
%h - same as %b
%H - hour as a decimal number using a 24-hour clock (range 00 to 23)
%I - hour as a decimal number using a 12-hour clock (range 01 to 12)
%m - month as a decimal number (range 01 to 12)
%M - minute as a decimal number
%n - newline character
%p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale
%r - time in a.m. and p.m. notation
%R - time in 24 hour notation
%S - second as a decimal number
%t - tab character
%T - current time, equal to %H:%M:%S
%x - preferred date representation for the current locale without the time
%X - preferred time representation for the current locale without the date
%y - year as a decimal number without a century (range 00 to 99)
%Y - year as a decimal number including the century
%Z - time zone or name or abbreviation
%% - a literal `%' character
</pre>
Unsupported codes:
<pre>
%C - century number (the year divided by 100 and truncated to an integer, range 00 to 99)
%g - like %G, but without the century.
%G - The 4-digit year corresponding to the ISO week number (see %V).
This has the same format and value as %Y, except that if the ISO week number belongs
to the previous or next year, that year is used instead.
%j - day of the year as a decimal number (range 001 to 366)
%u - weekday as a decimal number [1,7], with 1 representing Monday
%U - week number of the current year as a decimal number, starting
with the first Sunday as the first day of the first week
%V - The ISO 8601:1988 week number of the current year as a decimal number,
range 01 to 53, where week 1 is the first week that has at least 4 days in the
current year, and with Monday as the first day of the week. (Use %G or %g for
the year component that corresponds to the week number for the specified timestamp.)
%w - day of the week as a decimal, Sunday being 0
%W - week number of the current year as a decimal number, starting with the
first Monday as the first day of the first week
</pre>
=============================================================================
NOTES
Useful url for generating test timestamps:
http://www.4webhelp.net/us/timestamp.php
Possible future optimizations include
a. Using an algorithm similar to Plauger's in "The Standard C Library"
(page 428, xttotm.c _Ttotm() function). Plauger's algorithm will not
work outside 32-bit signed range, so i decided not to implement it.
b. Implement daylight savings, which looks awfully complicated, see
http://webexhibits.org/daylightsaving/
CHANGELOG
- 16 Jan 2011 0.36
Added adodb_time() which returns current time. If > 2038, will return as float
- 7 Feb 2011 0.35
Changed adodb_date to be symmetric with adodb_mktime. See $jan1_71. fix for bc.
- 13 July 2010 0.34
Changed adodb_get_gm_diff to use DateTimeZone().
- 11 Feb 2008 0.33
* Bug in 0.32 fix for hour handling. Fixed.
- 1 Feb 2008 0.32
* Now adodb_mktime(0,0,0,12+$m,20,2040) works properly.
- 10 Jan 2008 0.31
* Now adodb_mktime(0,0,0,24,1,2037) works correctly.
- 15 July 2007 0.30
Added PHP 5.2.0 compatability fixes.
* gmtime behaviour for 1970 has changed. We use the actual date if it is between 1970 to 2038 to get the
* timezone, otherwise we use the current year as the baseline to retrieve the timezone.
* Also the timezone's in php 5.2.* support historical data better, eg. if timezone today was +8, but
in 1970 it was +7:30, then php 5.2 return +7:30, while this library will use +8.
*
- 19 March 2006 0.24
Changed strftime() locale detection, because some locales prepend the day of week to the date when %c is used.
- 10 Feb 2006 0.23
PHP5 compat: when we detect PHP5, the RFC2822 format for gmt 0000hrs is changed from -0000 to +0000.
In PHP4, we will still use -0000 for 100% compat with PHP4.
- 08 Sept 2005 0.22
In adodb_date2(), $is_gmt not supported properly. Fixed.
- 18 July 2005 0.21
In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat.
Added support for negative months in adodb_mktime().
- 24 Feb 2005 0.20
Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date().
- 21 Dec 2004 0.17
In adodb_getdate(), the timestamp was accidentally converted to gmt when $is_gmt is false.
Also adodb_mktime(0,0,0) did not work properly. Both fixed thx Mauro.
- 17 Nov 2004 0.16
Removed intval typecast in adodb_mktime() for secs, allowing:
adodb_mktime(0,0,0 + 2236672153,1,1,1934);
Suggested by Ryan.
- 18 July 2004 0.15
All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory.
This brings it more in line with mktime (still not identical).
- 23 June 2004 0.14
Allow you to define your own daylights savings function, adodb_daylight_sv.
If the function is defined (somewhere in an include), then you can correct for daylights savings.
In this example, we apply daylights savings in June or July, adding one hour. This is extremely
unrealistic as it does not take into account time-zone, geographic location, current year.
function adodb_daylight_sv(&$arr, $is_gmt)
{
if ($is_gmt) return;
$m = $arr['mon'];
if ($m == 6 || $m == 7) $arr['hours'] += 1;
}
This is only called by adodb_date() and not by adodb_mktime().
The format of $arr is
Array (
[seconds] => 0
[minutes] => 0
[hours] => 0
[mday] => 1 # day of month, eg 1st day of the month
[mon] => 2 # month (eg. Feb)
[year] => 2102
[yday] => 31 # days in current year
[leap] => # true if leap year
[ndays] => 28 # no of days in current month
)
- 28 Apr 2004 0.13
Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov.
- 20 Mar 2004 0.12
Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32.
- 26 Oct 2003 0.11
Because of daylight savings problems (some systems apply daylight savings to
January!!!), changed adodb_get_gmt_diff() to ignore daylight savings.
- 9 Aug 2003 0.10
Fixed bug with dates after 2038.
See http://phplens.com/lens/lensforum/msgs.php?id=6980
- 1 July 2003 0.09
Added support for Q (Quarter).
Added adodb_date2(), which accepts ISO date in 2nd param
- 3 March 2003 0.08
Added support for 'S' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS
if you want PHP to handle negative timestamps between 1901 to 1969.
- 27 Feb 2003 0.07
All negative numbers handled by adodb now because of RH 7.3+ problems.
See http://bugs.php.net/bug.php?id=20048&edit=2
- 4 Feb 2003 0.06
Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates
are now correctly handled.
- 29 Jan 2003 0.05
Leap year checking differs under Julian calendar (pre 1582). Also
leap year code optimized by checking for most common case first.
We also handle month overflow correctly in mktime (eg month set to 13).
Day overflow for less than one month's days is supported.
- 28 Jan 2003 0.04
Gregorian correction handled. In PHP5, we might throw an error if
mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10.
Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582.
- 27 Jan 2003 0.03
Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION.
Fixed calculation of days since start of year for <1970.
- 27 Jan 2003 0.02
Changed _adodb_getdate() to inline leap year checking for better performance.
Fixed problem with time-zones west of GMT +0000.
- 24 Jan 2003 0.01
First implementation.
*/
/* Initialization */
/*
Version Number
*/
define('ADODB_DATE_VERSION',0.35);
$ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2);
/*
This code was originally for windows. But apparently this problem happens
also with Linux, RH 7.3 and later!
glibc-2.2.5-34 and greater has been changed to return -1 for dates <
1970. This used to work. The problem exists with RedHat 7.3 and 8.0
echo (mktime(0, 0, 0, 1, 1, 1960)); // prints -1
References:
http://bugs.php.net/bug.php?id=20048&edit=2
http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html
*/
if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1);
function adodb_date_test_date($y1,$m,$d=13)
{
$h = round(rand()% 24);
$t = adodb_mktime($h,0,0,$m,$d,$y1);
$rez = adodb_date('Y-n-j H:i:s',$t);
if ($h == 0) $h = '00';
else if ($h < 10) $h = '0'.$h;
if ("$y1-$m-$d $h:00:00" != $rez) {
print "<b>$y1 error, expected=$y1-$m-$d $h:00:00, adodb=$rez</b><br>";
return false;
}
return true;
}
function adodb_date_test_strftime($fmt)
{
$s1 = strftime($fmt);
$s2 = adodb_strftime($fmt);
if ($s1 == $s2) return true;
echo "error for $fmt, strftime=$s1, adodb=$s2<br>";
return false;
}
/**
Test Suite
*/
function adodb_date_test()
{
for ($m=-24; $m<=24; $m++)
echo "$m :",adodb_date('d-m-Y',adodb_mktime(0,0,0,1+$m,20,2040)),"<br>";
error_reporting(E_ALL);
print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."</h4>";
@set_time_limit(0);
$fail = false;
// This flag disables calling of PHP native functions, so we can properly test the code
if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1);
$t = time();
$fmt = 'Y-m-d H:i:s';
echo '<pre>';
echo 'adodb: ',adodb_date($fmt,$t),'<br>';
echo 'php : ',date($fmt,$t),'<br>';
echo '</pre>';
adodb_date_test_strftime('%Y %m %x %X');
adodb_date_test_strftime("%A %d %B %Y");
adodb_date_test_strftime("%H %M S");
$t = adodb_mktime(0,0,0);
if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>';
$t = adodb_mktime(0,0,0,6,1,2102);
if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
$t = adodb_mktime(0,0,0,2,1,2102);
if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
print "<p>Testing gregorian <=> julian conversion<p>";
$t = adodb_mktime(0,0,0,10,11,1492);
//http://www.holidayorigins.com/html/columbus_day.html - Friday check
if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing<br>';
$t = adodb_mktime(0,0,0,2,29,1500);
if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years<br>';
$t = adodb_mktime(0,0,0,2,29,1700);
if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years<br>';
print adodb_mktime(0,0,0,10,4,1582).' ';
print adodb_mktime(0,0,0,10,15,1582);
$diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582));
if ($diff != 3600*24) print " <b>Error in gregorian correction = ".($diff/3600/24)." days </b><br>";
print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : '<b>Error</b>')."<br>";
print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : '<b>Error</b>')."<br>";
print "<p>Testing overflow<p>";
$t = adodb_mktime(0,0,0,3,33,1965);
if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1 <br>';
$t = adodb_mktime(0,0,0,4,33,1971);
if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2 <br>';
$t = adodb_mktime(0,0,0,1,60,1965);
if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).' <br>';
$t = adodb_mktime(0,0,0,12,32,1965);
if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).' <br>';
$t = adodb_mktime(0,0,0,12,63,1965);
if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).' <br>';
$t = adodb_mktime(0,0,0,13,3,1965);
if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1 <br>';
print "Testing 2-digit => 4-digit year conversion<p>";
if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000<br>";
if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010<br>";
if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020<br>";
if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030<br>";
if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940<br>";
if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>";
if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>";
// Test string formating
print "<p>Testing date formating</p>";
$fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C2822 r s t U w y Y z Z 2003';
$s1 = date($fmt,0);
$s2 = adodb_date($fmt,0);
if ($s1 != $s2) {
print " date() 0 failed<br>$s1<br>$s2<br>";
}
flush();
for ($i=100; --$i > 0; ) {
$ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000);
$s1 = date($fmt,$ts);
$s2 = adodb_date($fmt,$ts);
//print "$s1 <br>$s2 <p>";
$pos = strcmp($s1,$s2);
if (($s1) != ($s2)) {
for ($j=0,$k=strlen($s1); $j < $k; $j++) {
if ($s1[$j] != $s2[$j]) {
print substr($s1,$j).' ';
break;
}
}
print "<b>Error date(): $ts<br><pre>
&nbsp; \"$s1\" (date len=".strlen($s1).")
&nbsp; \"$s2\" (adodb_date len=".strlen($s2).")</b></pre><br>";
$fail = true;
}
$a1 = getdate($ts);
$a2 = adodb_getdate($ts);
$rez = array_diff($a1,$a2);
if (sizeof($rez)>0) {
print "<b>Error getdate() $ts</b><br>";
print_r($a1);
print "<br>";
print_r($a2);
print "<p>";
$fail = true;
}
}
// Test generation of dates outside 1901-2038
print "<p>Testing random dates between 100 and 4000</p>";
adodb_date_test_date(100,1);
for ($i=100; --$i >= 0;) {
$y1 = 100+rand(0,1970-100);
$m = rand(1,12);
adodb_date_test_date($y1,$m);
$y1 = 3000-rand(0,3000-1970);
adodb_date_test_date($y1,$m);
}
print '<p>';
$start = 1960+rand(0,10);
$yrs = 12;
$i = 365.25*86400*($start-1970);
$offset = 36000+rand(10000,60000);
$max = 365*$yrs*86400;
$lastyear = 0;
// we generate a timestamp, convert it to a date, and convert it back to a timestamp
// and check if the roundtrip broke the original timestamp value.
print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: ";
$cnt = 0;
for ($max += $i; $i < $max; $i += $offset) {
$ret = adodb_date('m,d,Y,H,i,s',$i);
$arr = explode(',',$ret);
if ($lastyear != $arr[2]) {
$lastyear = $arr[2];
print " $lastyear ";
flush();
}
$newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]);
if ($i != $newi) {
print "Error at $i, adodb_mktime returned $newi ($ret)";
$fail = true;
break;
}
$cnt += 1;
}
echo "Tested $cnt dates<br>";
if (!$fail) print "<p>Passed !</p>";
else print "<p><b>Failed</b> :-(</p>";
}
function adodb_time()
{
$d = new DateTime();
return $d->format('U');
}
/**
Returns day of week, 0 = Sunday,... 6=Saturday.
Algorithm from PEAR::Date_Calc
*/
function adodb_dow($year, $month, $day)
{
/*
Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and
proclaimed that from that time onwards 3 days would be dropped from the calendar
every 400 years.
Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian).
*/
if ($year <= 1582) {
if ($year < 1582 ||
($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3;
else
$greg_correction = 0;
} else
$greg_correction = 0;
if($month > 2)
$month -= 2;
else {
$month += 10;
$year--;
}
$day = floor((13 * $month - 1) / 5) +
$day + ($year % 100) +
floor(($year % 100) / 4) +
floor(($year / 100) / 4) - 2 *
floor($year / 100) + 77 + $greg_correction;
return $day - 7 * floor($day / 7);
}
/**
Checks for leap year, returns true if it is. No 2-digit year check. Also
handles julian calendar correctly.
*/
function _adodb_is_leap_year($year)
{
if ($year % 4 != 0) return false;
if ($year % 400 == 0) {
return true;
// if gregorian calendar (>1582), century not-divisible by 400 is not leap
} else if ($year > 1582 && $year % 100 == 0 ) {
return false;
}
return true;
}
/**
checks for leap year, returns true if it is. Has 2-digit year check
*/
function adodb_is_leap_year($year)
{
return _adodb_is_leap_year(adodb_year_digit_check($year));
}
/**
Fix 2-digit years. Works for any century.
Assumes that if 2-digit is more than 30 years in future, then previous century.
*/
function adodb_year_digit_check($y)
{
if ($y < 100) {
$yr = (integer) date("Y");
$century = (integer) ($yr /100);
if ($yr%100 > 50) {
$c1 = $century + 1;
$c0 = $century;
} else {
$c1 = $century;
$c0 = $century - 1;
}
$c1 *= 100;
// if 2-digit year is less than 30 years in future, set it to this century
// otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
if (($y + $c1) < $yr+30) $y = $y + $c1;
else $y = $y + $c0*100;
}
return $y;
}
function adodb_get_gmt_diff_ts($ts)
{
if (0 <= $ts && $ts <= 0x7FFFFFFF) { // check if number in 32-bit signed range) {
$arr = getdate($ts);
$y = $arr['year'];
$m = $arr['mon'];
$d = $arr['mday'];
return adodb_get_gmt_diff($y,$m,$d);
} else {
return adodb_get_gmt_diff(false,false,false);
}
}
/**
get local time zone offset from GMT. Does not handle historical timezones before 1970.
*/
function adodb_get_gmt_diff($y,$m,$d)
{
static $TZ,$tzo;
global $ADODB_DATETIME_CLASS;
if (!defined('ADODB_TEST_DATES')) $y = false;
else if ($y < 1970 || $y >= 2038) $y = false;
if ($ADODB_DATETIME_CLASS && $y !== false) {
$dt = new DateTime();
$dt->setISODate($y,$m,$d);
if (empty($tzo)) {
$tzo = new DateTimeZone(date_default_timezone_get());
# $tzt = timezone_transitions_get( $tzo );
}
return -$tzo->getOffset($dt);
} else {
if (isset($TZ)) return $TZ;
$y = date('Y');
/*
if (function_exists('date_default_timezone_get') && function_exists('timezone_offset_get')) {
$tzonename = date_default_timezone_get();
if ($tzonename) {
$tobj = new DateTimeZone($tzonename);
$TZ = -timezone_offset_get($tobj,new DateTime("now",$tzo));
}
}
*/
if (empty($TZ)) $TZ = mktime(0,0,0,12,2,$y) - gmmktime(0,0,0,12,2,$y);
}
return $TZ;
}
/**
Returns an array with date info.
*/
function adodb_getdate($d=false,$fast=false)
{
if ($d === false) return getdate();
if (!defined('ADODB_TEST_DATES')) {
if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
return @getdate($d);
}
}
return _adodb_getdate($d);
}
/*
// generate $YRS table for _adodb_getdate()
function adodb_date_gentable($out=true)
{
for ($i=1970; $i >= 1600; $i-=10) {
$s = adodb_gmmktime(0,0,0,1,1,$i);
echo "$i => $s,<br>";
}
}
adodb_date_gentable();
for ($i=1970; $i > 1500; $i--) {
echo "<hr />$i ";
adodb_date_test_date($i,1,1);
}
*/
$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
function adodb_validdate($y,$m,$d)
{
global $_month_table_normal,$_month_table_leaf;
if (_adodb_is_leap_year($y)) $marr = $_month_table_leaf;
else $marr = $_month_table_normal;
if ($m > 12 || $m < 1) return false;
if ($d > 31 || $d < 1) return false;
if ($marr[$m] < $d) return false;
if ($y < 1000 && $y > 3000) return false;
return true;
}
/**
Low-level function that returns the getdate() array. We have a special
$fast flag, which if set to true, will return fewer array values,
and is much faster as it does not calculate dow, etc.
*/
function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
{
static $YRS;
global $_month_table_normal,$_month_table_leaf;
$d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff_ts($origd));
$_day_power = 86400;
$_hour_power = 3600;
$_min_power = 60;
if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction
$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
$d366 = $_day_power * 366;
$d365 = $_day_power * 365;
if ($d < 0) {
if (empty($YRS)) $YRS = array(
1970 => 0,
1960 => -315619200,
1950 => -631152000,
1940 => -946771200,
1930 => -1262304000,
1920 => -1577923200,
1910 => -1893456000,
1900 => -2208988800,
1890 => -2524521600,
1880 => -2840140800,
1870 => -3155673600,
1860 => -3471292800,
1850 => -3786825600,
1840 => -4102444800,
1830 => -4417977600,
1820 => -4733596800,
1810 => -5049129600,
1800 => -5364662400,
1790 => -5680195200,
1780 => -5995814400,
1770 => -6311347200,
1760 => -6626966400,
1750 => -6942499200,
1740 => -7258118400,
1730 => -7573651200,
1720 => -7889270400,
1710 => -8204803200,
1700 => -8520336000,
1690 => -8835868800,
1680 => -9151488000,
1670 => -9467020800,
1660 => -9782640000,
1650 => -10098172800,
1640 => -10413792000,
1630 => -10729324800,
1620 => -11044944000,
1610 => -11360476800,
1600 => -11676096000);
if ($is_gmt) $origd = $d;
// The valid range of a 32bit signed timestamp is typically from
// Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT
//
# old algorithm iterates through all years. new algorithm does it in
# 10 year blocks
/*
# old algo
for ($a = 1970 ; --$a >= 0;) {
$lastd = $d;
if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
else $d += $d365;
if ($d >= 0) {
$year = $a;
break;
}
}
*/
$lastsecs = 0;
$lastyear = 1970;
foreach($YRS as $year => $secs) {
if ($d >= $secs) {
$a = $lastyear;
break;
}
$lastsecs = $secs;
$lastyear = $year;
}
$d -= $lastsecs;
if (!isset($a)) $a = $lastyear;
//echo ' yr=',$a,' ', $d,'.';
for (; --$a >= 0;) {
$lastd = $d;
if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
else $d += $d365;
if ($d >= 0) {
$year = $a;
break;
}
}
/**/
$secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd;
$d = $lastd;
$mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
for ($a = 13 ; --$a > 0;) {
$lastd = $d;
$d += $mtab[$a] * $_day_power;
if ($d >= 0) {
$month = $a;
$ndays = $mtab[$a];
break;
}
}
$d = $lastd;
$day = $ndays + ceil(($d+1) / ($_day_power));
$d += ($ndays - $day+1)* $_day_power;
$hour = floor($d/$_hour_power);
} else {
for ($a = 1970 ;; $a++) {
$lastd = $d;
if ($leaf = _adodb_is_leap_year($a)) $d -= $d366;
else $d -= $d365;
if ($d < 0) {
$year = $a;
break;
}
}
$secsInYear = $lastd;
$d = $lastd;
$mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
for ($a = 1 ; $a <= 12; $a++) {
$lastd = $d;
$d -= $mtab[$a] * $_day_power;
if ($d < 0) {
$month = $a;
$ndays = $mtab[$a];
break;
}
}
$d = $lastd;
$day = ceil(($d+1) / $_day_power);
$d = $d - ($day-1) * $_day_power;
$hour = floor($d /$_hour_power);
}
$d -= $hour * $_hour_power;
$min = floor($d/$_min_power);
$secs = $d - $min * $_min_power;
if ($fast) {
return array(
'seconds' => $secs,
'minutes' => $min,
'hours' => $hour,
'mday' => $day,
'mon' => $month,
'year' => $year,
'yday' => floor($secsInYear/$_day_power),
'leap' => $leaf,
'ndays' => $ndays
);
}
$dow = adodb_dow($year,$month,$day);
return array(
'seconds' => $secs,
'minutes' => $min,
'hours' => $hour,
'mday' => $day,
'wday' => $dow,
'mon' => $month,
'year' => $year,
'yday' => floor($secsInYear/$_day_power),
'weekday' => gmdate('l',$_day_power*(3+$dow)),
'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
0 => $origd
);
}
/*
if ($isphp5)
$dates .= sprintf('%s%04d',($gmt<=0)?'+':'-',abs($gmt)/36);
else
$dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36);
break;*/
function adodb_tz_offset($gmt,$isphp5)
{
$zhrs = abs($gmt)/3600;
$hrs = floor($zhrs);
if ($isphp5)
return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
else
return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
}
function adodb_gmdate($fmt,$d=false)
{
return adodb_date($fmt,$d,true);
}
// accepts unix timestamp and iso date format in $d
function adodb_date2($fmt, $d=false, $is_gmt=false)
{
if ($d !== false) {
if (!preg_match(
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
($d), $rr)) return adodb_date($fmt,false,$is_gmt);
if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt);
// h-m-s-MM-DD-YY
if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1],false,$is_gmt);
else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1],false,$is_gmt);
}
return adodb_date($fmt,$d,$is_gmt);
}
/**
Return formatted date based on timestamp $d
*/
function adodb_date($fmt,$d=false,$is_gmt=false)
{
static $daylight;
global $ADODB_DATETIME_CLASS;
static $jan1_1971;
if (!isset($daylight)) {
$daylight = function_exists('adodb_daylight_sv');
if (empty($jan1_1971)) $jan1_1971 = mktime(0,0,0,1,1,1971); // we only use date() when > 1970 as adodb_mktime() only uses mktime() when > 1970
}
if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
if (!defined('ADODB_TEST_DATES')) {
if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= $jan1_1971) // if windows, must be +ve integer
return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
}
}
$_day_power = 86400;
$arr = _adodb_getdate($d,true,$is_gmt);
if ($daylight) adodb_daylight_sv($arr, $is_gmt);
$year = $arr['year'];
$month = $arr['mon'];
$day = $arr['mday'];
$hour = $arr['hours'];
$min = $arr['minutes'];
$secs = $arr['seconds'];
$max = strlen($fmt);
$dates = '';
$isphp5 = PHP_VERSION >= 5;
/*
at this point, we have the following integer vars to manipulate:
$year, $month, $day, $hour, $min, $secs
*/
for ($i=0; $i < $max; $i++) {
switch($fmt[$i]) {
case 'e':
$dates .= date('e');
break;
case 'T':
if ($ADODB_DATETIME_CLASS) {
$dt = new DateTime();
$dt->SetDate($year,$month,$day);
$dates .= $dt->Format('T');
} else
$dates .= date('T');
break;
// YEAR
case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
// 4.3.11 uses '04 Jun 2004'
// 4.3.8 uses ' 4 Jun 2004'
$dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', '
. ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour;
if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min;
if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
$gmt = adodb_get_gmt_diff($year,$month,$day);
$dates .= ' '.adodb_tz_offset($gmt,$isphp5);
break;
case 'Y': $dates .= $year; break;
case 'y': $dates .= substr($year,strlen($year)-2,2); break;
// MONTH
case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
case 'Q': $dates .= ($month+3)>>2; break;
case 'n': $dates .= $month; break;
case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
// DAY
case 't': $dates .= $arr['ndays']; break;
case 'z': $dates .= $arr['yday']; break;
case 'w': $dates .= adodb_dow($year,$month,$day); break;
case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
case 'j': $dates .= $day; break;
case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
case 'S':
$d10 = $day % 10;
if ($d10 == 1) $dates .= 'st';
else if ($d10 == 2 && $day != 12) $dates .= 'nd';
else if ($d10 == 3) $dates .= 'rd';
else $dates .= 'th';
break;
// HOUR
case 'Z':
$dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff($year,$month,$day); break;
case 'O':
$gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$month,$day);
$dates .= adodb_tz_offset($gmt,$isphp5);
break;
case 'H':
if ($hour < 10) $dates .= '0'.$hour;
else $dates .= $hour;
break;
case 'h':
if ($hour > 12) $hh = $hour - 12;
else {
if ($hour == 0) $hh = '12';
else $hh = $hour;
}
if ($hh < 10) $dates .= '0'.$hh;
else $dates .= $hh;
break;
case 'G':
$dates .= $hour;
break;
case 'g':
if ($hour > 12) $hh = $hour - 12;
else {
if ($hour == 0) $hh = '12';
else $hh = $hour;
}
$dates .= $hh;
break;
// MINUTES
case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break;
// SECONDS
case 'U': $dates .= $d; break;
case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break;
// AM/PM
// Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
case 'a':
if ($hour>=12) $dates .= 'pm';
else $dates .= 'am';
break;
case 'A':
if ($hour>=12) $dates .= 'PM';
else $dates .= 'AM';
break;
default:
$dates .= $fmt[$i]; break;
// ESCAPE
case "\\":
$i++;
if ($i < $max) $dates .= $fmt[$i];
break;
}
}
return $dates;
}
/**
Returns a timestamp given a GMT/UTC time.
Note that $is_dst is not implemented and is ignored.
*/
function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
{
return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
}
/**
Return a timestamp given a local time. Originally by jackbbs.
Note that $is_dst is not implemented and is ignored.
Not a very fast algorithm - O(n) operation. Could be optimized to O(1).
*/
function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false)
{
if (!defined('ADODB_TEST_DATES')) {
if ($mon === false) {
return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec);
}
// for windows, we don't check 1970 because with timezone differences,
// 1 Jan 1970 could generate negative timestamp, which is illegal
$usephpfns = (1970 < $year && $year < 2038
|| !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
);
if ($usephpfns && ($year + $mon/12+$day/365.25+$hr/(24*365.25) >= 2038)) $usephpfns = false;
if ($usephpfns) {
return $is_gmt ?
@gmmktime($hr,$min,$sec,$mon,$day,$year):
@mktime($hr,$min,$sec,$mon,$day,$year);
}
}
$gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$mon,$day);
/*
# disabled because some people place large values in $sec.
# however we need it for $mon because we use an array...
$hr = intval($hr);
$min = intval($min);
$sec = intval($sec);
*/
$mon = intval($mon);
$day = intval($day);
$year = intval($year);
$year = adodb_year_digit_check($year);
if ($mon > 12) {
$y = floor(($mon-1)/ 12);
$year += $y;
$mon -= $y*12;
} else if ($mon < 1) {
$y = ceil((1-$mon) / 12);
$year -= $y;
$mon += $y*12;
}
$_day_power = 86400;
$_hour_power = 3600;
$_min_power = 60;
$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
$_total_date = 0;
if ($year >= 1970) {
for ($a = 1970 ; $a <= $year; $a++) {
$leaf = _adodb_is_leap_year($a);
if ($leaf == true) {
$loop_table = $_month_table_leaf;
$_add_date = 366;
} else {
$loop_table = $_month_table_normal;
$_add_date = 365;
}
if ($a < $year) {
$_total_date += $_add_date;
} else {
for($b=1;$b<$mon;$b++) {
$_total_date += $loop_table[$b];
}
}
}
$_total_date +=$day-1;
$ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different;
} else {
for ($a = 1969 ; $a >= $year; $a--) {
$leaf = _adodb_is_leap_year($a);
if ($leaf == true) {
$loop_table = $_month_table_leaf;
$_add_date = 366;
} else {
$loop_table = $_month_table_normal;
$_add_date = 365;
}
if ($a > $year) { $_total_date += $_add_date;
} else {
for($b=12;$b>$mon;$b--) {
$_total_date += $loop_table[$b];
}
}
}
$_total_date += $loop_table[$mon] - $day;
$_day_time = $hr * $_hour_power + $min * $_min_power + $sec;
$_day_time = $_day_power - $_day_time;
$ret = -( $_total_date * $_day_power + $_day_time - $gmt_different);
if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction
else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582.
}
//print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret;
return $ret;
}
function adodb_gmstrftime($fmt, $ts=false)
{
return adodb_strftime($fmt,$ts,true);
}
// hack - convert to adodb_date
function adodb_strftime($fmt, $ts=false,$is_gmt=false)
{
global $ADODB_DATE_LOCALE;
if (!defined('ADODB_TEST_DATES')) {
if ((abs($ts) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
if (!defined('ADODB_NO_NEGATIVE_TS') || $ts >= 0) // if windows, must be +ve integer
return ($is_gmt)? @gmstrftime($fmt,$ts): @strftime($fmt,$ts);
}
}
if (empty($ADODB_DATE_LOCALE)) {
/*
$tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am
$sep = substr($tstr,2,1);
$hasAM = strrpos($tstr,'M') !== false;
*/
# see http://phplens.com/lens/lensforum/msgs.php?id=14865 for reasoning, and changelog for version 0.24
$dstr = gmstrftime('%x',31366800); // 30 Dec 1970, 1 am
$sep = substr($dstr,2,1);
$tstr = strtoupper(gmstrftime('%X',31366800)); // 30 Dec 1970, 1 am
$hasAM = strrpos($tstr,'M') !== false;
$ADODB_DATE_LOCALE = array();
$ADODB_DATE_LOCALE[] = strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y';
$ADODB_DATE_LOCALE[] = ($hasAM) ? 'h:i:s a' : 'H:i:s';
}
$inpct = false;
$fmtdate = '';
for ($i=0,$max = strlen($fmt); $i < $max; $i++) {
$ch = $fmt[$i];
if ($ch == '%') {
if ($inpct) {
$fmtdate .= '%';
$inpct = false;
} else
$inpct = true;
} else if ($inpct) {
$inpct = false;
switch($ch) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'E':
case 'O':
/* ignore format modifiers */
$inpct = true;
break;
case 'a': $fmtdate .= 'D'; break;
case 'A': $fmtdate .= 'l'; break;
case 'h':
case 'b': $fmtdate .= 'M'; break;
case 'B': $fmtdate .= 'F'; break;
case 'c': $fmtdate .= $ADODB_DATE_LOCALE[0].$ADODB_DATE_LOCALE[1]; break;
case 'C': $fmtdate .= '\C?'; break; // century
case 'd': $fmtdate .= 'd'; break;
case 'D': $fmtdate .= 'm/d/y'; break;
case 'e': $fmtdate .= 'j'; break;
case 'g': $fmtdate .= '\g?'; break; //?
case 'G': $fmtdate .= '\G?'; break; //?
case 'H': $fmtdate .= 'H'; break;
case 'I': $fmtdate .= 'h'; break;
case 'j': $fmtdate .= '?z'; $parsej = true; break; // wrong as j=1-based, z=0-basd
case 'm': $fmtdate .= 'm'; break;
case 'M': $fmtdate .= 'i'; break;
case 'n': $fmtdate .= "\n"; break;
case 'p': $fmtdate .= 'a'; break;
case 'r': $fmtdate .= 'h:i:s a'; break;
case 'R': $fmtdate .= 'H:i:s'; break;
case 'S': $fmtdate .= 's'; break;
case 't': $fmtdate .= "\t"; break;
case 'T': $fmtdate .= 'H:i:s'; break;
case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-based
case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based
case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break;
case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break;
case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-based
case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based
case 'y': $fmtdate .= 'y'; break;
case 'Y': $fmtdate .= 'Y'; break;
case 'Z': $fmtdate .= 'T'; break;
}
} else if (('A' <= ($ch) && ($ch) <= 'Z' ) || ('a' <= ($ch) && ($ch) <= 'z' ))
$fmtdate .= "\\".$ch;
else
$fmtdate .= $ch;
}
//echo "fmt=",$fmtdate,"<br>";
if ($ts === false) $ts = time();
$ret = adodb_date($fmtdate, $ts, $is_gmt);
return $ret;
}
-2224
View File
@@ -1,2224 +0,0 @@
<?php
// Copyright (c) 2004 ars Cognita Inc., all rights reserved
/* ******************************************************************************
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
*******************************************************************************/
/**
* xmlschema is a class that allows the user to quickly and easily
* build a database on any ADOdb-supported platform using a simple
* XML schema.
*
* Last Editor: $Author: jlim $
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision: 1.12 $
*
* @package axmls
* @tutorial getting_started.pkg
*/
function _file_get_contents($file)
{
if (function_exists('file_get_contents')) return file_get_contents($file);
$f = fopen($file,'r');
if (!$f) return '';
$t = '';
while ($s = fread($f,100000)) $t .= $s;
fclose($f);
return $t;
}
/**
* Debug on or off
*/
if( !defined( 'XMLS_DEBUG' ) ) {
define( 'XMLS_DEBUG', FALSE );
}
/**
* Default prefix key
*/
if( !defined( 'XMLS_PREFIX' ) ) {
define( 'XMLS_PREFIX', '%%P' );
}
/**
* Maximum length allowed for object prefix
*/
if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
define( 'XMLS_PREFIX_MAXLEN', 10 );
}
/**
* Execute SQL inline as it is generated
*/
if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
define( 'XMLS_EXECUTE_INLINE', FALSE );
}
/**
* Continue SQL Execution if an error occurs?
*/
if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
}
/**
* Current Schema Version
*/
if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
define( 'XMLS_SCHEMA_VERSION', '0.2' );
}
/**
* Default Schema Version. Used for Schemas without an explicit version set.
*/
if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
}
/**
* Default Schema Version. Used for Schemas without an explicit version set.
*/
if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
}
/**
* Include the main ADODB library
*/
if( !defined( '_ADODB_LAYER' ) ) {
require( 'adodb.inc.php' );
require( 'adodb-datadict.inc.php' );
}
/**
* Abstract DB Object. This class provides basic methods for database objects, such
* as tables and indexes.
*
* @package axmls
* @access private
*/
class dbObject {
/**
* var object Parent
*/
var $parent;
/**
* var string current element
*/
var $currentElement;
/**
* NOP
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
}
/**
* XML Callback to process start elements
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
}
/**
* XML Callback to process CDATA elements
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
}
function create(&$xmls) {
return array();
}
/**
* Destroys the object
*/
function destroy() {
}
/**
* Checks whether the specified RDBMS is supported by the current
* database object or its ranking ancestor.
*
* @param string $platform RDBMS platform name (from ADODB platform list).
* @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
*/
function supportedPlatform( $platform = NULL ) {
return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
}
/**
* Returns the prefix set by the ranking ancestor of the database object.
*
* @param string $name Prefix string.
* @return string Prefix.
*/
function prefix( $name = '' ) {
return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
}
/**
* Extracts a field ID from the specified field.
*
* @param string $field Field.
* @return string Field ID.
*/
function FieldID( $field ) {
return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
}
}
/**
* Creates a table object in ADOdb's datadict format
*
* This class stores information about a database table. As charactaristics
* of the table are loaded from the external source, methods and properties
* of this class are used to build up the table description in ADOdb's
* datadict format.
*
* @package axmls
* @access private
*/
class dbTable extends dbObject {
/**
* @var string Table name
*/
var $name;
/**
* @var array Field specifier: Meta-information about each field
*/
var $fields = array();
/**
* @var array List of table indexes.
*/
var $indexes = array();
/**
* @var array Table options: Table-level options
*/
var $opts = array();
/**
* @var string Field index: Keeps track of which field is currently being processed
*/
var $current_field;
/**
* @var boolean Mark table for destruction
* @access private
*/
var $drop_table;
/**
* @var boolean Mark field for destruction (not yet implemented)
* @access private
*/
var $drop_field = array();
/**
* Iniitializes a new table object.
*
* @param string $prefix DB Object prefix
* @param array $attributes Array of table attributes.
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
$this->name = $this->prefix($attributes['NAME']);
}
/**
* XML Callback to process start elements. Elements currently
* processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT.
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
case 'INDEX':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$index = $this->addIndex( $attributes );
xml_set_object( $parser, $index );
}
break;
case 'DATA':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$data = $this->addData( $attributes );
xml_set_object( $parser, $data );
}
break;
case 'DROP':
$this->drop();
break;
case 'FIELD':
// Add a field
$fieldName = $attributes['NAME'];
$fieldType = $attributes['TYPE'];
$fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;
$fieldOpts = isset( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;
$this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
break;
case 'KEY':
case 'NOTNULL':
case 'AUTOINCREMENT':
// Add a field option
$this->addFieldOpt( $this->current_field, $this->currentElement );
break;
case 'DEFAULT':
// Add a field option to the table object
// Work around ADOdb datadict issue that misinterprets empty strings.
if( $attributes['VALUE'] == '' ) {
$attributes['VALUE'] = " '' ";
}
$this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );
break;
case 'DEFDATE':
case 'DEFTIMESTAMP':
// Add a field option to the table object
$this->addFieldOpt( $this->current_field, $this->currentElement );
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Table constraint
case 'CONSTRAINT':
if( isset( $this->current_field ) ) {
$this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );
} else {
$this->addTableOpt( $cdata );
}
break;
// Table option
case 'OPT':
$this->addTableOpt( $cdata );
break;
default:
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
case 'TABLE':
$this->parent->addSQL( $this->create( $this->parent ) );
xml_set_object( $parser, $this->parent );
$this->destroy();
break;
case 'FIELD':
unset($this->current_field);
break;
}
}
/**
* Adds an index to a table object
*
* @param array $attributes Index attributes
* @return object dbIndex object
*/
function addIndex( $attributes ) {
$name = strtoupper( $attributes['NAME'] );
$this->indexes[$name] = new dbIndex( $this, $attributes );
return $this->indexes[$name];
}
/**
* Adds data to a table object
*
* @param array $attributes Data attributes
* @return object dbData object
*/
function addData( $attributes ) {
if( !isset( $this->data ) ) {
$this->data = new dbData( $this, $attributes );
}
return $this->data;
}
/**
* Adds a field to a table object
*
* $name is the name of the table to which the field should be added.
* $type is an ADODB datadict field type. The following field types
* are supported as of ADODB 3.40:
* - C: varchar
* - X: CLOB (character large object) or largest varchar size
* if CLOB is not supported
* - C2: Multibyte varchar
* - X2: Multibyte CLOB
* - B: BLOB (binary large object)
* - D: Date (some databases do not support this, and we return a datetime type)
* - T: Datetime or Timestamp
* - L: Integer field suitable for storing booleans (0 or 1)
* - I: Integer (mapped to I4)
* - I1: 1-byte integer
* - I2: 2-byte integer
* - I4: 4-byte integer
* - I8: 8-byte integer
* - F: Floating point number
* - N: Numeric or decimal number
*
* @param string $name Name of the table to which the field will be added.
* @param string $type ADODB datadict field type.
* @param string $size Field size
* @param array $opts Field options array
* @return array Field specifier array
*/
function addField( $name, $type, $size = NULL, $opts = NULL ) {
$field_id = $this->FieldID( $name );
// Set the field index so we know where we are
$this->current_field = $field_id;
// Set the field name (required)
$this->fields[$field_id]['NAME'] = $name;
// Set the field type (required)
$this->fields[$field_id]['TYPE'] = $type;
// Set the field size (optional)
if( isset( $size ) ) {
$this->fields[$field_id]['SIZE'] = $size;
}
// Set the field options
if( isset( $opts ) ) {
$this->fields[$field_id]['OPTS'][] = $opts;
}
}
/**
* Adds a field option to the current field specifier
*
* This method adds a field option allowed by the ADOdb datadict
* and appends it to the given field.
*
* @param string $field Field name
* @param string $opt ADOdb field option
* @param mixed $value Field option value
* @return array Field specifier array
*/
function addFieldOpt( $field, $opt, $value = NULL ) {
if( !isset( $value ) ) {
$this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;
// Add the option and value
} else {
$this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );
}
}
/**
* Adds an option to the table
*
* This method takes a comma-separated list of table-level options
* and appends them to the table object.
*
* @param string $opt Table option
* @return array Options
*/
function addTableOpt( $opt ) {
if(isset($this->currentPlatform)) {
$this->opts[$this->parent->db->databaseType] = $opt;
}
return $this->opts;
}
/**
* Generates the SQL that will create the table in the database
*
* @param object $xmls adoSchema object
* @return array Array containing table creation SQL
*/
function create( &$xmls ) {
$sql = array();
// drop any existing indexes
if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {
foreach( $legacy_indexes as $index => $index_details ) {
$sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );
}
}
// remove fields to be dropped from table object
foreach( $this->drop_field as $field ) {
unset( $this->fields[$field] );
}
// if table exists
if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {
// drop table
if( $this->drop_table ) {
$sql[] = $xmls->dict->DropTableSQL( $this->name );
return $sql;
}
// drop any existing fields not in schema
foreach( $legacy_fields as $field_id => $field ) {
if( !isset( $this->fields[$field_id] ) ) {
$sql[] = $xmls->dict->DropColumnSQL( $this->name, '`'.$field->name.'`' );
}
}
// if table doesn't exist
} else {
if( $this->drop_table ) {
return $sql;
}
$legacy_fields = array();
}
// Loop through the field specifier array, building the associative array for the field options
$fldarray = array();
foreach( $this->fields as $field_id => $finfo ) {
// Set an empty size if it isn't supplied
if( !isset( $finfo['SIZE'] ) ) {
$finfo['SIZE'] = '';
}
// Initialize the field array with the type and size
$fldarray[$field_id] = array(
'NAME' => $finfo['NAME'],
'TYPE' => $finfo['TYPE'],
'SIZE' => $finfo['SIZE']
);
// Loop through the options array and add the field options.
if( isset( $finfo['OPTS'] ) ) {
foreach( $finfo['OPTS'] as $opt ) {
// Option has an argument.
if( is_array( $opt ) ) {
$key = key( $opt );
$value = $opt[key( $opt )];
@$fldarray[$field_id][$key] .= $value;
// Option doesn't have arguments
} else {
$fldarray[$field_id][$opt] = $opt;
}
}
}
}
if( empty( $legacy_fields ) ) {
// Create the new table
$sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
logMsg( end( $sql ), 'Generated CreateTableSQL' );
} else {
// Upgrade an existing table
logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );
switch( $xmls->upgrade ) {
// Use ChangeTableSQL
case 'ALTER':
logMsg( 'Generated ChangeTableSQL (ALTERing table)' );
$sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );
break;
case 'REPLACE':
logMsg( 'Doing upgrade REPLACE (testing)' );
$sql[] = $xmls->dict->DropTableSQL( $this->name );
$sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
break;
// ignore table
default:
return array();
}
}
foreach( $this->indexes as $index ) {
$sql[] = $index->create( $xmls );
}
if( isset( $this->data ) ) {
$sql[] = $this->data->create( $xmls );
}
return $sql;
}
/**
* Marks a field or table for destruction
*/
function drop() {
if( isset( $this->current_field ) ) {
// Drop the current field
logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );
// $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );
$this->drop_field[$this->current_field] = $this->current_field;
} else {
// Drop the current table
logMsg( "Dropping table '{$this->name}'" );
// $this->drop_table = $xmls->dict->DropTableSQL( $this->name );
$this->drop_table = TRUE;
}
}
}
/**
* Creates an index object in ADOdb's datadict format
*
* This class stores information about a database index. As charactaristics
* of the index are loaded from the external source, methods and properties
* of this class are used to build up the index description in ADOdb's
* datadict format.
*
* @package axmls
* @access private
*/
class dbIndex extends dbObject {
/**
* @var string Index name
*/
var $name;
/**
* @var array Index options: Index-level options
*/
var $opts = array();
/**
* @var array Indexed fields: Table columns included in this index
*/
var $columns = array();
/**
* @var boolean Mark index for destruction
* @access private
*/
var $drop = FALSE;
/**
* Initializes the new dbIndex object.
*
* @param object $parent Parent object
* @param array $attributes Attributes
*
* @internal
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
$this->name = $this->prefix ($attributes['NAME']);
}
/**
* XML Callback to process start elements
*
* Processes XML opening tags.
* Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
case 'DROP':
$this->drop();
break;
case 'CLUSTERED':
case 'BITMAP':
case 'UNIQUE':
case 'FULLTEXT':
case 'HASH':
// Add index Option
$this->addIndexOpt( $this->currentElement );
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
* Processes XML cdata.
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
case 'COL':
$this->addField( $cdata );
break;
default:
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
case 'INDEX':
xml_set_object( $parser, $this->parent );
break;
}
}
/**
* Adds a field to the index
*
* @param string $name Field name
* @return string Field list
*/
function addField( $name ) {
$this->columns[$this->FieldID( $name )] = $name;
// Return the field list
return $this->columns;
}
/**
* Adds options to the index
*
* @param string $opt Comma-separated list of index options.
* @return string Option list
*/
function addIndexOpt( $opt ) {
$this->opts[] = $opt;
// Return the options list
return $this->opts;
}
/**
* Generates the SQL that will create the index in the database
*
* @param object $xmls adoSchema object
* @return array Array containing index creation SQL
*/
function create( &$xmls ) {
if( $this->drop ) {
return NULL;
}
// eliminate any columns that aren't in the table
foreach( $this->columns as $id => $col ) {
if( !isset( $this->parent->fields[$id] ) ) {
unset( $this->columns[$id] );
}
}
return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
}
/**
* Marks an index for destruction
*/
function drop() {
$this->drop = TRUE;
}
}
/**
* Creates a data object in ADOdb's datadict format
*
* This class stores information about table data.
*
* @package axmls
* @access private
*/
class dbData extends dbObject {
var $data = array();
var $row;
/**
* Initializes the new dbIndex object.
*
* @param object $parent Parent object
* @param array $attributes Attributes
*
* @internal
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
}
/**
* XML Callback to process start elements
*
* Processes XML opening tags.
* Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
case 'ROW':
$this->row = count( $this->data );
$this->data[$this->row] = array();
break;
case 'F':
$this->addField($attributes);
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
* Processes XML cdata.
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
case 'F':
$this->addData( $cdata );
break;
default:
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
case 'DATA':
xml_set_object( $parser, $this->parent );
break;
}
}
/**
* Adds a field to the index
*
* @param string $name Field name
* @return string Field list
*/
function addField( $attributes ) {
if( isset( $attributes['NAME'] ) ) {
$name = $attributes['NAME'];
} else {
$name = count($this->data[$this->row]);
}
// Set the field index so we know where we are
$this->current_field = $this->FieldID( $name );
}
/**
* Adds options to the index
*
* @param string $opt Comma-separated list of index options.
* @return string Option list
*/
function addData( $cdata ) {
if( !isset( $this->data[$this->row] ) ) {
$this->data[$this->row] = array();
}
if( !isset( $this->data[$this->row][$this->current_field] ) ) {
$this->data[$this->row][$this->current_field] = '';
}
$this->data[$this->row][$this->current_field] .= $cdata;
}
/**
* Generates the SQL that will create the index in the database
*
* @param object $xmls adoSchema object
* @return array Array containing index creation SQL
*/
function create( &$xmls ) {
$table = $xmls->dict->TableName($this->parent->name);
$table_field_count = count($this->parent->fields);
$sql = array();
// eliminate any columns that aren't in the table
foreach( $this->data as $row ) {
$table_fields = $this->parent->fields;
$fields = array();
foreach( $row as $field_id => $field_data ) {
if( !array_key_exists( $field_id, $table_fields ) ) {
if( is_numeric( $field_id ) ) {
$field_id = reset( array_keys( $table_fields ) );
} else {
continue;
}
}
$name = $table_fields[$field_id]['NAME'];
switch( $table_fields[$field_id]['TYPE'] ) {
case 'C':
case 'C2':
case 'X':
case 'X2':
$fields[$name] = $xmls->db->qstr( $field_data );
break;
case 'I':
case 'I1':
case 'I2':
case 'I4':
case 'I8':
$fields[$name] = intval($field_data);
break;
default:
$fields[$name] = $field_data;
}
unset($table_fields[$field_id]);
}
// check that at least 1 column is specified
if( empty( $fields ) ) {
continue;
}
// check that no required columns are missing
if( count( $fields ) < $table_field_count ) {
foreach( $table_fields as $field ) {
if (isset( $field['OPTS'] ))
if( ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {
continue(2);
}
}
}
$sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
}
return $sql;
}
}
/**
* Creates the SQL to execute a list of provided SQL queries
*
* @package axmls
* @access private
*/
class dbQuerySet extends dbObject {
/**
* @var array List of SQL queries
*/
var $queries = array();
/**
* @var string String used to build of a query line by line
*/
var $query;
/**
* @var string Query prefix key
*/
var $prefixKey = '';
/**
* @var boolean Auto prefix enable (TRUE)
*/
var $prefixMethod = 'AUTO';
/**
* Initializes the query set.
*
* @param object $parent Parent object
* @param array $attributes Attributes
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
// Overrides the manual prefix key
if( isset( $attributes['KEY'] ) ) {
$this->prefixKey = $attributes['KEY'];
}
$prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';
// Enables or disables automatic prefix prepending
switch( $prefixMethod ) {
case 'AUTO':
$this->prefixMethod = 'AUTO';
break;
case 'MANUAL':
$this->prefixMethod = 'MANUAL';
break;
case 'NONE':
$this->prefixMethod = 'NONE';
break;
}
}
/**
* XML Callback to process start elements. Elements currently
* processed are: QUERY.
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
case 'QUERY':
// Create a new query in a SQL queryset.
// Ignore this query set if a platform is specified and it's different than the
// current connection platform.
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$this->newQuery();
} else {
$this->discardQuery();
}
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*/
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Line of queryset SQL data
case 'QUERY':
$this->buildQuery( $cdata );
break;
default:
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
case 'QUERY':
// Add the finished query to the open query set.
$this->addQuery();
break;
case 'SQL':
$this->parent->addSQL( $this->create( $this->parent ) );
xml_set_object( $parser, $this->parent );
$this->destroy();
break;
default:
}
}
/**
* Re-initializes the query.
*
* @return boolean TRUE
*/
function newQuery() {
$this->query = '';
return TRUE;
}
/**
* Discards the existing query.
*
* @return boolean TRUE
*/
function discardQuery() {
unset( $this->query );
return TRUE;
}
/**
* Appends a line to a query that is being built line by line
*
* @param string $data Line of SQL data or NULL to initialize a new query
* @return string SQL query string.
*/
function buildQuery( $sql = NULL ) {
if( !isset( $this->query ) OR empty( $sql ) ) {
return FALSE;
}
$this->query .= $sql;
return $this->query;
}
/**
* Adds a completed query to the query list
*
* @return string SQL of added query
*/
function addQuery() {
if( !isset( $this->query ) ) {
return FALSE;
}
$this->queries[] = $return = trim($this->query);
unset( $this->query );
return $return;
}
/**
* Creates and returns the current query set
*
* @param object $xmls adoSchema object
* @return array Query set
*/
function create( &$xmls ) {
foreach( $this->queries as $id => $query ) {
switch( $this->prefixMethod ) {
case 'AUTO':
// Enable auto prefix replacement
// Process object prefix.
// Evaluate SQL statements to prepend prefix to objects
$query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
$query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
$query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
// SELECT statements aren't working yet
#$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );
case 'MANUAL':
// If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.
// If prefixKey is not set, we use the default constant XMLS_PREFIX
if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {
// Enable prefix override
$query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );
} else {
// Use default replacement
$query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );
}
}
$this->queries[$id] = trim( $query );
}
// Return the query set array
return $this->queries;
}
/**
* Rebuilds the query with the prefix attached to any objects
*
* @param string $regex Regex used to add prefix
* @param string $query SQL query string
* @param string $prefix Prefix to be appended to tables, indices, etc.
* @return string Prefixed SQL query string.
*/
function prefixQuery( $regex, $query, $prefix = NULL ) {
if( !isset( $prefix ) ) {
return $query;
}
if( preg_match( $regex, $query, $match ) ) {
$preamble = $match[1];
$postamble = $match[5];
$objectList = explode( ',', $match[3] );
// $prefix = $prefix . '_';
$prefixedList = '';
foreach( $objectList as $object ) {
if( $prefixedList !== '' ) {
$prefixedList .= ', ';
}
$prefixedList .= $prefix . trim( $object );
}
$query = $preamble . ' ' . $prefixedList . ' ' . $postamble;
}
return $query;
}
}
/**
* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
*
* This class is used to load and parse the XML file, to create an array of SQL statements
* that can be used to build a database, and to build the database using the SQL array.
*
* @tutorial getting_started.pkg
*
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision: 1.12 $
*
* @package axmls
*/
class adoSchema {
/**
* @var array Array containing SQL queries to generate all objects
* @access private
*/
var $sqlArray;
/**
* @var object ADOdb connection object
* @access private
*/
var $db;
/**
* @var object ADOdb Data Dictionary
* @access private
*/
var $dict;
/**
* @var string Current XML element
* @access private
*/
var $currentElement = '';
/**
* @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
* @access private
*/
var $upgrade = '';
/**
* @var string Optional object prefix
* @access private
*/
var $objectPrefix = '';
/**
* @var long Original Magic Quotes Runtime value
* @access private
*/
var $mgq;
/**
* @var long System debug
* @access private
*/
var $debug;
/**
* @var string Regular expression to find schema version
* @access private
*/
var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';
/**
* @var string Current schema version
* @access private
*/
var $schemaVersion;
/**
* @var int Success of last Schema execution
*/
var $success;
/**
* @var bool Execute SQL inline as it is generated
*/
var $executeInline;
/**
* @var bool Continue SQL execution if errors occur
*/
var $continueOnError;
/**
* Creates an adoSchema object
*
* Creating an adoSchema object is the first step in processing an XML schema.
* The only parameter is an ADOdb database connection object, which must already
* have been created.
*
* @param object $db ADOdb database connection object.
*/
function __construct( $db ) {
// Initialize the environment
$this->mgq = get_magic_quotes_runtime();
ini_set("magic_quotes_runtime", 0);
#set_magic_quotes_runtime(0);
$this->db = $db;
$this->debug = $this->db->debug;
$this->dict = NewDataDictionary( $this->db );
$this->sqlArray = array();
$this->schemaVersion = XMLS_SCHEMA_VERSION;
$this->executeInline( XMLS_EXECUTE_INLINE );
$this->continueOnError( XMLS_CONTINUE_ON_ERROR );
$this->setUpgradeMethod();
}
/**
* Sets the method to be used for upgrading an existing database
*
* Use this method to specify how existing database objects should be upgraded.
* The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
* alter each database object directly, REPLACE attempts to rebuild each object
* from scratch, BEST attempts to determine the best upgrade method for each
* object, and NONE disables upgrading.
*
* This method is not yet used by AXMLS, but exists for backward compatibility.
* The ALTER method is automatically assumed when the adoSchema object is
* instantiated; other upgrade methods are not currently supported.
*
* @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
* @returns string Upgrade method used
*/
function SetUpgradeMethod( $method = '' ) {
if( !is_string( $method ) ) {
return FALSE;
}
$method = strtoupper( $method );
// Handle the upgrade methods
switch( $method ) {
case 'ALTER':
$this->upgrade = $method;
break;
case 'REPLACE':
$this->upgrade = $method;
break;
case 'BEST':
$this->upgrade = 'ALTER';
break;
case 'NONE':
$this->upgrade = 'NONE';
break;
default:
// Use default if no legitimate method is passed.
$this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;
}
return $this->upgrade;
}
/**
* Enables/disables inline SQL execution.
*
* Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
* AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
* is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
* to apply the schema to the database.
*
* @param bool $mode execute
* @return bool current execution mode
*
* @see ParseSchema(), ExecuteSchema()
*/
function ExecuteInline( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->executeInline = $mode;
}
return $this->executeInline;
}
/**
* Enables/disables SQL continue on error.
*
* Call this method to enable or disable continuation of SQL execution if an error occurs.
* If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
* If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
* of the schema will continue.
*
* @param bool $mode execute
* @return bool current continueOnError mode
*
* @see addSQL(), ExecuteSchema()
*/
function ContinueOnError( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->continueOnError = $mode;
}
return $this->continueOnError;
}
/**
* Loads an XML schema from a file and converts it to SQL.
*
* Call this method to load the specified schema (see the DTD for the proper format) from
* the filesystem and generate the SQL necessary to create the database described.
* @see ParseSchemaString()
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute
*/
function ParseSchema( $filename, $returnSchema = FALSE ) {
return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
* Loads an XML schema from a file and converts it to SQL.
*
* Call this method to load the specified schema from a file (see the DTD for the proper format)
* and generate the SQL necessary to create the database described by the schema.
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*
* @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
* @see ParseSchema(), ParseSchemaString()
*/
function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
// die( 'Unable to open file' );
return FALSE;
}
// do version detection here
if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
return FALSE;
}
if ( $returnSchema )
{
$xmlstring = '';
while( $data = fread( $fp, 100000 ) ) {
$xmlstring .= $data;
}
return $xmlstring;
}
$this->success = 2;
$xmlParser = $this->create_parser();
// Process the file
while( $data = fread( $fp, 4096 ) ) {
if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
die( sprintf(
"XML error: %s at line %d",
xml_error_string( xml_get_error_code( $xmlParser) ),
xml_get_current_line_number( $xmlParser)
) );
}
}
xml_parser_free( $xmlParser );
return $this->sqlArray;
}
/**
* Converts an XML schema string to SQL.
*
* Call this method to parse a string containing an XML schema (see the DTD for the proper format)
* and generate the SQL necessary to create the database described by the schema.
* @see ParseSchema()
*
* @param string $xmlstring XML schema string.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*/
function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
}
// do version detection here
if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {
return FALSE;
}
if ( $returnSchema )
{
return $xmlstring;
}
$this->success = 2;
$xmlParser = $this->create_parser();
if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {
die( sprintf(
"XML error: %s at line %d",
xml_error_string( xml_get_error_code( $xmlParser) ),
xml_get_current_line_number( $xmlParser)
) );
}
xml_parser_free( $xmlParser );
return $this->sqlArray;
}
/**
* Loads an XML schema from a file and converts it to uninstallation SQL.
*
* Call this method to load the specified schema (see the DTD for the proper format) from
* the filesystem and generate the SQL necessary to remove the database described.
* @see RemoveSchemaString()
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute
*/
function RemoveSchema( $filename, $returnSchema = FALSE ) {
return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
* Converts an XML schema string to uninstallation SQL.
*
* Call this method to parse a string containing an XML schema (see the DTD for the proper format)
* and generate the SQL necessary to uninstall the database described by the schema.
* @see RemoveSchema()
*
* @param string $schema XML schema string.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*/
function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
// grab current version
if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
return FALSE;
}
return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
}
/**
* Applies the current XML schema to the database (post execution).
*
* Call this method to apply the current schema (generally created by calling
* ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes,
* and executing other SQL specified in the schema) after parsing.
* @see ParseSchema(), ParseSchemaString(), ExecuteInline()
*
* @param array $sqlArray Array of SQL statements that will be applied rather than
* the current schema.
* @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
* @returns integer 0 if failure, 1 if errors, 2 if successful.
*/
function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
if( !is_bool( $continueOnErr ) ) {
$continueOnErr = $this->ContinueOnError();
}
if( !isset( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
}
if( !is_array( $sqlArray ) ) {
$this->success = 0;
} else {
$this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
}
return $this->success;
}
/**
* Returns the current SQL array.
*
* Call this method to fetch the array of SQL queries resulting from
* ParseSchema() or ParseSchemaString().
*
* @param string $format Format: HTML, TEXT, or NONE (PHP array)
* @return array Array of SQL statements or FALSE if an error occurs
*/
function PrintSQL( $format = 'NONE' ) {
$sqlArray = null;
return $this->getSQL( $format, $sqlArray );
}
/**
* Saves the current SQL array to the local filesystem as a list of SQL queries.
*
* Call this method to save the array of SQL queries (generally resulting from a
* parsed XML schema) to the filesystem.
*
* @param string $filename Path and name where the file should be saved.
* @return boolean TRUE if save is successful, else FALSE.
*/
function SaveSQL( $filename = './schema.sql' ) {
if( !isset( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
}
if( !isset( $sqlArray ) ) {
return FALSE;
}
$fp = fopen( $filename, "w" );
foreach( $sqlArray as $key => $query ) {
fwrite( $fp, $query . ";\n" );
}
fclose( $fp );
}
/**
* Create an xml parser
*
* @return object PHP XML parser object
*
* @access private
*/
function create_parser() {
// Create the parser
$xmlParser = xml_parser_create();
xml_set_object( $xmlParser, $this );
// Initialize the XML callback functions
xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );
xml_set_character_data_handler( $xmlParser, '_tag_cdata' );
return $xmlParser;
}
/**
* XML Callback to process start elements
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
switch( strtoupper( $tag ) ) {
case 'TABLE':
$this->obj = new dbTable( $this, $attributes );
xml_set_object( $parser, $this->obj );
break;
case 'SQL':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$this->obj = new dbQuerySet( $this, $attributes );
xml_set_object( $parser, $this->obj );
}
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
}
/**
* XML Callback to process end elements
*
* @access private
* @internal
*/
function _tag_close( &$parser, $tag ) {
}
/**
* Converts an XML schema string to the specified DTD version.
*
* Call this method to convert a string containing an XML schema to a different AXMLS
* DTD version. For instance, to convert a schema created for an pre-1.0 version for
* AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
* parameter is specified, the schema will be converted to the current DTD version.
* If the newFile parameter is provided, the converted schema will be written to the specified
* file.
* @see ConvertSchemaFile()
*
* @param string $schema String containing XML schema that will be converted.
* @param string $newVersion DTD version to convert to.
* @param string $newFile File name of (converted) output file.
* @return string Converted XML schema or FALSE if an error occurs.
*/
function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
// grab current version
if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
return FALSE;
}
if( !isset ($newVersion) ) {
$newVersion = $this->schemaVersion;
}
if( $version == $newVersion ) {
$result = $schema;
} else {
$result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
}
if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
fwrite( $fp, $result );
fclose( $fp );
}
return $result;
}
// compat for pre-4.3 - jlim
function _file_get_contents($path)
{
if (function_exists('file_get_contents')) return file_get_contents($path);
return join('',file($path));
}
/**
* Converts an XML schema file to the specified DTD version.
*
* Call this method to convert the specified XML schema file to a different AXMLS
* DTD version. For instance, to convert a schema created for an pre-1.0 version for
* AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
* parameter is specified, the schema will be converted to the current DTD version.
* If the newFile parameter is provided, the converted schema will be written to the specified
* file.
* @see ConvertSchemaString()
*
* @param string $filename Name of XML schema file that will be converted.
* @param string $newVersion DTD version to convert to.
* @param string $newFile File name of (converted) output file.
* @return string Converted XML schema or FALSE if an error occurs.
*/
function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
// grab current version
if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
return FALSE;
}
if( !isset ($newVersion) ) {
$newVersion = $this->schemaVersion;
}
if( $version == $newVersion ) {
$result = _file_get_contents( $filename );
// remove unicode BOM if present
if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
$result = substr( $result, 3 );
}
} else {
$result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
}
if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
fwrite( $fp, $result );
fclose( $fp );
}
return $result;
}
function TransformSchema( $schema, $xsl, $schematype='string' )
{
// Fail if XSLT extension is not available
if( ! function_exists( 'xslt_create' ) ) {
return FALSE;
}
$xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';
// look for xsl
if( !is_readable( $xsl_file ) ) {
return FALSE;
}
switch( $schematype )
{
case 'file':
if( !is_readable( $schema ) ) {
return FALSE;
}
$schema = _file_get_contents( $schema );
break;
case 'string':
default:
if( !is_string( $schema ) ) {
return FALSE;
}
}
$arguments = array (
'/_xml' => $schema,
'/_xsl' => _file_get_contents( $xsl_file )
);
// create an XSLT processor
$xh = xslt_create ();
// set error handler
xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
// process the schema
$result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
xslt_free ($xh);
return $result;
}
/**
* Processes XSLT transformation errors
*
* @param object $parser XML parser object
* @param integer $errno Error number
* @param integer $level Error level
* @param array $fields Error information fields
*
* @access private
*/
function xslt_error_handler( $parser, $errno, $level, $fields ) {
if( is_array( $fields ) ) {
$msg = array(
'Message Type' => ucfirst( $fields['msgtype'] ),
'Message Code' => $fields['code'],
'Message' => $fields['msg'],
'Error Number' => $errno,
'Level' => $level
);
switch( $fields['URI'] ) {
case 'arg:/_xml':
$msg['Input'] = 'XML';
break;
case 'arg:/_xsl':
$msg['Input'] = 'XSL';
break;
default:
$msg['Input'] = $fields['URI'];
}
$msg['Line'] = $fields['line'];
} else {
$msg = array(
'Message Type' => 'Error',
'Error Number' => $errno,
'Level' => $level,
'Fields' => var_export( $fields, TRUE )
);
}
$error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"
. '<table>' . "\n";
foreach( $msg as $label => $details ) {
$error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";
}
$error_details .= '</table>';
trigger_error( $error_details, E_USER_ERROR );
}
/**
* Returns the AXMLS Schema Version of the requested XML schema file.
*
* Call this method to obtain the AXMLS DTD version of the requested XML schema file.
* @see SchemaStringVersion()
*
* @param string $filename AXMLS schema file
* @return string Schema version number or FALSE on error
*/
function SchemaFileVersion( $filename ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
// die( 'Unable to open file' );
return FALSE;
}
// Process the file
while( $data = fread( $fp, 4096 ) ) {
if( preg_match( $this->versionRegex, $data, $matches ) ) {
return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
}
}
return FALSE;
}
/**
* Returns the AXMLS Schema Version of the provided XML schema string.
*
* Call this method to obtain the AXMLS DTD version of the provided XML schema string.
* @see SchemaFileVersion()
*
* @param string $xmlstring XML schema string
* @return string Schema version number or FALSE on error
*/
function SchemaStringVersion( $xmlstring ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
}
if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {
return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
}
return FALSE;
}
/**
* Extracts an XML schema from an existing database.
*
* Call this method to create an XML schema string from an existing database.
* If the data parameter is set to TRUE, AXMLS will include the data from the database
* in the schema.
*
* @param boolean $data Include data in schema dump
* @return string Generated XML schema
*/
function ExtractSchema( $data = FALSE ) {
$old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
$schema = '<?xml version="1.0"?>' . "\n"
. '<schema version="' . $this->schemaVersion . '">' . "\n";
if( is_array( $tables = $this->db->MetaTables( 'TABLES' ) ) ) {
foreach( $tables as $table ) {
$schema .= ' <table name="' . $table . '">' . "\n";
// grab details from database
$rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE 1=1' );
$fields = $this->db->MetaColumns( $table );
$indexes = $this->db->MetaIndexes( $table );
if( is_array( $fields ) ) {
foreach( $fields as $details ) {
$extra = '';
$content = array();
if( $details->max_length > 0 ) {
$extra .= ' size="' . $details->max_length . '"';
}
if( $details->primary_key ) {
$content[] = '<KEY/>';
} elseif( $details->not_null ) {
$content[] = '<NOTNULL/>';
}
if( $details->has_default ) {
$content[] = '<DEFAULT value="' . $details->default_value . '"/>';
}
if( $details->auto_increment ) {
$content[] = '<AUTOINCREMENT/>';
}
// this stops the creation of 'R' columns,
// AUTOINCREMENT is used to create auto columns
$details->primary_key = 0;
$type = $rs->MetaType( $details );
$schema .= ' <field name="' . $details->name . '" type="' . $type . '"' . $extra . '>';
if( !empty( $content ) ) {
$schema .= "\n " . implode( "\n ", $content ) . "\n ";
}
$schema .= '</field>' . "\n";
}
}
if( is_array( $indexes ) ) {
foreach( $indexes as $index => $details ) {
$schema .= ' <index name="' . $index . '">' . "\n";
if( $details['unique'] ) {
$schema .= ' <UNIQUE/>' . "\n";
}
foreach( $details['columns'] as $column ) {
$schema .= ' <col>' . $column . '</col>' . "\n";
}
$schema .= ' </index>' . "\n";
}
}
if( $data ) {
$rs = $this->db->Execute( 'SELECT * FROM ' . $table );
if( is_object( $rs ) ) {
$schema .= ' <data>' . "\n";
while( $row = $rs->FetchRow() ) {
foreach( $row as $key => $val ) {
$row[$key] = htmlentities($val);
}
$schema .= ' <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n";
}
$schema .= ' </data>' . "\n";
}
}
$schema .= ' </table>' . "\n";
}
}
$this->db->SetFetchMode( $old_mode );
$schema .= '</schema>';
return $schema;
}
/**
* Sets a prefix for database objects
*
* Call this method to set a standard prefix that will be prepended to all database tables
* and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
*
* @param string $prefix Prefix that will be prepended.
* @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
* @return boolean TRUE if successful, else FALSE
*/
function SetPrefix( $prefix = '', $underscore = TRUE ) {
switch( TRUE ) {
// clear prefix
case empty( $prefix ):
logMsg( 'Cleared prefix' );
$this->objectPrefix = '';
return TRUE;
// prefix too long
case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
// prefix contains invalid characters
case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
logMsg( 'Invalid prefix: ' . $prefix );
return FALSE;
}
if( $underscore AND substr( $prefix, -1 ) != '_' ) {
$prefix .= '_';
}
// prefix valid
logMsg( 'Set prefix: ' . $prefix );
$this->objectPrefix = $prefix;
return TRUE;
}
/**
* Returns an object name with the current prefix prepended.
*
* @param string $name Name
* @return string Prefixed name
*
* @access private
*/
function prefix( $name = '' ) {
// if prefix is set
if( !empty( $this->objectPrefix ) ) {
// Prepend the object prefix to the table name
// prepend after quote if used
return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );
}
// No prefix set. Use name provided.
return $name;
}
/**
* Checks if element references a specific platform
*
* @param string $platform Requested platform
* @returns boolean TRUE if platform check succeeds
*
* @access private
*/
function supportedPlatform( $platform = NULL ) {
$regex = '/^(\w*\|)*' . $this->db->databaseType . '(\|\w*)*$/';
if( !isset( $platform ) OR preg_match( $regex, $platform ) ) {
logMsg( "Platform $platform is supported" );
return TRUE;
} else {
logMsg( "Platform $platform is NOT supported" );
return FALSE;
}
}
/**
* Clears the array of generated SQL.
*
* @access private
*/
function clearSQL() {
$this->sqlArray = array();
}
/**
* Adds SQL into the SQL array.
*
* @param mixed $sql SQL to Add
* @return boolean TRUE if successful, else FALSE.
*
* @access private
*/
function addSQL( $sql = NULL ) {
if( is_array( $sql ) ) {
foreach( $sql as $line ) {
$this->addSQL( $line );
}
return TRUE;
}
if( is_string( $sql ) ) {
$this->sqlArray[] = $sql;
// if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.
if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {
$saved = $this->db->debug;
$this->db->debug = $this->debug;
$ok = $this->db->Execute( $sql );
$this->db->debug = $saved;
if( !$ok ) {
if( $this->debug ) {
ADOConnection::outp( $this->db->ErrorMsg() );
}
$this->success = 1;
}
}
return TRUE;
}
return FALSE;
}
/**
* Gets the SQL array in the specified format.
*
* @param string $format Format
* @return mixed SQL
*
* @access private
*/
function getSQL( $format = NULL, $sqlArray = NULL ) {
if( !is_array( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
}
if( !is_array( $sqlArray ) ) {
return FALSE;
}
switch( strtolower( $format ) ) {
case 'string':
case 'text':
return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';
case'html':
return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';
}
return $this->sqlArray;
}
/**
* Destroys an adoSchema object.
*
* Call this method to clean up after an adoSchema object that is no longer in use.
* @deprecated adoSchema now cleans up automatically.
*/
function Destroy() {
ini_set("magic_quotes_runtime", $this->mgq );
#set_magic_quotes_runtime( $this->mgq );
}
}
/**
* Message logging function
*
* @access private
*/
function logMsg( $msg, $title = NULL, $force = FALSE ) {
if( XMLS_DEBUG or $force ) {
echo '<pre>';
if( isset( $title ) ) {
echo '<h3>' . htmlentities( $title ) . '</h3>';
}
if( is_object( $this ) ) {
echo '[' . get_class( $this ) . '] ';
}
print_r( $msg );
echo '</pre>';
}
}
-2406
View File
@@ -1,2406 +0,0 @@
<?php
// Copyright (c) 2004-2005 ars Cognita Inc., all rights reserved
/* ******************************************************************************
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
*******************************************************************************/
/**
* xmlschema is a class that allows the user to quickly and easily
* build a database on any ADOdb-supported platform using a simple
* XML schema.
*
* Last Editor: $Author: jlim $
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision: 1.62 $
*
* @package axmls
* @tutorial getting_started.pkg
*/
function _file_get_contents($file)
{
if (function_exists('file_get_contents')) return file_get_contents($file);
$f = fopen($file,'r');
if (!$f) return '';
$t = '';
while ($s = fread($f,100000)) $t .= $s;
fclose($f);
return $t;
}
/**
* Debug on or off
*/
if( !defined( 'XMLS_DEBUG' ) ) {
define( 'XMLS_DEBUG', FALSE );
}
/**
* Default prefix key
*/
if( !defined( 'XMLS_PREFIX' ) ) {
define( 'XMLS_PREFIX', '%%P' );
}
/**
* Maximum length allowed for object prefix
*/
if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
define( 'XMLS_PREFIX_MAXLEN', 10 );
}
/**
* Execute SQL inline as it is generated
*/
if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
define( 'XMLS_EXECUTE_INLINE', FALSE );
}
/**
* Continue SQL Execution if an error occurs?
*/
if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
}
/**
* Current Schema Version
*/
if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
define( 'XMLS_SCHEMA_VERSION', '0.3' );
}
/**
* Default Schema Version. Used for Schemas without an explicit version set.
*/
if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
}
/**
* How to handle data rows that already exist in a database during and upgrade.
* Options are INSERT (attempts to insert duplicate rows), UPDATE (updates existing
* rows) and IGNORE (ignores existing rows).
*/
if( !defined( 'XMLS_MODE_INSERT' ) ) {
define( 'XMLS_MODE_INSERT', 0 );
}
if( !defined( 'XMLS_MODE_UPDATE' ) ) {
define( 'XMLS_MODE_UPDATE', 1 );
}
if( !defined( 'XMLS_MODE_IGNORE' ) ) {
define( 'XMLS_MODE_IGNORE', 2 );
}
if( !defined( 'XMLS_EXISTING_DATA' ) ) {
define( 'XMLS_EXISTING_DATA', XMLS_MODE_INSERT );
}
/**
* Default Schema Version. Used for Schemas without an explicit version set.
*/
if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
}
/**
* Include the main ADODB library
*/
if( !defined( '_ADODB_LAYER' ) ) {
require( 'adodb.inc.php' );
require( 'adodb-datadict.inc.php' );
}
/**
* Abstract DB Object. This class provides basic methods for database objects, such
* as tables and indexes.
*
* @package axmls
* @access private
*/
class dbObject {
/**
* var object Parent
*/
var $parent;
/**
* var string current element
*/
var $currentElement;
/**
* NOP
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
}
/**
* XML Callback to process start elements
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
}
/**
* XML Callback to process CDATA elements
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
}
function create(&$xmls) {
return array();
}
/**
* Destroys the object
*/
function destroy() {
}
/**
* Checks whether the specified RDBMS is supported by the current
* database object or its ranking ancestor.
*
* @param string $platform RDBMS platform name (from ADODB platform list).
* @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
*/
function supportedPlatform( $platform = NULL ) {
return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
}
/**
* Returns the prefix set by the ranking ancestor of the database object.
*
* @param string $name Prefix string.
* @return string Prefix.
*/
function prefix( $name = '' ) {
return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
}
/**
* Extracts a field ID from the specified field.
*
* @param string $field Field.
* @return string Field ID.
*/
function FieldID( $field ) {
return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
}
}
/**
* Creates a table object in ADOdb's datadict format
*
* This class stores information about a database table. As charactaristics
* of the table are loaded from the external source, methods and properties
* of this class are used to build up the table description in ADOdb's
* datadict format.
*
* @package axmls
* @access private
*/
class dbTable extends dbObject {
/**
* @var string Table name
*/
var $name;
/**
* @var array Field specifier: Meta-information about each field
*/
var $fields = array();
/**
* @var array List of table indexes.
*/
var $indexes = array();
/**
* @var array Table options: Table-level options
*/
var $opts = array();
/**
* @var string Field index: Keeps track of which field is currently being processed
*/
var $current_field;
/**
* @var boolean Mark table for destruction
* @access private
*/
var $drop_table;
/**
* @var boolean Mark field for destruction (not yet implemented)
* @access private
*/
var $drop_field = array();
/**
* @var array Platform-specific options
* @access private
*/
var $currentPlatform = true;
/**
* Iniitializes a new table object.
*
* @param string $prefix DB Object prefix
* @param array $attributes Array of table attributes.
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
$this->name = $this->prefix($attributes['NAME']);
}
/**
* XML Callback to process start elements. Elements currently
* processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT.
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
case 'INDEX':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$index = $this->addIndex( $attributes );
xml_set_object( $parser, $index );
}
break;
case 'DATA':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$data = $this->addData( $attributes );
xml_set_object( $parser, $data );
}
break;
case 'DROP':
$this->drop();
break;
case 'FIELD':
// Add a field
$fieldName = $attributes['NAME'];
$fieldType = $attributes['TYPE'];
$fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;
$fieldOpts = !empty( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;
$this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
break;
case 'KEY':
case 'NOTNULL':
case 'AUTOINCREMENT':
case 'DEFDATE':
case 'DEFTIMESTAMP':
case 'UNSIGNED':
// Add a field option
$this->addFieldOpt( $this->current_field, $this->currentElement );
break;
case 'DEFAULT':
// Add a field option to the table object
// Work around ADOdb datadict issue that misinterprets empty strings.
if( $attributes['VALUE'] == '' ) {
$attributes['VALUE'] = " '' ";
}
$this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );
break;
case 'OPT':
case 'CONSTRAINT':
// Accept platform-specific options
$this->currentPlatform = ( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) );
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Table/field constraint
case 'CONSTRAINT':
if( isset( $this->current_field ) ) {
$this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );
} else {
$this->addTableOpt( $cdata );
}
break;
// Table/field option
case 'OPT':
if( isset( $this->current_field ) ) {
$this->addFieldOpt( $this->current_field, $cdata );
} else {
$this->addTableOpt( $cdata );
}
break;
default:
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
case 'TABLE':
$this->parent->addSQL( $this->create( $this->parent ) );
xml_set_object( $parser, $this->parent );
$this->destroy();
break;
case 'FIELD':
unset($this->current_field);
break;
case 'OPT':
case 'CONSTRAINT':
$this->currentPlatform = true;
break;
default:
}
}
/**
* Adds an index to a table object
*
* @param array $attributes Index attributes
* @return object dbIndex object
*/
function addIndex( $attributes ) {
$name = strtoupper( $attributes['NAME'] );
$this->indexes[$name] = new dbIndex( $this, $attributes );
return $this->indexes[$name];
}
/**
* Adds data to a table object
*
* @param array $attributes Data attributes
* @return object dbData object
*/
function addData( $attributes ) {
if( !isset( $this->data ) ) {
$this->data = new dbData( $this, $attributes );
}
return $this->data;
}
/**
* Adds a field to a table object
*
* $name is the name of the table to which the field should be added.
* $type is an ADODB datadict field type. The following field types
* are supported as of ADODB 3.40:
* - C: varchar
* - X: CLOB (character large object) or largest varchar size
* if CLOB is not supported
* - C2: Multibyte varchar
* - X2: Multibyte CLOB
* - B: BLOB (binary large object)
* - D: Date (some databases do not support this, and we return a datetime type)
* - T: Datetime or Timestamp
* - L: Integer field suitable for storing booleans (0 or 1)
* - I: Integer (mapped to I4)
* - I1: 1-byte integer
* - I2: 2-byte integer
* - I4: 4-byte integer
* - I8: 8-byte integer
* - F: Floating point number
* - N: Numeric or decimal number
*
* @param string $name Name of the table to which the field will be added.
* @param string $type ADODB datadict field type.
* @param string $size Field size
* @param array $opts Field options array
* @return array Field specifier array
*/
function addField( $name, $type, $size = NULL, $opts = NULL ) {
$field_id = $this->FieldID( $name );
// Set the field index so we know where we are
$this->current_field = $field_id;
// Set the field name (required)
$this->fields[$field_id]['NAME'] = $name;
// Set the field type (required)
$this->fields[$field_id]['TYPE'] = $type;
// Set the field size (optional)
if( isset( $size ) ) {
$this->fields[$field_id]['SIZE'] = $size;
}
// Set the field options
if( isset( $opts ) ) {
$this->fields[$field_id]['OPTS'] = array($opts);
} else {
$this->fields[$field_id]['OPTS'] = array();
}
}
/**
* Adds a field option to the current field specifier
*
* This method adds a field option allowed by the ADOdb datadict
* and appends it to the given field.
*
* @param string $field Field name
* @param string $opt ADOdb field option
* @param mixed $value Field option value
* @return array Field specifier array
*/
function addFieldOpt( $field, $opt, $value = NULL ) {
if( $this->currentPlatform ) {
if( !isset( $value ) ) {
$this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;
// Add the option and value
} else {
$this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );
}
}
}
/**
* Adds an option to the table
*
* This method takes a comma-separated list of table-level options
* and appends them to the table object.
*
* @param string $opt Table option
* @return array Options
*/
function addTableOpt( $opt ) {
if(isset($this->currentPlatform)) {
$this->opts[$this->parent->db->databaseType] = $opt;
}
return $this->opts;
}
/**
* Generates the SQL that will create the table in the database
*
* @param object $xmls adoSchema object
* @return array Array containing table creation SQL
*/
function create( &$xmls ) {
$sql = array();
// drop any existing indexes
if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {
foreach( $legacy_indexes as $index => $index_details ) {
$sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );
}
}
// remove fields to be dropped from table object
foreach( $this->drop_field as $field ) {
unset( $this->fields[$field] );
}
// if table exists
if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {
// drop table
if( $this->drop_table ) {
$sql[] = $xmls->dict->DropTableSQL( $this->name );
return $sql;
}
// drop any existing fields not in schema
foreach( $legacy_fields as $field_id => $field ) {
if( !isset( $this->fields[$field_id] ) ) {
$sql[] = $xmls->dict->DropColumnSQL( $this->name, $field->name );
}
}
// if table doesn't exist
} else {
if( $this->drop_table ) {
return $sql;
}
$legacy_fields = array();
}
// Loop through the field specifier array, building the associative array for the field options
$fldarray = array();
foreach( $this->fields as $field_id => $finfo ) {
// Set an empty size if it isn't supplied
if( !isset( $finfo['SIZE'] ) ) {
$finfo['SIZE'] = '';
}
// Initialize the field array with the type and size
$fldarray[$field_id] = array(
'NAME' => $finfo['NAME'],
'TYPE' => $finfo['TYPE'],
'SIZE' => $finfo['SIZE']
);
// Loop through the options array and add the field options.
if( isset( $finfo['OPTS'] ) ) {
foreach( $finfo['OPTS'] as $opt ) {
// Option has an argument.
if( is_array( $opt ) ) {
$key = key( $opt );
$value = $opt[key( $opt )];
@$fldarray[$field_id][$key] .= $value;
// Option doesn't have arguments
} else {
$fldarray[$field_id][$opt] = $opt;
}
}
}
}
if( empty( $legacy_fields ) ) {
// Create the new table
$sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
logMsg( end( $sql ), 'Generated CreateTableSQL' );
} else {
// Upgrade an existing table
logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );
switch( $xmls->upgrade ) {
// Use ChangeTableSQL
case 'ALTER':
logMsg( 'Generated ChangeTableSQL (ALTERing table)' );
$sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );
break;
case 'REPLACE':
logMsg( 'Doing upgrade REPLACE (testing)' );
$sql[] = $xmls->dict->DropTableSQL( $this->name );
$sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
break;
// ignore table
default:
return array();
}
}
foreach( $this->indexes as $index ) {
$sql[] = $index->create( $xmls );
}
if( isset( $this->data ) ) {
$sql[] = $this->data->create( $xmls );
}
return $sql;
}
/**
* Marks a field or table for destruction
*/
function drop() {
if( isset( $this->current_field ) ) {
// Drop the current field
logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );
// $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );
$this->drop_field[$this->current_field] = $this->current_field;
} else {
// Drop the current table
logMsg( "Dropping table '{$this->name}'" );
// $this->drop_table = $xmls->dict->DropTableSQL( $this->name );
$this->drop_table = TRUE;
}
}
}
/**
* Creates an index object in ADOdb's datadict format
*
* This class stores information about a database index. As charactaristics
* of the index are loaded from the external source, methods and properties
* of this class are used to build up the index description in ADOdb's
* datadict format.
*
* @package axmls
* @access private
*/
class dbIndex extends dbObject {
/**
* @var string Index name
*/
var $name;
/**
* @var array Index options: Index-level options
*/
var $opts = array();
/**
* @var array Indexed fields: Table columns included in this index
*/
var $columns = array();
/**
* @var boolean Mark index for destruction
* @access private
*/
var $drop = FALSE;
/**
* Initializes the new dbIndex object.
*
* @param object $parent Parent object
* @param array $attributes Attributes
*
* @internal
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
$this->name = $this->prefix ($attributes['NAME']);
}
/**
* XML Callback to process start elements
*
* Processes XML opening tags.
* Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
case 'DROP':
$this->drop();
break;
case 'CLUSTERED':
case 'BITMAP':
case 'UNIQUE':
case 'FULLTEXT':
case 'HASH':
// Add index Option
$this->addIndexOpt( $this->currentElement );
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
* Processes XML cdata.
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
case 'COL':
$this->addField( $cdata );
break;
default:
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
case 'INDEX':
xml_set_object( $parser, $this->parent );
break;
}
}
/**
* Adds a field to the index
*
* @param string $name Field name
* @return string Field list
*/
function addField( $name ) {
$this->columns[$this->FieldID( $name )] = $name;
// Return the field list
return $this->columns;
}
/**
* Adds options to the index
*
* @param string $opt Comma-separated list of index options.
* @return string Option list
*/
function addIndexOpt( $opt ) {
$this->opts[] = $opt;
// Return the options list
return $this->opts;
}
/**
* Generates the SQL that will create the index in the database
*
* @param object $xmls adoSchema object
* @return array Array containing index creation SQL
*/
function create( &$xmls ) {
if( $this->drop ) {
return NULL;
}
// eliminate any columns that aren't in the table
foreach( $this->columns as $id => $col ) {
if( !isset( $this->parent->fields[$id] ) ) {
unset( $this->columns[$id] );
}
}
return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
}
/**
* Marks an index for destruction
*/
function drop() {
$this->drop = TRUE;
}
}
/**
* Creates a data object in ADOdb's datadict format
*
* This class stores information about table data, and is called
* when we need to load field data into a table.
*
* @package axmls
* @access private
*/
class dbData extends dbObject {
var $data = array();
var $row;
/**
* Initializes the new dbData object.
*
* @param object $parent Parent object
* @param array $attributes Attributes
*
* @internal
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
}
/**
* XML Callback to process start elements
*
* Processes XML opening tags.
* Elements currently processed are: ROW and F (field).
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
case 'ROW':
$this->row = count( $this->data );
$this->data[$this->row] = array();
break;
case 'F':
$this->addField($attributes);
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
* Processes XML cdata.
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
case 'F':
$this->addData( $cdata );
break;
default:
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
case 'DATA':
xml_set_object( $parser, $this->parent );
break;
}
}
/**
* Adds a field to the insert
*
* @param string $name Field name
* @return string Field list
*/
function addField( $attributes ) {
// check we're in a valid row
if( !isset( $this->row ) || !isset( $this->data[$this->row] ) ) {
return;
}
// Set the field index so we know where we are
if( isset( $attributes['NAME'] ) ) {
$this->current_field = $this->FieldID( $attributes['NAME'] );
} else {
$this->current_field = count( $this->data[$this->row] );
}
// initialise data
if( !isset( $this->data[$this->row][$this->current_field] ) ) {
$this->data[$this->row][$this->current_field] = '';
}
}
/**
* Adds options to the index
*
* @param string $opt Comma-separated list of index options.
* @return string Option list
*/
function addData( $cdata ) {
// check we're in a valid field
if ( isset( $this->data[$this->row][$this->current_field] ) ) {
// add data to field
$this->data[$this->row][$this->current_field] .= $cdata;
}
}
/**
* Generates the SQL that will add/update the data in the database
*
* @param object $xmls adoSchema object
* @return array Array containing index creation SQL
*/
function create( &$xmls ) {
$table = $xmls->dict->TableName($this->parent->name);
$table_field_count = count($this->parent->fields);
$tables = $xmls->db->MetaTables();
$sql = array();
$ukeys = $xmls->db->MetaPrimaryKeys( $table );
if( !empty( $this->parent->indexes ) and !empty( $ukeys ) ) {
foreach( $this->parent->indexes as $indexObj ) {
if( !in_array( $indexObj->name, $ukeys ) ) $ukeys[] = $indexObj->name;
}
}
// eliminate any columns that aren't in the table
foreach( $this->data as $row ) {
$table_fields = $this->parent->fields;
$fields = array();
$rawfields = array(); // Need to keep some of the unprocessed data on hand.
foreach( $row as $field_id => $field_data ) {
if( !array_key_exists( $field_id, $table_fields ) ) {
if( is_numeric( $field_id ) ) {
$field_id = reset( array_keys( $table_fields ) );
} else {
continue;
}
}
$name = $table_fields[$field_id]['NAME'];
switch( $table_fields[$field_id]['TYPE'] ) {
case 'I':
case 'I1':
case 'I2':
case 'I4':
case 'I8':
$fields[$name] = intval($field_data);
break;
case 'C':
case 'C2':
case 'X':
case 'X2':
default:
$fields[$name] = $xmls->db->qstr( $field_data );
$rawfields[$name] = $field_data;
}
unset($table_fields[$field_id]);
}
// check that at least 1 column is specified
if( empty( $fields ) ) {
continue;
}
// check that no required columns are missing
if( count( $fields ) < $table_field_count ) {
foreach( $table_fields as $field ) {
if( isset( $field['OPTS'] ) and ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {
continue(2);
}
}
}
// The rest of this method deals with updating existing data records.
if( !in_array( $table, $tables ) or ( $mode = $xmls->existingData() ) == XMLS_MODE_INSERT ) {
// Table doesn't yet exist, so it's safe to insert.
logMsg( "$table doesn't exist, inserting or mode is INSERT" );
$sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
continue;
}
// Prepare to test for potential violations. Get primary keys and unique indexes
$mfields = array_merge( $fields, $rawfields );
$keyFields = array_intersect( $ukeys, array_keys( $mfields ) );
if( empty( $ukeys ) or count( $keyFields ) == 0 ) {
// No unique keys in schema, so safe to insert
logMsg( "Either schema or data has no unique keys, so safe to insert" );
$sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
continue;
}
// Select record containing matching unique keys.
$where = '';
foreach( $ukeys as $key ) {
if( isset( $mfields[$key] ) and $mfields[$key] ) {
if( $where ) $where .= ' AND ';
$where .= $key . ' = ' . $xmls->db->qstr( $mfields[$key] );
}
}
$records = $xmls->db->Execute( 'SELECT * FROM ' . $table . ' WHERE ' . $where );
switch( $records->RecordCount() ) {
case 0:
// No matching record, so safe to insert.
logMsg( "No matching records. Inserting new row with unique data" );
$sql[] = $xmls->db->GetInsertSQL( $records, $mfields );
break;
case 1:
// Exactly one matching record, so we can update if the mode permits.
logMsg( "One matching record..." );
if( $mode == XMLS_MODE_UPDATE ) {
logMsg( "...Updating existing row from unique data" );
$sql[] = $xmls->db->GetUpdateSQL( $records, $mfields );
}
break;
default:
// More than one matching record; the result is ambiguous, so we must ignore the row.
logMsg( "More than one matching record. Ignoring row." );
}
}
return $sql;
}
}
/**
* Creates the SQL to execute a list of provided SQL queries
*
* @package axmls
* @access private
*/
class dbQuerySet extends dbObject {
/**
* @var array List of SQL queries
*/
var $queries = array();
/**
* @var string String used to build of a query line by line
*/
var $query;
/**
* @var string Query prefix key
*/
var $prefixKey = '';
/**
* @var boolean Auto prefix enable (TRUE)
*/
var $prefixMethod = 'AUTO';
/**
* Initializes the query set.
*
* @param object $parent Parent object
* @param array $attributes Attributes
*/
function __construct( &$parent, $attributes = NULL ) {
$this->parent = $parent;
// Overrides the manual prefix key
if( isset( $attributes['KEY'] ) ) {
$this->prefixKey = $attributes['KEY'];
}
$prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';
// Enables or disables automatic prefix prepending
switch( $prefixMethod ) {
case 'AUTO':
$this->prefixMethod = 'AUTO';
break;
case 'MANUAL':
$this->prefixMethod = 'MANUAL';
break;
case 'NONE':
$this->prefixMethod = 'NONE';
break;
}
}
/**
* XML Callback to process start elements. Elements currently
* processed are: QUERY.
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
case 'QUERY':
// Create a new query in a SQL queryset.
// Ignore this query set if a platform is specified and it's different than the
// current connection platform.
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$this->newQuery();
} else {
$this->discardQuery();
}
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*/
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Line of queryset SQL data
case 'QUERY':
$this->buildQuery( $cdata );
break;
default:
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
case 'QUERY':
// Add the finished query to the open query set.
$this->addQuery();
break;
case 'SQL':
$this->parent->addSQL( $this->create( $this->parent ) );
xml_set_object( $parser, $this->parent );
$this->destroy();
break;
default:
}
}
/**
* Re-initializes the query.
*
* @return boolean TRUE
*/
function newQuery() {
$this->query = '';
return TRUE;
}
/**
* Discards the existing query.
*
* @return boolean TRUE
*/
function discardQuery() {
unset( $this->query );
return TRUE;
}
/**
* Appends a line to a query that is being built line by line
*
* @param string $data Line of SQL data or NULL to initialize a new query
* @return string SQL query string.
*/
function buildQuery( $sql = NULL ) {
if( !isset( $this->query ) OR empty( $sql ) ) {
return FALSE;
}
$this->query .= $sql;
return $this->query;
}
/**
* Adds a completed query to the query list
*
* @return string SQL of added query
*/
function addQuery() {
if( !isset( $this->query ) ) {
return FALSE;
}
$this->queries[] = $return = trim($this->query);
unset( $this->query );
return $return;
}
/**
* Creates and returns the current query set
*
* @param object $xmls adoSchema object
* @return array Query set
*/
function create( &$xmls ) {
foreach( $this->queries as $id => $query ) {
switch( $this->prefixMethod ) {
case 'AUTO':
// Enable auto prefix replacement
// Process object prefix.
// Evaluate SQL statements to prepend prefix to objects
$query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
$query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
$query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
// SELECT statements aren't working yet
#$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );
case 'MANUAL':
// If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.
// If prefixKey is not set, we use the default constant XMLS_PREFIX
if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {
// Enable prefix override
$query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );
} else {
// Use default replacement
$query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );
}
}
$this->queries[$id] = trim( $query );
}
// Return the query set array
return $this->queries;
}
/**
* Rebuilds the query with the prefix attached to any objects
*
* @param string $regex Regex used to add prefix
* @param string $query SQL query string
* @param string $prefix Prefix to be appended to tables, indices, etc.
* @return string Prefixed SQL query string.
*/
function prefixQuery( $regex, $query, $prefix = NULL ) {
if( !isset( $prefix ) ) {
return $query;
}
if( preg_match( $regex, $query, $match ) ) {
$preamble = $match[1];
$postamble = $match[5];
$objectList = explode( ',', $match[3] );
// $prefix = $prefix . '_';
$prefixedList = '';
foreach( $objectList as $object ) {
if( $prefixedList !== '' ) {
$prefixedList .= ', ';
}
$prefixedList .= $prefix . trim( $object );
}
$query = $preamble . ' ' . $prefixedList . ' ' . $postamble;
}
return $query;
}
}
/**
* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
*
* This class is used to load and parse the XML file, to create an array of SQL statements
* that can be used to build a database, and to build the database using the SQL array.
*
* @tutorial getting_started.pkg
*
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision: 1.62 $
*
* @package axmls
*/
class adoSchema {
/**
* @var array Array containing SQL queries to generate all objects
* @access private
*/
var $sqlArray;
/**
* @var object ADOdb connection object
* @access private
*/
var $db;
/**
* @var object ADOdb Data Dictionary
* @access private
*/
var $dict;
/**
* @var string Current XML element
* @access private
*/
var $currentElement = '';
/**
* @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
* @access private
*/
var $upgrade = '';
/**
* @var string Optional object prefix
* @access private
*/
var $objectPrefix = '';
/**
* @var long Original Magic Quotes Runtime value
* @access private
*/
var $mgq;
/**
* @var long System debug
* @access private
*/
var $debug;
/**
* @var string Regular expression to find schema version
* @access private
*/
var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';
/**
* @var string Current schema version
* @access private
*/
var $schemaVersion;
/**
* @var int Success of last Schema execution
*/
var $success;
/**
* @var bool Execute SQL inline as it is generated
*/
var $executeInline;
/**
* @var bool Continue SQL execution if errors occur
*/
var $continueOnError;
/**
* @var int How to handle existing data rows (insert, update, or ignore)
*/
var $existingData;
/**
* Creates an adoSchema object
*
* Creating an adoSchema object is the first step in processing an XML schema.
* The only parameter is an ADOdb database connection object, which must already
* have been created.
*
* @param object $db ADOdb database connection object.
*/
function __construct( $db ) {
// Initialize the environment
$this->mgq = get_magic_quotes_runtime();
#set_magic_quotes_runtime(0);
ini_set("magic_quotes_runtime", 0);
$this->db = $db;
$this->debug = $this->db->debug;
$this->dict = NewDataDictionary( $this->db );
$this->sqlArray = array();
$this->schemaVersion = XMLS_SCHEMA_VERSION;
$this->executeInline( XMLS_EXECUTE_INLINE );
$this->continueOnError( XMLS_CONTINUE_ON_ERROR );
$this->existingData( XMLS_EXISTING_DATA );
$this->setUpgradeMethod();
}
/**
* Sets the method to be used for upgrading an existing database
*
* Use this method to specify how existing database objects should be upgraded.
* The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
* alter each database object directly, REPLACE attempts to rebuild each object
* from scratch, BEST attempts to determine the best upgrade method for each
* object, and NONE disables upgrading.
*
* This method is not yet used by AXMLS, but exists for backward compatibility.
* The ALTER method is automatically assumed when the adoSchema object is
* instantiated; other upgrade methods are not currently supported.
*
* @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
* @returns string Upgrade method used
*/
function SetUpgradeMethod( $method = '' ) {
if( !is_string( $method ) ) {
return FALSE;
}
$method = strtoupper( $method );
// Handle the upgrade methods
switch( $method ) {
case 'ALTER':
$this->upgrade = $method;
break;
case 'REPLACE':
$this->upgrade = $method;
break;
case 'BEST':
$this->upgrade = 'ALTER';
break;
case 'NONE':
$this->upgrade = 'NONE';
break;
default:
// Use default if no legitimate method is passed.
$this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;
}
return $this->upgrade;
}
/**
* Specifies how to handle existing data row when there is a unique key conflict.
*
* The existingData setting specifies how the parser should handle existing rows
* when a unique key violation occurs during the insert. This can happen when inserting
* data into an existing table with one or more primary keys or unique indexes.
* The existingData method takes one of three options: XMLS_MODE_INSERT attempts
* to always insert the data as a new row. In the event of a unique key violation,
* the database will generate an error. XMLS_MODE_UPDATE attempts to update the
* any existing rows with the new data based upon primary or unique key fields in
* the schema. If the data row in the schema specifies no unique fields, the row
* data will be inserted as a new row. XMLS_MODE_IGNORE specifies that any data rows
* that would result in a unique key violation be ignored; no inserts or updates will
* take place. For backward compatibility, the default setting is XMLS_MODE_INSERT,
* but XMLS_MODE_UPDATE will generally be the most appropriate setting.
*
* @param int $mode XMLS_MODE_INSERT, XMLS_MODE_UPDATE, or XMLS_MODE_IGNORE
* @return int current mode
*/
function ExistingData( $mode = NULL ) {
if( is_int( $mode ) ) {
switch( $mode ) {
case XMLS_MODE_UPDATE:
$mode = XMLS_MODE_UPDATE;
break;
case XMLS_MODE_IGNORE:
$mode = XMLS_MODE_IGNORE;
break;
case XMLS_MODE_INSERT:
$mode = XMLS_MODE_INSERT;
break;
default:
$mode = XMLS_EXISTING_DATA;
break;
}
$this->existingData = $mode;
}
return $this->existingData;
}
/**
* Enables/disables inline SQL execution.
*
* Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
* AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
* is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
* to apply the schema to the database.
*
* @param bool $mode execute
* @return bool current execution mode
*
* @see ParseSchema(), ExecuteSchema()
*/
function ExecuteInline( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->executeInline = $mode;
}
return $this->executeInline;
}
/**
* Enables/disables SQL continue on error.
*
* Call this method to enable or disable continuation of SQL execution if an error occurs.
* If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
* If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
* of the schema will continue.
*
* @param bool $mode execute
* @return bool current continueOnError mode
*
* @see addSQL(), ExecuteSchema()
*/
function ContinueOnError( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->continueOnError = $mode;
}
return $this->continueOnError;
}
/**
* Loads an XML schema from a file and converts it to SQL.
*
* Call this method to load the specified schema (see the DTD for the proper format) from
* the filesystem and generate the SQL necessary to create the database
* described. This method automatically converts the schema to the latest
* axmls schema version.
* @see ParseSchemaString()
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute
*/
function ParseSchema( $filename, $returnSchema = FALSE ) {
return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
* Loads an XML schema from a file and converts it to SQL.
*
* Call this method to load the specified schema directly from a file (see
* the DTD for the proper format) and generate the SQL necessary to create
* the database described by the schema. Use this method when you are dealing
* with large schema files. Otherwise, ParseSchema() is faster.
* This method does not automatically convert the schema to the latest axmls
* schema version. You must convert the schema manually using either the
* ConvertSchemaFile() or ConvertSchemaString() method.
* @see ParseSchema()
* @see ConvertSchemaFile()
* @see ConvertSchemaString()
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*
* @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
* @see ParseSchema(), ParseSchemaString()
*/
function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
logMsg( 'Unable to open file' );
return FALSE;
}
// do version detection here
if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
logMsg( 'Invalid Schema Version' );
return FALSE;
}
if( $returnSchema ) {
$xmlstring = '';
while( $data = fread( $fp, 4096 ) ) {
$xmlstring .= $data . "\n";
}
return $xmlstring;
}
$this->success = 2;
$xmlParser = $this->create_parser();
// Process the file
while( $data = fread( $fp, 4096 ) ) {
if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
die( sprintf(
"XML error: %s at line %d",
xml_error_string( xml_get_error_code( $xmlParser) ),
xml_get_current_line_number( $xmlParser)
) );
}
}
xml_parser_free( $xmlParser );
return $this->sqlArray;
}
/**
* Converts an XML schema string to SQL.
*
* Call this method to parse a string containing an XML schema (see the DTD for the proper format)
* and generate the SQL necessary to create the database described by the schema.
* @see ParseSchema()
*
* @param string $xmlstring XML schema string.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*/
function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
logMsg( 'Empty or Invalid Schema' );
return FALSE;
}
// do version detection here
if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {
logMsg( 'Invalid Schema Version' );
return FALSE;
}
if( $returnSchema ) {
return $xmlstring;
}
$this->success = 2;
$xmlParser = $this->create_parser();
if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {
die( sprintf(
"XML error: %s at line %d",
xml_error_string( xml_get_error_code( $xmlParser) ),
xml_get_current_line_number( $xmlParser)
) );
}
xml_parser_free( $xmlParser );
return $this->sqlArray;
}
/**
* Loads an XML schema from a file and converts it to uninstallation SQL.
*
* Call this method to load the specified schema (see the DTD for the proper format) from
* the filesystem and generate the SQL necessary to remove the database described.
* @see RemoveSchemaString()
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute
*/
function RemoveSchema( $filename, $returnSchema = FALSE ) {
return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
* Converts an XML schema string to uninstallation SQL.
*
* Call this method to parse a string containing an XML schema (see the DTD for the proper format)
* and generate the SQL necessary to uninstall the database described by the schema.
* @see RemoveSchema()
*
* @param string $schema XML schema string.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*/
function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
// grab current version
if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
return FALSE;
}
return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
}
/**
* Applies the current XML schema to the database (post execution).
*
* Call this method to apply the current schema (generally created by calling
* ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes,
* and executing other SQL specified in the schema) after parsing.
* @see ParseSchema(), ParseSchemaString(), ExecuteInline()
*
* @param array $sqlArray Array of SQL statements that will be applied rather than
* the current schema.
* @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
* @returns integer 0 if failure, 1 if errors, 2 if successful.
*/
function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
if( !is_bool( $continueOnErr ) ) {
$continueOnErr = $this->ContinueOnError();
}
if( !isset( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
}
if( !is_array( $sqlArray ) ) {
$this->success = 0;
} else {
$this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
}
return $this->success;
}
/**
* Returns the current SQL array.
*
* Call this method to fetch the array of SQL queries resulting from
* ParseSchema() or ParseSchemaString().
*
* @param string $format Format: HTML, TEXT, or NONE (PHP array)
* @return array Array of SQL statements or FALSE if an error occurs
*/
function PrintSQL( $format = 'NONE' ) {
$sqlArray = null;
return $this->getSQL( $format, $sqlArray );
}
/**
* Saves the current SQL array to the local filesystem as a list of SQL queries.
*
* Call this method to save the array of SQL queries (generally resulting from a
* parsed XML schema) to the filesystem.
*
* @param string $filename Path and name where the file should be saved.
* @return boolean TRUE if save is successful, else FALSE.
*/
function SaveSQL( $filename = './schema.sql' ) {
if( !isset( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
}
if( !isset( $sqlArray ) ) {
return FALSE;
}
$fp = fopen( $filename, "w" );
foreach( $sqlArray as $key => $query ) {
fwrite( $fp, $query . ";\n" );
}
fclose( $fp );
}
/**
* Create an xml parser
*
* @return object PHP XML parser object
*
* @access private
*/
function create_parser() {
// Create the parser
$xmlParser = xml_parser_create();
xml_set_object( $xmlParser, $this );
// Initialize the XML callback functions
xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );
xml_set_character_data_handler( $xmlParser, '_tag_cdata' );
return $xmlParser;
}
/**
* XML Callback to process start elements
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
switch( strtoupper( $tag ) ) {
case 'TABLE':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$this->obj = new dbTable( $this, $attributes );
xml_set_object( $parser, $this->obj );
}
break;
case 'SQL':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$this->obj = new dbQuerySet( $this, $attributes );
xml_set_object( $parser, $this->obj );
}
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
}
/**
* XML Callback to process end elements
*
* @access private
* @internal
*/
function _tag_close( &$parser, $tag ) {
}
/**
* Converts an XML schema string to the specified DTD version.
*
* Call this method to convert a string containing an XML schema to a different AXMLS
* DTD version. For instance, to convert a schema created for an pre-1.0 version for
* AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
* parameter is specified, the schema will be converted to the current DTD version.
* If the newFile parameter is provided, the converted schema will be written to the specified
* file.
* @see ConvertSchemaFile()
*
* @param string $schema String containing XML schema that will be converted.
* @param string $newVersion DTD version to convert to.
* @param string $newFile File name of (converted) output file.
* @return string Converted XML schema or FALSE if an error occurs.
*/
function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
// grab current version
if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
return FALSE;
}
if( !isset ($newVersion) ) {
$newVersion = $this->schemaVersion;
}
if( $version == $newVersion ) {
$result = $schema;
} else {
$result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
}
if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
fwrite( $fp, $result );
fclose( $fp );
}
return $result;
}
/*
// compat for pre-4.3 - jlim
function _file_get_contents($path)
{
if (function_exists('file_get_contents')) return file_get_contents($path);
return join('',file($path));
}*/
/**
* Converts an XML schema file to the specified DTD version.
*
* Call this method to convert the specified XML schema file to a different AXMLS
* DTD version. For instance, to convert a schema created for an pre-1.0 version for
* AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
* parameter is specified, the schema will be converted to the current DTD version.
* If the newFile parameter is provided, the converted schema will be written to the specified
* file.
* @see ConvertSchemaString()
*
* @param string $filename Name of XML schema file that will be converted.
* @param string $newVersion DTD version to convert to.
* @param string $newFile File name of (converted) output file.
* @return string Converted XML schema or FALSE if an error occurs.
*/
function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
// grab current version
if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
return FALSE;
}
if( !isset ($newVersion) ) {
$newVersion = $this->schemaVersion;
}
if( $version == $newVersion ) {
$result = _file_get_contents( $filename );
// remove unicode BOM if present
if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
$result = substr( $result, 3 );
}
} else {
$result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
}
if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
fwrite( $fp, $result );
fclose( $fp );
}
return $result;
}
function TransformSchema( $schema, $xsl, $schematype='string' )
{
// Fail if XSLT extension is not available
if( ! function_exists( 'xslt_create' ) ) {
return FALSE;
}
$xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';
// look for xsl
if( !is_readable( $xsl_file ) ) {
return FALSE;
}
switch( $schematype )
{
case 'file':
if( !is_readable( $schema ) ) {
return FALSE;
}
$schema = _file_get_contents( $schema );
break;
case 'string':
default:
if( !is_string( $schema ) ) {
return FALSE;
}
}
$arguments = array (
'/_xml' => $schema,
'/_xsl' => _file_get_contents( $xsl_file )
);
// create an XSLT processor
$xh = xslt_create ();
// set error handler
xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
// process the schema
$result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
xslt_free ($xh);
return $result;
}
/**
* Processes XSLT transformation errors
*
* @param object $parser XML parser object
* @param integer $errno Error number
* @param integer $level Error level
* @param array $fields Error information fields
*
* @access private
*/
function xslt_error_handler( $parser, $errno, $level, $fields ) {
if( is_array( $fields ) ) {
$msg = array(
'Message Type' => ucfirst( $fields['msgtype'] ),
'Message Code' => $fields['code'],
'Message' => $fields['msg'],
'Error Number' => $errno,
'Level' => $level
);
switch( $fields['URI'] ) {
case 'arg:/_xml':
$msg['Input'] = 'XML';
break;
case 'arg:/_xsl':
$msg['Input'] = 'XSL';
break;
default:
$msg['Input'] = $fields['URI'];
}
$msg['Line'] = $fields['line'];
} else {
$msg = array(
'Message Type' => 'Error',
'Error Number' => $errno,
'Level' => $level,
'Fields' => var_export( $fields, TRUE )
);
}
$error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"
. '<table>' . "\n";
foreach( $msg as $label => $details ) {
$error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";
}
$error_details .= '</table>';
trigger_error( $error_details, E_USER_ERROR );
}
/**
* Returns the AXMLS Schema Version of the requested XML schema file.
*
* Call this method to obtain the AXMLS DTD version of the requested XML schema file.
* @see SchemaStringVersion()
*
* @param string $filename AXMLS schema file
* @return string Schema version number or FALSE on error
*/
function SchemaFileVersion( $filename ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
// die( 'Unable to open file' );
return FALSE;
}
// Process the file
while( $data = fread( $fp, 4096 ) ) {
if( preg_match( $this->versionRegex, $data, $matches ) ) {
return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
}
}
return FALSE;
}
/**
* Returns the AXMLS Schema Version of the provided XML schema string.
*
* Call this method to obtain the AXMLS DTD version of the provided XML schema string.
* @see SchemaFileVersion()
*
* @param string $xmlstring XML schema string
* @return string Schema version number or FALSE on error
*/
function SchemaStringVersion( $xmlstring ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
}
if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {
return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
}
return FALSE;
}
/**
* Extracts an XML schema from an existing database.
*
* Call this method to create an XML schema string from an existing database.
* If the data parameter is set to TRUE, AXMLS will include the data from the database
* in the schema.
*
* @param boolean $data Include data in schema dump
* @indent string indentation to use
* @prefix string extract only tables with given prefix
* @stripprefix strip prefix string when storing in XML schema
* @return string Generated XML schema
*/
function ExtractSchema( $data = FALSE, $indent = ' ', $prefix = '' , $stripprefix=false) {
$old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
$schema = '<?xml version="1.0"?>' . "\n"
. '<schema version="' . $this->schemaVersion . '">' . "\n";
if( is_array( $tables = $this->db->MetaTables( 'TABLES' ,false ,($prefix) ? str_replace('_','\_',$prefix).'%' : '') ) ) {
foreach( $tables as $table ) {
$schema .= $indent
. '<table name="'
. htmlentities( $stripprefix ? str_replace($prefix, '', $table) : $table )
. '">' . "\n";
// grab details from database
$rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE -1' );
$fields = $this->db->MetaColumns( $table );
$indexes = $this->db->MetaIndexes( $table );
if( is_array( $fields ) ) {
foreach( $fields as $details ) {
$extra = '';
$content = array();
if( isset($details->max_length) && $details->max_length > 0 ) {
$extra .= ' size="' . $details->max_length . '"';
}
if( isset($details->primary_key) && $details->primary_key ) {
$content[] = '<KEY/>';
} elseif( isset($details->not_null) && $details->not_null ) {
$content[] = '<NOTNULL/>';
}
if( isset($details->has_default) && $details->has_default ) {
$content[] = '<DEFAULT value="' . htmlentities( $details->default_value ) . '"/>';
}
if( isset($details->auto_increment) && $details->auto_increment ) {
$content[] = '<AUTOINCREMENT/>';
}
if( isset($details->unsigned) && $details->unsigned ) {
$content[] = '<UNSIGNED/>';
}
// this stops the creation of 'R' columns,
// AUTOINCREMENT is used to create auto columns
$details->primary_key = 0;
$type = $rs->MetaType( $details );
$schema .= str_repeat( $indent, 2 ) . '<field name="' . htmlentities( $details->name ) . '" type="' . $type . '"' . $extra;
if( !empty( $content ) ) {
$schema .= ">\n" . str_repeat( $indent, 3 )
. implode( "\n" . str_repeat( $indent, 3 ), $content ) . "\n"
. str_repeat( $indent, 2 ) . '</field>' . "\n";
} else {
$schema .= "/>\n";
}
}
}
if( is_array( $indexes ) ) {
foreach( $indexes as $index => $details ) {
$schema .= str_repeat( $indent, 2 ) . '<index name="' . $index . '">' . "\n";
if( $details['unique'] ) {
$schema .= str_repeat( $indent, 3 ) . '<UNIQUE/>' . "\n";
}
foreach( $details['columns'] as $column ) {
$schema .= str_repeat( $indent, 3 ) . '<col>' . htmlentities( $column ) . '</col>' . "\n";
}
$schema .= str_repeat( $indent, 2 ) . '</index>' . "\n";
}
}
if( $data ) {
$rs = $this->db->Execute( 'SELECT * FROM ' . $table );
if( is_object( $rs ) && !$rs->EOF ) {
$schema .= str_repeat( $indent, 2 ) . "<data>\n";
while( $row = $rs->FetchRow() ) {
foreach( $row as $key => $val ) {
if ( $val != htmlentities( $val ) ) {
$row[$key] = '<![CDATA[' . $val . ']]>';
}
}
$schema .= str_repeat( $indent, 3 ) . '<row><f>' . implode( '</f><f>', $row ) . "</f></row>\n";
}
$schema .= str_repeat( $indent, 2 ) . "</data>\n";
}
}
$schema .= $indent . "</table>\n";
}
}
$this->db->SetFetchMode( $old_mode );
$schema .= '</schema>';
return $schema;
}
/**
* Sets a prefix for database objects
*
* Call this method to set a standard prefix that will be prepended to all database tables
* and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
*
* @param string $prefix Prefix that will be prepended.
* @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
* @return boolean TRUE if successful, else FALSE
*/
function SetPrefix( $prefix = '', $underscore = TRUE ) {
switch( TRUE ) {
// clear prefix
case empty( $prefix ):
logMsg( 'Cleared prefix' );
$this->objectPrefix = '';
return TRUE;
// prefix too long
case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
// prefix contains invalid characters
case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
logMsg( 'Invalid prefix: ' . $prefix );
return FALSE;
}
if( $underscore AND substr( $prefix, -1 ) != '_' ) {
$prefix .= '_';
}
// prefix valid
logMsg( 'Set prefix: ' . $prefix );
$this->objectPrefix = $prefix;
return TRUE;
}
/**
* Returns an object name with the current prefix prepended.
*
* @param string $name Name
* @return string Prefixed name
*
* @access private
*/
function prefix( $name = '' ) {
// if prefix is set
if( !empty( $this->objectPrefix ) ) {
// Prepend the object prefix to the table name
// prepend after quote if used
return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );
}
// No prefix set. Use name provided.
return $name;
}
/**
* Checks if element references a specific platform
*
* @param string $platform Requested platform
* @returns boolean TRUE if platform check succeeds
*
* @access private
*/
function supportedPlatform( $platform = NULL ) {
if( !empty( $platform ) ) {
$regex = '/(^|\|)' . $this->db->databaseType . '(\||$)/i';
if( preg_match( '/^- /', $platform ) ) {
if (preg_match ( $regex, substr( $platform, 2 ) ) ) {
logMsg( 'Platform ' . $platform . ' is NOT supported' );
return FALSE;
}
} else {
if( !preg_match ( $regex, $platform ) ) {
logMsg( 'Platform ' . $platform . ' is NOT supported' );
return FALSE;
}
}
}
logMsg( 'Platform ' . $platform . ' is supported' );
return TRUE;
}
/**
* Clears the array of generated SQL.
*
* @access private
*/
function clearSQL() {
$this->sqlArray = array();
}
/**
* Adds SQL into the SQL array.
*
* @param mixed $sql SQL to Add
* @return boolean TRUE if successful, else FALSE.
*
* @access private
*/
function addSQL( $sql = NULL ) {
if( is_array( $sql ) ) {
foreach( $sql as $line ) {
$this->addSQL( $line );
}
return TRUE;
}
if( is_string( $sql ) ) {
$this->sqlArray[] = $sql;
// if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.
if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {
$saved = $this->db->debug;
$this->db->debug = $this->debug;
$ok = $this->db->Execute( $sql );
$this->db->debug = $saved;
if( !$ok ) {
if( $this->debug ) {
ADOConnection::outp( $this->db->ErrorMsg() );
}
$this->success = 1;
}
}
return TRUE;
}
return FALSE;
}
/**
* Gets the SQL array in the specified format.
*
* @param string $format Format
* @return mixed SQL
*
* @access private
*/
function getSQL( $format = NULL, $sqlArray = NULL ) {
if( !is_array( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
}
if( !is_array( $sqlArray ) ) {
return FALSE;
}
switch( strtolower( $format ) ) {
case 'string':
case 'text':
return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';
case'html':
return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';
}
return $this->sqlArray;
}
/**
* Destroys an adoSchema object.
*
* Call this method to clean up after an adoSchema object that is no longer in use.
* @deprecated adoSchema now cleans up automatically.
*/
function Destroy() {
ini_set("magic_quotes_runtime", $this->mgq );
#set_magic_quotes_runtime( $this->mgq );
}
}
/**
* Message logging function
*
* @access private
*/
function logMsg( $msg, $title = NULL, $force = FALSE ) {
if( XMLS_DEBUG or $force ) {
echo '<pre>';
if( isset( $title ) ) {
echo '<h3>' . htmlentities( $title ) . '</h3>';
}
if( @is_object( $this ) ) {
echo '[' . get_class( $this ) . '] ';
}
print_r( $msg );
echo '</pre>';
}
}
File diff suppressed because it is too large Load Diff
-37
View File
@@ -1,37 +0,0 @@
{
"name" : "adodb/adodb-php",
"description" : "ADOdb is a PHP database abstraction layer library",
"license" : [ "BSD-3-Clause", "LGPL-2.1" ],
"authors" : [
{
"name": "John Lim",
"email" : "jlim@natsoft.com",
"role": "Author"
},
{
"name": "Damien Regad",
"role": "Current maintainer"
},
{
"name": "Mark Newnham",
"role": "Developer"
}
],
"keywords" : [ "database", "abstraction", "layer", "library", "php" ],
"homepage": "http://adodb.org/",
"support" : {
"issues" : "https://github.com/ADOdb/ADOdb/issues",
"source" : "https://github.com/ADOdb/ADOdb"
},
"require" : {
"php" : ">=5.3.2"
},
"autoload" : {
"files" : ["adodb.inc.php"]
}
}
-181
View File
@@ -1,181 +0,0 @@
<?php
/**
* Helper functions to convert between ADODB recordset objects and XMLRPC values.
* Uses John Lim's AdoDB and Edd Dumbill's phpxmlrpc libs
*
* @author Daniele Baroncelli
* @author Gaetano Giunta
* @copyright (c) 2003-2004 Giunta/Baroncelli. All rights reserved.
*
* @todo some more error checking here and there
* @todo document the xmlrpc-struct used to encode recordset info
* @todo verify if using xmlrpc_encode($rs->GetArray()) would work with:
* - ADODB_FETCH_BOTH
* - null values
*/
/**
* Include the main libraries
*/
require_once('xmlrpc.inc');
if (!defined('ADODB_DIR')) require_once('adodb.inc.php');
/**
* Builds an xmlrpc struct value out of an AdoDB recordset
*/
function rs2xmlrpcval(&$adodbrs) {
$header = rs2xmlrpcval_header($adodbrs);
$body = rs2xmlrpcval_body($adodbrs);
// put it all together and build final xmlrpc struct
$xmlrpcrs = new xmlrpcval ( array(
"header" => $header,
"body" => $body,
), "struct");
return $xmlrpcrs;
}
/**
* Builds an xmlrpc struct value describing an AdoDB recordset
*/
function rs2xmlrpcval_header($adodbrs)
{
$numfields = $adodbrs->FieldCount();
$numrecords = $adodbrs->RecordCount();
// build structure holding recordset information
$fieldstruct = array();
for ($i = 0; $i < $numfields; $i++) {
$fld = $adodbrs->FetchField($i);
$fieldarray = array();
if (isset($fld->name))
$fieldarray["name"] = new xmlrpcval ($fld->name);
if (isset($fld->type))
$fieldarray["type"] = new xmlrpcval ($fld->type);
if (isset($fld->max_length))
$fieldarray["max_length"] = new xmlrpcval ($fld->max_length, "int");
if (isset($fld->not_null))
$fieldarray["not_null"] = new xmlrpcval ($fld->not_null, "boolean");
if (isset($fld->has_default))
$fieldarray["has_default"] = new xmlrpcval ($fld->has_default, "boolean");
if (isset($fld->default_value))
$fieldarray["default_value"] = new xmlrpcval ($fld->default_value);
$fieldstruct[$i] = new xmlrpcval ($fieldarray, "struct");
}
$fieldcount = new xmlrpcval ($numfields, "int");
$recordcount = new xmlrpcval ($numrecords, "int");
$sql = new xmlrpcval ($adodbrs->sql);
$fieldinfo = new xmlrpcval ($fieldstruct, "array");
$header = new xmlrpcval ( array(
"fieldcount" => $fieldcount,
"recordcount" => $recordcount,
"sql" => $sql,
"fieldinfo" => $fieldinfo
), "struct");
return $header;
}
/**
* Builds an xmlrpc struct value out of an AdoDB recordset
* (data values only, no data definition)
*/
function rs2xmlrpcval_body($adodbrs)
{
$numfields = $adodbrs->FieldCount();
// build structure containing recordset data
$adodbrs->MoveFirst();
$rows = array();
while (!$adodbrs->EOF) {
$columns = array();
// This should work on all cases of fetch mode: assoc, num, both or default
if ($adodbrs->fetchMode == 'ADODB_FETCH_BOTH' || count($adodbrs->fields) == 2 * $adodbrs->FieldCount())
for ($i = 0; $i < $numfields; $i++)
if ($adodbrs->fields[$i] === null)
$columns[$i] = new xmlrpcval ('');
else
$columns[$i] = xmlrpc_encode ($adodbrs->fields[$i]);
else
foreach ($adodbrs->fields as $val)
if ($val === null)
$columns[] = new xmlrpcval ('');
else
$columns[] = xmlrpc_encode ($val);
$rows[] = new xmlrpcval ($columns, "array");
$adodbrs->MoveNext();
}
$body = new xmlrpcval ($rows, "array");
return $body;
}
/**
* Returns an xmlrpc struct value as string out of an AdoDB recordset
*/
function rs2xmlrpcstring (&$adodbrs) {
$xmlrpc = rs2xmlrpcval ($adodbrs);
if ($xmlrpc)
return $xmlrpc->serialize();
else
return null;
}
/**
* Given a well-formed xmlrpc struct object returns an AdoDB object
*
* @todo add some error checking on the input value
*/
function xmlrpcval2rs (&$xmlrpcval) {
$fields_array = array();
$data_array = array();
// rebuild column information
$header = $xmlrpcval->structmem('header');
$numfields = $header->structmem('fieldcount');
$numfields = $numfields->scalarval();
$numrecords = $header->structmem('recordcount');
$numrecords = $numrecords->scalarval();
$sqlstring = $header->structmem('sql');
$sqlstring = $sqlstring->scalarval();
$fieldinfo = $header->structmem('fieldinfo');
for ($i = 0; $i < $numfields; $i++) {
$temp = $fieldinfo->arraymem($i);
$fld = new ADOFieldObject();
while (list($key,$value) = $temp->structeach()) {
if ($key == "name") $fld->name = $value->scalarval();
if ($key == "type") $fld->type = $value->scalarval();
if ($key == "max_length") $fld->max_length = $value->scalarval();
if ($key == "not_null") $fld->not_null = $value->scalarval();
if ($key == "has_default") $fld->has_default = $value->scalarval();
if ($key == "default_value") $fld->default_value = $value->scalarval();
} // while
$fields_array[] = $fld;
} // for
// fetch recordset information into php array
$body = $xmlrpcval->structmem('body');
for ($i = 0; $i < $numrecords; $i++) {
$data_array[$i]= array();
$xmlrpcrs_row = $body->arraymem($i);
for ($j = 0; $j < $numfields; $j++) {
$temp = $xmlrpcrs_row->arraymem($j);
$data_array[$i][$j] = $temp->scalarval();
} // for j
} // for i
// finally build in-memory recordset object and return it
$rs = new ADORecordSet_array();
$rs->InitArrayFields($data_array,$fields_array);
return $rs;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

@@ -1,95 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_access extends ADODB_DataDict {
var $databaseType = 'access';
var $seqField = false;
function ActualType($meta)
{
switch($meta) {
case 'C': return 'TEXT';
case 'XL':
case 'X': return 'MEMO';
case 'C2': return 'TEXT'; // up to 32K
case 'X2': return 'MEMO';
case 'B': return 'BINARY';
case 'TS':
case 'D': return 'DATETIME';
case 'T': return 'DATETIME';
case 'L': return 'BYTE';
case 'I': return 'INTEGER';
case 'I1': return 'BYTE';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'INTEGER';
case 'F': return 'DOUBLE';
case 'N': return 'NUMERIC';
default:
return $meta;
}
}
// return string must begin with space
function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
if ($fautoinc) {
$ftype = 'COUNTER';
return '';
}
if (substr($ftype,0,7) == 'DECIMAL') $ftype = 'DECIMAL';
$suffix = '';
if (strlen($fdefault)) {
//$suffix .= " DEFAULT $fdefault";
if ($this->debug) ADOConnection::outp("Warning: Access does not supported DEFAULT values (field $fname)");
}
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
function CreateDatabase($dbname,$options=false)
{
return array();
}
function SetSchema($schema)
{
}
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
return array();
}
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
return array();
}
}
-143
View File
@@ -1,143 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_db2 extends ADODB_DataDict {
var $databaseType = 'db2';
var $seqField = false;
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL': return 'CLOB';
case 'X': return 'VARCHAR(3600)';
case 'C2': return 'VARCHAR'; // up to 32K
case 'X2': return 'VARCHAR(3600)'; // up to 32000, but default page size too small
case 'B': return 'BLOB';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'TIMESTAMP';
case 'L': return 'SMALLINT';
case 'I': return 'INTEGER';
case 'I1': return 'SMALLINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'BIGINT';
case 'F': return 'DOUBLE';
case 'N': return 'DECIMAL';
default:
return $meta;
}
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if ($fautoinc) return ' GENERATED ALWAYS AS IDENTITY'; # as identity start with
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
return array();
}
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
return array();
}
function ChangeTableSQL($tablename, $flds, $tableoptions = false)
{
/**
Allow basic table changes to DB2 databases
DB2 will fatally reject changes to non character columns
*/
$validTypes = array("CHAR","VARC");
$invalidTypes = array("BIGI","BLOB","CLOB","DATE", "DECI","DOUB", "INTE", "REAL","SMAL", "TIME");
// check table exists
$cols = $this->MetaColumns($tablename);
if ( empty($cols)) {
return $this->CreateTableSQL($tablename, $flds, $tableoptions);
}
// already exists, alter table instead
list($lines,$pkey) = $this->_GenFields($flds);
$alter = 'ALTER TABLE ' . $this->TableName($tablename);
$sql = array();
foreach ( $lines as $id => $v ) {
if ( isset($cols[$id]) && is_object($cols[$id]) ) {
/**
If the first field of $v is the fieldname, and
the second is the field type/size, we assume its an
attempt to modify the column size, so check that it is allowed
$v can have an indeterminate number of blanks between the
fields, so account for that too
*/
$vargs = explode(' ' , $v);
// assume that $vargs[0] is the field name.
$i=0;
// Find the next non-blank value;
for ($i=1;$i<sizeof($vargs);$i++)
if ($vargs[$i] != '')
break;
// if $vargs[$i] is one of the following, we are trying to change the
// size of the field, if not allowed, simply ignore the request.
if (in_array(substr($vargs[$i],0,4),$invalidTypes))
continue;
// insert the appropriate DB2 syntax
if (in_array(substr($vargs[$i],0,4),$validTypes)) {
array_splice($vargs,$i,0,array('SET','DATA','TYPE'));
}
// Now Look for the NOT NULL statement as this is not allowed in
// the ALTER table statement. If it is in there, remove it
if (in_array('NOT',$vargs) && in_array('NULL',$vargs)) {
for ($i=1;$i<sizeof($vargs);$i++)
if ($vargs[$i] == 'NOT')
break;
array_splice($vargs,$i,2,'');
}
$v = implode(' ',$vargs);
$sql[] = $alter . $this->alterCol . ' ' . $v;
} else {
$sql[] = $alter . $this->addCol . ' ' . $v;
}
}
return $sql;
}
}
@@ -1,151 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
class ADODB2_firebird extends ADODB_DataDict {
var $databaseType = 'firebird';
var $seqField = false;
var $seqPrefix = 'gen_';
var $blobSize = 40000;
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL': return 'VARCHAR(32000)';
case 'X': return 'VARCHAR(4000)';
case 'C2': return 'VARCHAR'; // up to 32K
case 'X2': return 'VARCHAR(4000)';
case 'B': return 'BLOB';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'TIMESTAMP';
case 'L': return 'SMALLINT';
case 'I': return 'INTEGER';
case 'I1': return 'SMALLINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'INTEGER';
case 'F': return 'DOUBLE PRECISION';
case 'N': return 'DECIMAL';
default:
return $meta;
}
}
function NameQuote($name = NULL)
{
if (!is_string($name)) {
return FALSE;
}
$name = trim($name);
if ( !is_object($this->connection) ) {
return $name;
}
$quote = $this->connection->nameQuote;
// if name is of the form `name`, quote it
if ( preg_match('/^`(.+)`$/', $name, $matches) ) {
return $quote . $matches[1] . $quote;
}
// if name contains special characters, quote it
if ( !preg_match('/^[' . $this->nameRegex . ']+$/', $name) ) {
return $quote . $name . $quote;
}
return $quote . $name . $quote;
}
function CreateDatabase($dbname, $options=false)
{
$options = $this->_Options($options);
$sql = array();
$sql[] = "DECLARE EXTERNAL FUNCTION LOWER CSTRING(80) RETURNS CSTRING(80) FREE_IT ENTRY_POINT 'IB_UDF_lower' MODULE_NAME 'ib_udf'";
return $sql;
}
function _DropAutoIncrement($t)
{
if (strpos($t,'.') !== false) {
$tarr = explode('.',$t);
return 'DROP GENERATOR '.$tarr[0].'."gen_'.$tarr[1].'"';
}
return 'DROP GENERATOR "GEN_'.$t;
}
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fautoinc) $this->seqField = $fname;
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
/*
CREATE or replace TRIGGER jaddress_insert
before insert on jaddress
for each row
begin
IF ( NEW."seqField" IS NULL OR NEW."seqField" = 0 ) THEN
NEW."seqField" = GEN_ID("GEN_tabname", 1);
end;
*/
function _Triggers($tabname,$tableoptions)
{
if (!$this->seqField) return array();
$tab1 = preg_replace( '/"/', '', $tabname );
if ($this->schema) {
$t = strpos($tab1,'.');
if ($t !== false) $tab = substr($tab1,$t+1);
else $tab = $tab1;
$seqField = $this->seqField;
$seqname = $this->schema.'.'.$this->seqPrefix.$tab;
$trigname = $this->schema.'.trig_'.$this->seqPrefix.$tab;
} else {
$seqField = $this->seqField;
$seqname = $this->seqPrefix.$tab1;
$trigname = 'trig_'.$seqname;
}
if (isset($tableoptions['REPLACE']))
{ $sql[] = "DROP GENERATOR \"$seqname\"";
$sql[] = "CREATE GENERATOR \"$seqname\"";
$sql[] = "ALTER TRIGGER \"$trigname\" BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END";
}
else
{ $sql[] = "CREATE GENERATOR \"$seqname\"";
$sql[] = "CREATE TRIGGER \"$trigname\" FOR $tabname BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END";
}
$this->seqField = false;
return $sql;
}
}
@@ -1,127 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_generic extends ADODB_DataDict {
var $databaseType = 'generic';
var $seqField = false;
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL':
case 'X': return 'VARCHAR(250)';
case 'C2': return 'VARCHAR';
case 'X2': return 'VARCHAR(250)';
case 'B': return 'VARCHAR';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'DATE';
case 'L': return 'DECIMAL(1)';
case 'I': return 'DECIMAL(10)';
case 'I1': return 'DECIMAL(3)';
case 'I2': return 'DECIMAL(5)';
case 'I4': return 'DECIMAL(10)';
case 'I8': return 'DECIMAL(20)';
case 'F': return 'DECIMAL(32,8)';
case 'N': return 'DECIMAL';
default:
return $meta;
}
}
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
return array();
}
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
return array();
}
}
/*
//db2
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'X': return 'VARCHAR';
case 'C2': return 'VARCHAR'; // up to 32K
case 'X2': return 'VARCHAR';
case 'B': return 'BLOB';
case 'D': return 'DATE';
case 'T': return 'TIMESTAMP';
case 'L': return 'SMALLINT';
case 'I': return 'INTEGER';
case 'I1': return 'SMALLINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'BIGINT';
case 'F': return 'DOUBLE';
case 'N': return 'DECIMAL';
default:
return $meta;
}
}
// ifx
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';// 255
case 'X': return 'TEXT';
case 'C2': return 'NVARCHAR';
case 'X2': return 'TEXT';
case 'B': return 'BLOB';
case 'D': return 'DATE';
case 'T': return 'DATETIME';
case 'L': return 'SMALLINT';
case 'I': return 'INTEGER';
case 'I1': return 'SMALLINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'DECIMAL(20)';
case 'F': return 'FLOAT';
case 'N': return 'DECIMAL';
default:
return $meta;
}
}
*/
@@ -1,67 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_ibase extends ADODB_DataDict {
var $databaseType = 'ibase';
var $seqField = false;
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL':
case 'X': return 'VARCHAR(4000)';
case 'C2': return 'VARCHAR'; // up to 32K
case 'X2': return 'VARCHAR(4000)';
case 'B': return 'BLOB';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'TIMESTAMP';
case 'L': return 'SMALLINT';
case 'I': return 'INTEGER';
case 'I1': return 'SMALLINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'INTEGER';
case 'F': return 'DOUBLE PRECISION';
case 'N': return 'DECIMAL';
default:
return $meta;
}
}
function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
return array();
}
function DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
return array();
}
}
@@ -1,81 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_informix extends ADODB_DataDict {
var $databaseType = 'informix';
var $seqField = false;
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';// 255
case 'XL':
case 'X': return 'TEXT';
case 'C2': return 'NVARCHAR';
case 'X2': return 'TEXT';
case 'B': return 'BLOB';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'DATETIME YEAR TO SECOND';
case 'L': return 'SMALLINT';
case 'I': return 'INTEGER';
case 'I1': return 'SMALLINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'DECIMAL(20)';
case 'F': return 'FLOAT';
case 'N': return 'DECIMAL';
default:
return $meta;
}
}
function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
return array();
}
function DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
return array();
}
// return string must begin with space
function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
if ($fautoinc) {
$ftype = 'SERIAL';
return '';
}
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
}
@@ -1,285 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
/*
In ADOdb, named quotes for MS SQL Server use ". From the MSSQL Docs:
Note Delimiters are for identifiers only. Delimiters cannot be used for keywords,
whether or not they are marked as reserved in SQL Server.
Quoted identifiers are delimited by double quotation marks ("):
SELECT * FROM "Blanks in Table Name"
Bracketed identifiers are delimited by brackets ([ ]):
SELECT * FROM [Blanks In Table Name]
Quoted identifiers are valid only when the QUOTED_IDENTIFIER option is set to ON. By default,
the Microsoft OLE DB Provider for SQL Server and SQL Server ODBC driver set QUOTED_IDENTIFIER ON
when they connect.
In Transact-SQL, the option can be set at various levels using SET QUOTED_IDENTIFIER,
the quoted identifier option of sp_dboption, or the user options option of sp_configure.
When SET ANSI_DEFAULTS is ON, SET QUOTED_IDENTIFIER is enabled.
Syntax
SET QUOTED_IDENTIFIER { ON | OFF }
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_mssql extends ADODB_DataDict {
var $databaseType = 'mssql';
var $dropIndex = 'DROP INDEX %2$s.%1$s';
var $renameTable = "EXEC sp_rename '%s','%s'";
var $renameColumn = "EXEC sp_rename '%s.%s','%s'";
var $typeX = 'TEXT'; ## Alternatively, set it to VARCHAR(4000)
var $typeXL = 'TEXT';
//var $alterCol = ' ALTER COLUMN ';
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'R':
case 'INT':
case 'INTEGER': return 'I';
case 'BIT':
case 'TINYINT': return 'I1';
case 'SMALLINT': return 'I2';
case 'BIGINT': return 'I8';
case 'SMALLDATETIME': return 'T';
case 'REAL':
case 'FLOAT': return 'F';
default: return parent::MetaType($t,$len,$fieldobj);
}
}
function ActualType($meta)
{
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR';
case 'XL': return (isset($this)) ? $this->typeXL : 'TEXT';
case 'X': return (isset($this)) ? $this->typeX : 'TEXT'; ## could be varchar(8000), but we want compat with oracle
case 'C2': return 'NVARCHAR';
case 'X2': return 'NTEXT';
case 'B': return 'IMAGE';
case 'D': return 'DATETIME';
case 'TS':
case 'T': return 'DATETIME';
case 'L': return 'BIT';
case 'R':
case 'I': return 'INT';
case 'I1': return 'TINYINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INT';
case 'I8': return 'BIGINT';
case 'F': return 'REAL';
case 'N': return 'NUMERIC';
default:
return $meta;
}
}
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$f = array();
list($lines,$pkey) = $this->_GenFields($flds);
$s = "ALTER TABLE $tabname $this->addCol";
foreach($lines as $v) {
$f[] = "\n $v";
}
$s .= implode(', ',$f);
$sql[] = $s;
return $sql;
}
/*
function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
foreach($lines as $v) {
$sql[] = "ALTER TABLE $tabname $this->alterCol $v";
}
return $sql;
}
*/
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
if (!is_array($flds))
$flds = explode(',',$flds);
$f = array();
$s = 'ALTER TABLE ' . $tabname;
foreach($flds as $v) {
$f[] = "\n$this->dropCol ".$this->NameQuote($v);
}
$s .= implode(', ',$f);
$sql[] = $s;
return $sql;
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fautoinc) $suffix .= ' IDENTITY(1,1)';
if ($fnotnull) $suffix .= ' NOT NULL';
else if ($suffix == '') $suffix .= ' NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
/*
CREATE TABLE
[ database_name.[ owner ] . | owner. ] table_name
( { < column_definition >
| column_name AS computed_column_expression
| < table_constraint > ::= [ CONSTRAINT constraint_name ] }
| [ { PRIMARY KEY | UNIQUE } [ ,...n ]
)
[ ON { filegroup | DEFAULT } ]
[ TEXTIMAGE_ON { filegroup | DEFAULT } ]
< column_definition > ::= { column_name data_type }
[ COLLATE < collation_name > ]
[ [ DEFAULT constant_expression ]
| [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
]
[ ROWGUIDCOL]
[ < column_constraint > ] [ ...n ]
< column_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ NULL | NOT NULL ]
| [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
[ WITH FILLFACTOR = fillfactor ]
[ON {filegroup | DEFAULT} ] ]
]
| [ [ FOREIGN KEY ]
REFERENCES ref_table [ ( ref_column ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
]
| CHECK [ NOT FOR REPLICATION ]
( logical_expression )
}
< table_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
{ ( column [ ASC | DESC ] [ ,...n ] ) }
[ WITH FILLFACTOR = fillfactor ]
[ ON { filegroup | DEFAULT } ]
]
| FOREIGN KEY
[ ( column [ ,...n ] ) ]
REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ]
( search_conditions )
}
*/
/*
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
[ WITH < index_option > [ ,...n] ]
[ ON filegroup ]
< index_option > :: =
{ PAD_INDEX |
FILLFACTOR = fillfactor |
IGNORE_DUP_KEY |
DROP_EXISTING |
STATISTICS_NORECOMPUTE |
SORT_IN_TEMPDB
}
*/
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
if ( isset($idxoptions['DROP']) )
return $sql;
}
if ( empty ($flds) ) {
return $sql;
}
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
$clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
if ( is_array($flds) )
$flds = implode(', ',$flds);
$s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
if ( isset($idxoptions[$this->upperName]) )
$s .= $idxoptions[$this->upperName];
$sql[] = $s;
return $sql;
}
function _GetSize($ftype, $ty, $fsize, $fprec)
{
switch ($ftype) {
case 'INT':
case 'SMALLINT':
case 'TINYINT':
case 'BIGINT':
return $ftype;
}
if ($ty == 'T') return $ftype;
return parent::_GetSize($ftype, $ty, $fsize, $fprec);
}
}
@@ -1,369 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
/*
In ADOdb, named quotes for MS SQL Server use ". From the MSSQL Docs:
Note Delimiters are for identifiers only. Delimiters cannot be used for keywords,
whether or not they are marked as reserved in SQL Server.
Quoted identifiers are delimited by double quotation marks ("):
SELECT * FROM "Blanks in Table Name"
Bracketed identifiers are delimited by brackets ([ ]):
SELECT * FROM [Blanks In Table Name]
Quoted identifiers are valid only when the QUOTED_IDENTIFIER option is set to ON. By default,
the Microsoft OLE DB Provider for SQL Server and SQL Server ODBC driver set QUOTED_IDENTIFIER ON
when they connect.
In Transact-SQL, the option can be set at various levels using SET QUOTED_IDENTIFIER,
the quoted identifier option of sp_dboption, or the user options option of sp_configure.
When SET ANSI_DEFAULTS is ON, SET QUOTED_IDENTIFIER is enabled.
Syntax
SET QUOTED_IDENTIFIER { ON | OFF }
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_mssqlnative extends ADODB_DataDict {
var $databaseType = 'mssqlnative';
var $dropIndex = 'DROP INDEX %1$s ON %2$s';
var $renameTable = "EXEC sp_rename '%s','%s'";
var $renameColumn = "EXEC sp_rename '%s.%s','%s'";
var $typeX = 'TEXT'; ## Alternatively, set it to VARCHAR(4000)
var $typeXL = 'TEXT';
//var $alterCol = ' ALTER COLUMN ';
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$_typeConversion = array(
-155 => 'D',
93 => 'D',
-154 => 'D',
-2 => 'D',
91 => 'D',
12 => 'C',
1 => 'C',
-9 => 'C',
-8 => 'C',
-7 => 'L',
-6 => 'I2',
-5 => 'I8',
-11 => 'I',
4 => 'I',
5 => 'I4',
-1 => 'X',
-10 => 'X',
2 => 'N',
3 => 'N',
6 => 'N',
7 => 'N',
-152 => 'X',
-151 => 'X',
-4 => 'X',
-3 => 'X'
);
return $_typeConversion($t);
}
function ActualType($meta)
{
$DATE_TYPE = 'DATETIME';
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR';
case 'XL': return (isset($this)) ? $this->typeXL : 'TEXT';
case 'X': return (isset($this)) ? $this->typeX : 'TEXT'; ## could be varchar(8000), but we want compat with oracle
case 'C2': return 'NVARCHAR';
case 'X2': return 'NTEXT';
case 'B': return 'IMAGE';
case 'D': return $DATE_TYPE;
case 'T': return 'TIME';
case 'L': return 'BIT';
case 'R':
case 'I': return 'INT';
case 'I1': return 'TINYINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INT';
case 'I8': return 'BIGINT';
case 'F': return 'REAL';
case 'N': return 'NUMERIC';
default:
print "RETURN $meta";
return $meta;
}
}
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$f = array();
list($lines,$pkey) = $this->_GenFields($flds);
$s = "ALTER TABLE $tabname $this->addCol";
foreach($lines as $v) {
$f[] = "\n $v";
}
$s .= implode(', ',$f);
$sql[] = $s;
return $sql;
}
function DefaultConstraintname($tabname, $colname)
{
$constraintname = false;
$rs = $this->connection->Execute(
"SELECT name FROM sys.default_constraints
WHERE object_name(parent_object_id) = '$tabname'
AND col_name(parent_object_id, parent_column_id) = '$colname'"
);
if ( is_object($rs) ) {
$row = $rs->FetchRow();
$constraintname = $row['name'];
}
return $constraintname;
}
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
foreach($lines as $v) {
$not_null = false;
if ($not_null = preg_match('/NOT NULL/i',$v)) {
$v = preg_replace('/NOT NULL/i','',$v);
}
if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
list(,$colname,$default) = $matches;
$v = preg_replace('/^' . preg_quote($colname) . '\s/', '', $v);
$t = trim(str_replace('DEFAULT '.$default,'',$v));
if ( $constraintname = $this->DefaultConstraintname($tabname,$colname) ) {
$sql[] = 'ALTER TABLE '.$tabname.' DROP CONSTRAINT '. $constraintname;
}
if ($not_null) {
$sql[] = $alter . $colname . ' ' . $t . ' NOT NULL';
} else {
$sql[] = $alter . $colname . ' ' . $t ;
}
$sql[] = 'ALTER TABLE ' . $tabname
. ' ADD CONSTRAINT DF__' . $tabname . '__' . $colname . '__' . dechex(rand())
. ' DEFAULT ' . $default . ' FOR ' . $colname;
} else {
$colname = strtok($v," ");
if ( $constraintname = $this->DefaultConstraintname($tabname,$colname) ) {
$sql[] = 'ALTER TABLE '.$tabname.' DROP CONSTRAINT '. $constraintname;
}
if ($not_null) {
$sql[] = $alter . $v . ' NOT NULL';
} else {
$sql[] = $alter . $v;
}
}
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
/**
* Drop a column, syntax is ALTER TABLE table DROP COLUMN column,column
*
* @param string $tabname Table Name
* @param string[] $flds One, or an array of Fields To Drop
* @param string $tableflds Throwaway value to make the function match the parent
* @param string $tableoptions Throway value to make the function match the parent
*
* @return string The SQL necessary to drop the column
*/
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
if (!is_array($flds))
$flds = explode(',',$flds);
$f = array();
$s = 'ALTER TABLE ' . $tabname;
foreach($flds as $v) {
if ( $constraintname = $this->DefaultConstraintname($tabname,$v) ) {
$sql[] = 'ALTER TABLE ' . $tabname . ' DROP CONSTRAINT ' . $constraintname;
}
$f[] = ' DROP COLUMN ' . $this->NameQuote($v);
}
$s .= implode(', ',$f);
$sql[] = $s;
return $sql;
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fautoinc) $suffix .= ' IDENTITY(1,1)';
if ($fnotnull) $suffix .= ' NOT NULL';
else if ($suffix == '') $suffix .= ' NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
/*
CREATE TABLE
[ database_name.[ owner ] . | owner. ] table_name
( { < column_definition >
| column_name AS computed_column_expression
| < table_constraint > ::= [ CONSTRAINT constraint_name ] }
| [ { PRIMARY KEY | UNIQUE } [ ,...n ]
)
[ ON { filegroup | DEFAULT } ]
[ TEXTIMAGE_ON { filegroup | DEFAULT } ]
< column_definition > ::= { column_name data_type }
[ COLLATE < collation_name > ]
[ [ DEFAULT constant_expression ]
| [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
]
[ ROWGUIDCOL]
[ < column_constraint > ] [ ...n ]
< column_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ NULL | NOT NULL ]
| [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
[ WITH FILLFACTOR = fillfactor ]
[ON {filegroup | DEFAULT} ] ]
]
| [ [ FOREIGN KEY ]
REFERENCES ref_table [ ( ref_column ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
]
| CHECK [ NOT FOR REPLICATION ]
( logical_expression )
}
< table_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
{ ( column [ ASC | DESC ] [ ,...n ] ) }
[ WITH FILLFACTOR = fillfactor ]
[ ON { filegroup | DEFAULT } ]
]
| FOREIGN KEY
[ ( column [ ,...n ] ) ]
REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ]
( search_conditions )
}
*/
/*
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
[ WITH < index_option > [ ,...n] ]
[ ON filegroup ]
< index_option > :: =
{ PAD_INDEX |
FILLFACTOR = fillfactor |
IGNORE_DUP_KEY |
DROP_EXISTING |
STATISTICS_NORECOMPUTE |
SORT_IN_TEMPDB
}
*/
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
if ( isset($idxoptions['DROP']) )
return $sql;
}
if ( empty ($flds) ) {
return $sql;
}
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
$clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
if ( is_array($flds) )
$flds = implode(', ',$flds);
$s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
if ( isset($idxoptions[$this->upperName]) )
$s .= $idxoptions[$this->upperName];
$sql[] = $s;
return $sql;
}
function _GetSize($ftype, $ty, $fsize, $fprec)
{
switch ($ftype) {
case 'INT':
case 'SMALLINT':
case 'TINYINT':
case 'BIGINT':
return $ftype;
}
if ($ty == 'T') return $ftype;
return parent::_GetSize($ftype, $ty, $fsize, $fprec);
}
}
@@ -1,183 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_mysql extends ADODB_DataDict {
var $databaseType = 'mysql';
var $alterCol = ' MODIFY COLUMN';
var $alterTableAddIndex = true;
var $dropTable = 'DROP TABLE IF EXISTS %s'; // requires mysql 3.22 or later
var $dropIndex = 'DROP INDEX %s ON %s';
var $renameColumn = 'ALTER TABLE %s CHANGE COLUMN %s %s %s'; // needs column-definition!
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$is_serial = is_object($fieldobj) && $fieldobj->primary_key && $fieldobj->auto_increment;
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
case 'TINYBLOB':
case 'TINYTEXT':
case 'ENUM':
case 'SET':
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
case 'LONGTEXT':
case 'MEDIUMTEXT':
return 'X';
// php_mysql extension always returns 'blob' even if 'text'
// so we have to check whether binary...
case 'IMAGE':
case 'LONGBLOB':
case 'BLOB':
case 'MEDIUMBLOB':
return !empty($fieldobj->binary) ? 'B' : 'X';
case 'YEAR':
case 'DATE': return 'D';
case 'TIME':
case 'DATETIME':
case 'TIMESTAMP': return 'T';
case 'FLOAT':
case 'DOUBLE':
return 'F';
case 'INT':
case 'INTEGER': return $is_serial ? 'R' : 'I';
case 'TINYINT': return $is_serial ? 'R' : 'I1';
case 'SMALLINT': return $is_serial ? 'R' : 'I2';
case 'MEDIUMINT': return $is_serial ? 'R' : 'I4';
case 'BIGINT': return $is_serial ? 'R' : 'I8';
default: return 'N';
}
}
function ActualType($meta)
{
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR';
case 'XL':return 'LONGTEXT';
case 'X': return 'TEXT';
case 'C2': return 'VARCHAR';
case 'X2': return 'LONGTEXT';
case 'B': return 'LONGBLOB';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'DATETIME';
case 'L': return 'TINYINT';
case 'R':
case 'I4':
case 'I': return 'INTEGER';
case 'I1': return 'TINYINT';
case 'I2': return 'SMALLINT';
case 'I8': return 'BIGINT';
case 'F': return 'DOUBLE';
case 'N': return 'NUMERIC';
default:
return $meta;
}
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if ($funsigned) $suffix .= ' UNSIGNED';
if ($fnotnull) $suffix .= ' NOT NULL';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fautoinc) $suffix .= ' AUTO_INCREMENT';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
/*
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
[table_options] [select_statement]
create_definition:
col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
[PRIMARY KEY] [reference_definition]
or PRIMARY KEY (index_col_name,...)
or KEY [index_name] (index_col_name,...)
or INDEX [index_name] (index_col_name,...)
or UNIQUE [INDEX] [index_name] (index_col_name,...)
or FULLTEXT [INDEX] [index_name] (index_col_name,...)
or [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_col_name,...)
[reference_definition]
or CHECK (expr)
*/
/*
CREATE [UNIQUE|FULLTEXT] INDEX index_name
ON tbl_name (col_name[(length)],... )
*/
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
if ($this->alterTableAddIndex) $sql[] = "ALTER TABLE $tabname DROP INDEX $idxname";
else $sql[] = sprintf($this->dropIndex, $idxname, $tabname);
if ( isset($idxoptions['DROP']) )
return $sql;
}
if ( empty ($flds) ) {
return $sql;
}
if (isset($idxoptions['FULLTEXT'])) {
$unique = ' FULLTEXT';
} elseif (isset($idxoptions['UNIQUE'])) {
$unique = ' UNIQUE';
} else {
$unique = '';
}
if ( is_array($flds) ) $flds = implode(', ',$flds);
if ($this->alterTableAddIndex) $s = "ALTER TABLE $tabname ADD $unique INDEX $idxname ";
else $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname;
$s .= ' (' . $flds . ')';
if ( isset($idxoptions[$this->upperName]) )
$s .= $idxoptions[$this->upperName];
$sql[] = $s;
return $sql;
}
}
-300
View File
@@ -1,300 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_oci8 extends ADODB_DataDict {
var $databaseType = 'oci8';
var $seqField = false;
var $seqPrefix = 'SEQ_';
var $dropTable = "DROP TABLE %s CASCADE CONSTRAINTS";
var $trigPrefix = 'TRIG_';
var $alterCol = ' MODIFY ';
var $typeX = 'VARCHAR(4000)';
var $typeXL = 'CLOB';
function MetaType($t, $len=-1, $fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
case 'VARCHAR':
case 'VARCHAR2':
case 'CHAR':
case 'VARBINARY':
case 'BINARY':
if (isset($this) && $len <= $this->blobSize) return 'C';
return 'X';
case 'NCHAR':
case 'NVARCHAR2':
case 'NVARCHAR':
if (isset($this) && $len <= $this->blobSize) return 'C2';
return 'X2';
case 'NCLOB':
case 'CLOB':
return 'XL';
case 'LONG RAW':
case 'LONG VARBINARY':
case 'BLOB':
return 'B';
case 'TIMESTAMP':
return 'TS';
case 'DATE':
return 'T';
case 'INT':
case 'SMALLINT':
case 'INTEGER':
return 'I';
default:
return 'N';
}
}
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'X': return $this->typeX;
case 'XL': return $this->typeXL;
case 'C2': return 'NVARCHAR2';
case 'X2': return 'NVARCHAR2(4000)';
case 'B': return 'BLOB';
case 'TS':
return 'TIMESTAMP';
case 'D':
case 'T': return 'DATE';
case 'L': return 'NUMBER(1)';
case 'I1': return 'NUMBER(3)';
case 'I2': return 'NUMBER(5)';
case 'I':
case 'I4': return 'NUMBER(10)';
case 'I8': return 'NUMBER(20)';
case 'F': return 'NUMBER';
case 'N': return 'NUMBER';
case 'R': return 'NUMBER(20)';
default:
return $meta;
}
}
function CreateDatabase($dbname, $options=false)
{
$options = $this->_Options($options);
$password = isset($options['PASSWORD']) ? $options['PASSWORD'] : 'tiger';
$tablespace = isset($options["TABLESPACE"]) ? " DEFAULT TABLESPACE ".$options["TABLESPACE"] : '';
$sql[] = "CREATE USER ".$dbname." IDENTIFIED BY ".$password.$tablespace;
$sql[] = "GRANT CREATE SESSION, CREATE TABLE,UNLIMITED TABLESPACE,CREATE SEQUENCE TO $dbname";
return $sql;
}
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName($tabname);
$f = array();
list($lines,$pkey) = $this->_GenFields($flds);
$s = "ALTER TABLE $tabname ADD (";
foreach($lines as $v) {
$f[] = "\n $v";
}
$s .= implode(', ',$f).')';
$sql[] = $s;
return $sql;
}
function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
$tabname = $this->TableName($tabname);
$f = array();
list($lines,$pkey) = $this->_GenFields($flds);
$s = "ALTER TABLE $tabname MODIFY(";
foreach($lines as $v) {
$f[] = "\n $v";
}
$s .= implode(', ',$f).')';
$sql[] = $s;
return $sql;
}
function DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
if (!is_array($flds)) $flds = explode(',',$flds);
foreach ($flds as $k => $v) $flds[$k] = $this->NameQuote($v);
$sql = array();
$s = "ALTER TABLE $tabname DROP(";
$s .= implode(', ',$flds).') CASCADE CONSTRAINTS';
$sql[] = $s;
return $sql;
}
function _DropAutoIncrement($t)
{
if (strpos($t,'.') !== false) {
$tarr = explode('.',$t);
return "drop sequence ".$tarr[0].".seq_".$tarr[1];
}
return "drop sequence seq_".$t;
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if ($fdefault == "''" && $fnotnull) {// this is null in oracle
$fnotnull = false;
if ($this->debug) ADOConnection::outp("NOT NULL and DEFAULT='' illegal in Oracle");
}
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fautoinc) $this->seqField = $fname;
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
/*
CREATE or replace TRIGGER jaddress_insert
before insert on jaddress
for each row
begin
select seqaddress.nextval into :new.A_ID from dual;
end;
*/
function _Triggers($tabname,$tableoptions)
{
if (!$this->seqField) return array();
if ($this->schema) {
$t = strpos($tabname,'.');
if ($t !== false) $tab = substr($tabname,$t+1);
else $tab = $tabname;
$seqname = $this->schema.'.'.$this->seqPrefix.$tab;
$trigname = $this->schema.'.'.$this->trigPrefix.$this->seqPrefix.$tab;
} else {
$seqname = $this->seqPrefix.$tabname;
$trigname = $this->trigPrefix.$seqname;
}
if (strlen($seqname) > 30) {
$seqname = $this->seqPrefix.uniqid('');
} // end if
if (strlen($trigname) > 30) {
$trigname = $this->trigPrefix.uniqid('');
} // end if
if (isset($tableoptions['REPLACE'])) $sql[] = "DROP SEQUENCE $seqname";
$seqCache = '';
if (isset($tableoptions['SEQUENCE_CACHE'])){$seqCache = $tableoptions['SEQUENCE_CACHE'];}
$seqIncr = '';
if (isset($tableoptions['SEQUENCE_INCREMENT'])){$seqIncr = ' INCREMENT BY '.$tableoptions['SEQUENCE_INCREMENT'];}
$seqStart = '';
if (isset($tableoptions['SEQUENCE_START'])){$seqIncr = ' START WITH '.$tableoptions['SEQUENCE_START'];}
$sql[] = "CREATE SEQUENCE $seqname $seqStart $seqIncr $seqCache";
$sql[] = "CREATE OR REPLACE TRIGGER $trigname BEFORE insert ON $tabname FOR EACH ROW WHEN (NEW.$this->seqField IS NULL OR NEW.$this->seqField = 0) BEGIN select $seqname.nextval into :new.$this->seqField from dual; END;";
$this->seqField = false;
return $sql;
}
/*
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
[table_options] [select_statement]
create_definition:
col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
[PRIMARY KEY] [reference_definition]
or PRIMARY KEY (index_col_name,...)
or KEY [index_name] (index_col_name,...)
or INDEX [index_name] (index_col_name,...)
or UNIQUE [INDEX] [index_name] (index_col_name,...)
or FULLTEXT [INDEX] [index_name] (index_col_name,...)
or [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_col_name,...)
[reference_definition]
or CHECK (expr)
*/
function _IndexSQL($idxname, $tabname, $flds,$idxoptions)
{
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
if ( isset($idxoptions['DROP']) )
return $sql;
}
if ( empty ($flds) ) {
return $sql;
}
if (isset($idxoptions['BITMAP'])) {
$unique = ' BITMAP';
} elseif (isset($idxoptions['UNIQUE'])) {
$unique = ' UNIQUE';
} else {
$unique = '';
}
if ( is_array($flds) )
$flds = implode(', ',$flds);
$s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
if ( isset($idxoptions[$this->upperName]) )
$s .= $idxoptions[$this->upperName];
if (isset($idxoptions['oci8']))
$s .= $idxoptions['oci8'];
$sql[] = $s;
return $sql;
}
function GetCommentSQL($table,$col)
{
$table = $this->connection->qstr($table);
$col = $this->connection->qstr($col);
return "select comments from USER_COL_COMMENTS where TABLE_NAME=$table and COLUMN_NAME=$col";
}
function SetCommentSQL($table,$col,$cmt)
{
$cmt = $this->connection->qstr($cmt);
return "COMMENT ON COLUMN $table.$col IS $cmt";
}
}
@@ -1,484 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_postgres extends ADODB_DataDict {
var $databaseType = 'postgres';
var $seqField = false;
var $seqPrefix = 'SEQ_';
var $addCol = ' ADD COLUMN';
var $quote = '"';
var $renameTable = 'ALTER TABLE %s RENAME TO %s'; // at least since 7.1
var $dropTable = 'DROP TABLE %s CASCADE';
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$is_serial = is_object($fieldobj) && !empty($fieldobj->primary_key) && !empty($fieldobj->unique) &&
!empty($fieldobj->has_default) && substr($fieldobj->default_value,0,8) == 'nextval(';
switch (strtoupper($t)) {
case 'INTERVAL':
case 'CHAR':
case 'CHARACTER':
case 'VARCHAR':
case 'NAME':
case 'BPCHAR':
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
return 'X';
case 'IMAGE': // user defined type
case 'BLOB': // user defined type
case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
case 'VARBIT':
case 'BYTEA':
return 'B';
case 'BOOL':
case 'BOOLEAN':
return 'L';
case 'DATE':
return 'D';
case 'TIME':
case 'DATETIME':
case 'TIMESTAMP':
case 'TIMESTAMPTZ':
return 'T';
case 'INTEGER': return !$is_serial ? 'I' : 'R';
case 'SMALLINT':
case 'INT2': return !$is_serial ? 'I2' : 'R';
case 'INT4': return !$is_serial ? 'I4' : 'R';
case 'BIGINT':
case 'INT8': return !$is_serial ? 'I8' : 'R';
case 'OID':
case 'SERIAL':
return 'R';
case 'FLOAT4':
case 'FLOAT8':
case 'DOUBLE PRECISION':
case 'REAL':
return 'F';
default:
return 'N';
}
}
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL':
case 'X': return 'TEXT';
case 'C2': return 'VARCHAR';
case 'X2': return 'TEXT';
case 'B': return 'BYTEA';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'TIMESTAMP';
case 'L': return 'BOOLEAN';
case 'I': return 'INTEGER';
case 'I1': return 'SMALLINT';
case 'I2': return 'INT2';
case 'I4': return 'INT4';
case 'I8': return 'INT8';
case 'F': return 'FLOAT8';
case 'N': return 'NUMERIC';
default:
return $meta;
}
}
/**
* Adding a new Column
*
* reimplementation of the default function as postgres does NOT allow to set the default in the same statement
*
* @param string $tabname table-name
* @param string $flds column-names and types for the changed columns
* @return array with SQL strings
*/
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$sql = array();
$not_null = false;
list($lines,$pkey) = $this->_GenFields($flds);
$alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
foreach($lines as $v) {
if (($not_null = preg_match('/NOT NULL/i',$v))) {
$v = preg_replace('/NOT NULL/i','',$v);
}
if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
list(,$colname,$default) = $matches;
$sql[] = $alter . str_replace('DEFAULT '.$default,'',$v);
$sql[] = 'UPDATE '.$tabname.' SET '.$colname.'='.$default;
$sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET DEFAULT ' . $default;
} else {
$sql[] = $alter . $v;
}
if ($not_null) {
list($colname) = explode(' ',$v);
$sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL';
}
}
return $sql;
}
function DropIndexSQL ($idxname, $tabname = NULL)
{
return array(sprintf($this->dropIndex, $this->TableName($idxname), $this->TableName($tabname)));
}
/**
* Change the definition of one column
*
* Postgres can't do that on it's own, you need to supply the complete defintion of the new table,
* to allow, recreating the table and copying the content over to the new table
* @param string $tabname table-name
* @param string $flds column-name and type for the changed column
* @param string $tableflds complete defintion of the new table, eg. for postgres, default ''
* @param array/ $tableoptions options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
/*
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if (!$tableflds) {
if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
return array();
}
return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions);
}*/
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
// Check if alter single column datatype available - works with 8.0+
$has_alter_column = 8.0 <= (float) @$this->serverInfo['version'];
if ($has_alter_column) {
$tabname = $this->TableName($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
$set_null = false;
foreach($lines as $v) {
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
if ($not_null = preg_match('/NOT NULL/i',$v)) {
$v = preg_replace('/NOT NULL/i','',$v);
}
// this next block doesn't work - there is no way that I can see to
// explicitly ask a column to be null using $flds
else if ($set_null = preg_match('/NULL/i',$v)) {
// if they didn't specify not null, see if they explicitely asked for null
// Lookbehind pattern covers the case 'fieldname NULL datatype DEFAULT NULL'
// only the first NULL should be removed, not the one specifying
// the default value
$v = preg_replace('/(?<!DEFAULT)\sNULL/i','',$v);
}
if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
$existing = $this->MetaColumns($tabname);
list(,$colname,$default) = $matches;
$alter .= $colname;
if ($this->connection) {
$old_coltype = $this->connection->MetaType($existing[strtoupper($colname)]);
}
else {
$old_coltype = $t;
}
$v = preg_replace('/^' . preg_quote($colname) . '\s/', '', $v);
$t = trim(str_replace('DEFAULT '.$default,'',$v));
// Type change from bool to int
if ( $old_coltype == 'L' && $t == 'INTEGER' ) {
$sql[] = $alter . ' DROP DEFAULT';
$sql[] = $alter . " TYPE $t USING ($colname::BOOL)::INT";
$sql[] = $alter . " SET DEFAULT $default";
}
// Type change from int to bool
else if ( $old_coltype == 'I' && $t == 'BOOLEAN' ) {
if( strcasecmp('NULL', trim($default)) != 0 ) {
$default = $this->connection->qstr($default);
}
$sql[] = $alter . ' DROP DEFAULT';
$sql[] = $alter . " TYPE $t USING CASE WHEN $colname = 0 THEN false ELSE true END";
$sql[] = $alter . " SET DEFAULT $default";
}
// Any other column types conversion
else {
$sql[] = $alter . " TYPE $t";
$sql[] = $alter . " SET DEFAULT $default";
}
}
else {
// drop default?
preg_match ('/^\s*(\S+)\s+(.*)$/',$v,$matches);
list (,$colname,$rest) = $matches;
$alter .= $colname;
$sql[] = $alter . ' TYPE ' . $rest;
}
# list($colname) = explode(' ',$v);
if ($not_null) {
// this does not error out if the column is already not null
$sql[] = $alter . ' SET NOT NULL';
}
if ($set_null) {
// this does not error out if the column is already null
$sql[] = $alter . ' DROP NOT NULL';
}
}
return $sql;
}
// does not have alter column
if (!$tableflds) {
if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
return array();
}
return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions);
}
/**
* Drop one column
*
* Postgres < 7.3 can't do that on it's own, you need to supply the complete defintion of the new table,
* to allow, recreating the table and copying the content over to the new table
* @param string $tabname table-name
* @param string $flds column-name and type for the changed column
* @param string $tableflds complete defintion of the new table, eg. for postgres, default ''
* @param array/ $tableoptions options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$has_drop_column = 7.3 <= (float) @$this->serverInfo['version'];
if (!$has_drop_column && !$tableflds) {
if ($this->debug) ADOConnection::outp("DropColumnSQL needs complete table-definiton for PostgreSQL < 7.3");
return array();
}
if ($has_drop_column) {
return ADODB_DataDict::DropColumnSQL($tabname, $flds);
}
return $this->_recreate_copy_table($tabname,$flds,$tableflds,$tableoptions);
}
/**
* Save the content into a temp. table, drop and recreate the original table and copy the content back in
*
* We also take care to set the values of the sequenz and recreate the indexes.
* All this is done in a transaction, to not loose the content of the table, if something went wrong!
* @internal
* @param string $tabname table-name
* @param string $dropflds column-names to drop
* @param string $tableflds complete defintion of the new table, eg. for postgres
* @param array/string $tableoptions options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
function _recreate_copy_table($tabname,$dropflds,$tableflds,$tableoptions='')
{
if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds);
$copyflds = array();
foreach($this->MetaColumns($tabname) as $fld) {
if (!$dropflds || !in_array($fld->name,$dropflds)) {
// we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one
if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) &&
in_array($fld->type,array('varchar','char','text','bytea'))) {
$copyflds[] = "to_number($fld->name,'S9999999999999D99')";
} else {
$copyflds[] = $fld->name;
}
// identify the sequence name and the fld its on
if ($fld->primary_key && $fld->has_default &&
preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) {
$seq_name = $matches[1];
$seq_fld = $fld->name;
}
}
}
$copyflds = implode(', ',$copyflds);
$tempname = $tabname.'_tmp';
$aSql[] = 'BEGIN'; // we use a transaction, to make sure not to loose the content of the table
$aSql[] = "SELECT * INTO TEMPORARY TABLE $tempname FROM $tabname";
$aSql = array_merge($aSql,$this->DropTableSQL($tabname));
$aSql = array_merge($aSql,$this->CreateTableSQL($tabname,$tableflds,$tableoptions));
$aSql[] = "INSERT INTO $tabname SELECT $copyflds FROM $tempname";
if ($seq_name && $seq_fld) { // if we have a sequence we need to set it again
$seq_name = $tabname.'_'.$seq_fld.'_seq'; // has to be the name of the new implicit sequence
$aSql[] = "SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname";
}
$aSql[] = "DROP TABLE $tempname";
// recreate the indexes, if they not contain one of the droped columns
foreach($this->MetaIndexes($tabname) as $idx_name => $idx_data)
{
if (substr($idx_name,-5) != '_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data['columns'])))) {
$aSql = array_merge($aSql,$this->CreateIndexSQL($idx_name,$tabname,$idx_data['columns'],
$idx_data['unique'] ? array('UNIQUE') : False));
}
}
$aSql[] = 'COMMIT';
return $aSql;
}
function DropTableSQL($tabname)
{
$sql = ADODB_DataDict::DropTableSQL($tabname);
$drop_seq = $this->_DropAutoIncrement($tabname);
if ($drop_seq) $sql[] = $drop_seq;
return $sql;
}
// return string must begin with space
function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
if ($fautoinc) {
$ftype = 'SERIAL';
return '';
}
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
// search for a sequece for the given table (asumes the seqence-name contains the table-name!)
// if yes return sql to drop it
// this is still necessary if postgres < 7.3 or the SERIAL was created on an earlier version!!!
function _DropAutoIncrement($tabname)
{
$tabname = $this->connection->quote('%'.$tabname.'%');
$seq = $this->connection->GetOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'");
// check if a tables depends on the sequenz and it therefor cant and dont need to be droped separatly
if (!$seq || $this->connection->GetOne("SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) {
return False;
}
return "DROP SEQUENCE ".$seq;
}
function RenameTableSQL($tabname,$newname)
{
if (!empty($this->schema)) {
$rename_from = $this->TableName($tabname);
$schema_save = $this->schema;
$this->schema = false;
$rename_to = $this->TableName($newname);
$this->schema = $schema_save;
return array (sprintf($this->renameTable, $rename_from, $rename_to));
}
return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname)));
}
/*
CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
{ column_name data_type [ DEFAULT default_expr ] [ column_constraint [, ... ] ]
| table_constraint } [, ... ]
)
[ INHERITS ( parent_table [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ]
where column_constraint is:
[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | UNIQUE | PRIMARY KEY |
CHECK (expression) |
REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL ]
[ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
and table_constraint is:
[ CONSTRAINT constraint_name ]
{ UNIQUE ( column_name [, ... ] ) |
PRIMARY KEY ( column_name [, ... ] ) |
CHECK ( expression ) |
FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
[ MATCH FULL | MATCH PARTIAL ] [ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
*/
/*
CREATE [ UNIQUE ] INDEX index_name ON table
[ USING acc_method ] ( column [ ops_name ] [, ...] )
[ WHERE predicate ]
CREATE [ UNIQUE ] INDEX index_name ON table
[ USING acc_method ] ( func_name( column [, ... ]) [ ops_name ] )
[ WHERE predicate ]
*/
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
if ( isset($idxoptions['DROP']) )
return $sql;
}
if ( empty ($flds) ) {
return $sql;
}
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
$s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' ';
if (isset($idxoptions['HASH']))
$s .= 'USING HASH ';
if ( isset($idxoptions[$this->upperName]) )
$s .= $idxoptions[$this->upperName];
if ( is_array($flds) )
$flds = implode(', ',$flds);
$s .= '(' . $flds . ')';
$sql[] = $s;
return $sql;
}
function _GetSize($ftype, $ty, $fsize, $fprec)
{
if (strlen($fsize) && $ty != 'X' && $ty != 'B' && $ty != 'I' && strpos($ftype,'(') === false) {
$ftype .= "(".$fsize;
if (strlen($fprec)) $ftype .= ",".$fprec;
$ftype .= ')';
}
return $ftype;
}
}
@@ -1,122 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Modified from datadict-generic.inc.php for sapdb by RalfBecker-AT-outdoor-training.de
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_sapdb extends ADODB_DataDict {
var $databaseType = 'sapdb';
var $seqField = false;
var $renameColumn = 'RENAME COLUMN %s.%s TO %s';
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL':
case 'X': return 'LONG';
case 'C2': return 'VARCHAR UNICODE';
case 'X2': return 'LONG UNICODE';
case 'B': return 'LONG';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'TIMESTAMP';
case 'L': return 'BOOLEAN';
case 'I': return 'INTEGER';
case 'I1': return 'FIXED(3)';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'FIXED(20)';
case 'F': return 'FLOAT(38)';
case 'N': return 'FIXED';
default:
return $meta;
}
}
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
static $maxdb_type2adodb = array(
'VARCHAR' => 'C',
'CHARACTER' => 'C',
'LONG' => 'X', // no way to differ between 'X' and 'B' :-(
'DATE' => 'D',
'TIMESTAMP' => 'T',
'BOOLEAN' => 'L',
'INTEGER' => 'I4',
'SMALLINT' => 'I2',
'FLOAT' => 'F',
'FIXED' => 'N',
);
$type = isset($maxdb_type2adodb[$t]) ? $maxdb_type2adodb[$t] : 'C';
// convert integer-types simulated with fixed back to integer
if ($t == 'FIXED' && !$fieldobj->scale && ($len == 20 || $len == 3)) {
$type = $len == 20 ? 'I8' : 'I1';
}
if ($fieldobj->auto_increment) $type = 'R';
return $type;
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if ($funsigned) $suffix .= ' UNSIGNED';
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fautoinc) $suffix .= ' DEFAULT SERIAL';
elseif (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
return array( 'ALTER TABLE ' . $tabname . ' ADD (' . implode(', ',$lines) . ')' );
}
function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
return array( 'ALTER TABLE ' . $tabname . ' MODIFY (' . implode(', ',$lines) . ')' );
}
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
if (!is_array($flds)) $flds = explode(',',$flds);
foreach($flds as $k => $v) {
$flds[$k] = $this->NameQuote($v);
}
return array( 'ALTER TABLE ' . $tabname . ' DROP (' . implode(', ',$flds) . ')' );
}
}
@@ -1,90 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
SQLite datadict Andrei Besleaga
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_sqlite extends ADODB_DataDict {
var $databaseType = 'sqlite';
var $seqField = false;
var $addCol=' ADD COLUMN';
var $dropTable = 'DROP TABLE IF EXISTS %s';
var $dropIndex = 'DROP INDEX IF EXISTS %s';
var $renameTable = 'ALTER TABLE %s RENAME TO %s';
function ActualType($meta)
{
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR'; // TEXT , TEXT affinity
case 'XL':return 'LONGTEXT'; // TEXT , TEXT affinity
case 'X': return 'TEXT'; // TEXT , TEXT affinity
case 'C2': return 'VARCHAR'; // TEXT , TEXT affinity
case 'X2': return 'LONGTEXT'; // TEXT , TEXT affinity
case 'B': return 'LONGBLOB'; // TEXT , NONE affinity , BLOB
case 'D': return 'DATE'; // NUMERIC , NUMERIC affinity
case 'T': return 'DATETIME'; // NUMERIC , NUMERIC affinity
case 'L': return 'TINYINT'; // NUMERIC , INTEGER affinity
case 'R':
case 'I4':
case 'I': return 'INTEGER'; // NUMERIC , INTEGER affinity
case 'I1': return 'TINYINT'; // NUMERIC , INTEGER affinity
case 'I2': return 'SMALLINT'; // NUMERIC , INTEGER affinity
case 'I8': return 'BIGINT'; // NUMERIC , INTEGER affinity
case 'F': return 'DOUBLE'; // NUMERIC , REAL affinity
case 'N': return 'NUMERIC'; // NUMERIC , NUMERIC affinity
default:
return $meta;
}
}
// return string must begin with space
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if ($funsigned) $suffix .= ' UNSIGNED';
if ($fnotnull) $suffix .= ' NOT NULL';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fautoinc) $suffix .= ' AUTOINCREMENT';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported natively by SQLite");
return array();
}
function DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported natively by SQLite");
return array();
}
function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='')
{
if ($this->debug) ADOConnection::outp("RenameColumnSQL not supported natively by SQLite");
return array();
}
}
@@ -1,230 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_sybase extends ADODB_DataDict {
var $databaseType = 'sybase';
var $dropIndex = 'DROP INDEX %2$s.%1$s';
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'INT':
case 'INTEGER': return 'I';
case 'BIT':
case 'TINYINT': return 'I1';
case 'SMALLINT': return 'I2';
case 'BIGINT': return 'I8';
case 'REAL':
case 'FLOAT': return 'F';
default: return parent::MetaType($t,$len,$fieldobj);
}
}
function ActualType($meta)
{
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR';
case 'XL':
case 'X': return 'TEXT';
case 'C2': return 'NVARCHAR';
case 'X2': return 'NTEXT';
case 'B': return 'IMAGE';
case 'D': return 'DATETIME';
case 'TS':
case 'T': return 'DATETIME';
case 'L': return 'BIT';
case 'I': return 'INT';
case 'I1': return 'TINYINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INT';
case 'I8': return 'BIGINT';
case 'F': return 'REAL';
case 'N': return 'NUMERIC';
default:
return $meta;
}
}
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$f = array();
list($lines,$pkey) = $this->_GenFields($flds);
$s = "ALTER TABLE $tabname $this->addCol";
foreach($lines as $v) {
$f[] = "\n $v";
}
$s .= implode(', ',$f);
$sql[] = $s;
return $sql;
}
function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
foreach($lines as $v) {
$sql[] = "ALTER TABLE $tabname $this->alterCol $v";
}
return $sql;
}
function DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
{
$tabname = $this->TableName($tabname);
if (!is_array($flds)) $flds = explode(',',$flds);
$f = array();
$s = "ALTER TABLE $tabname";
foreach($flds as $v) {
$f[] = "\n$this->dropCol ".$this->NameQuote($v);
}
$s .= implode(', ',$f);
$sql[] = $s;
return $sql;
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fautoinc) $suffix .= ' DEFAULT AUTOINCREMENT';
if ($fnotnull) $suffix .= ' NOT NULL';
else if ($suffix == '') $suffix .= ' NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
/*
CREATE TABLE
[ database_name.[ owner ] . | owner. ] table_name
( { < column_definition >
| column_name AS computed_column_expression
| < table_constraint > ::= [ CONSTRAINT constraint_name ] }
| [ { PRIMARY KEY | UNIQUE } [ ,...n ]
)
[ ON { filegroup | DEFAULT } ]
[ TEXTIMAGE_ON { filegroup | DEFAULT } ]
< column_definition > ::= { column_name data_type }
[ COLLATE < collation_name > ]
[ [ DEFAULT constant_expression ]
| [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
]
[ ROWGUIDCOL]
[ < column_constraint > ] [ ...n ]
< column_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ NULL | NOT NULL ]
| [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
[ WITH FILLFACTOR = fillfactor ]
[ON {filegroup | DEFAULT} ] ]
]
| [ [ FOREIGN KEY ]
REFERENCES ref_table [ ( ref_column ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
]
| CHECK [ NOT FOR REPLICATION ]
( logical_expression )
}
< table_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
{ ( column [ ASC | DESC ] [ ,...n ] ) }
[ WITH FILLFACTOR = fillfactor ]
[ ON { filegroup | DEFAULT } ]
]
| FOREIGN KEY
[ ( column [ ,...n ] ) ]
REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ]
( search_conditions )
}
*/
/*
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
[ WITH < index_option > [ ,...n] ]
[ ON filegroup ]
< index_option > :: =
{ PAD_INDEX |
FILLFACTOR = fillfactor |
IGNORE_DUP_KEY |
DROP_EXISTING |
STATISTICS_NORECOMPUTE |
SORT_IN_TEMPDB
}
*/
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
if ( isset($idxoptions['DROP']) )
return $sql;
}
if ( empty ($flds) ) {
return $sql;
}
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
$clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
if ( is_array($flds) )
$flds = implode(', ',$flds);
$s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
if ( isset($idxoptions[$this->upperName]) )
$s .= $idxoptions[$this->upperName];
$sql[] = $s;
return $sql;
}
}
-17
View File
@@ -1,17 +0,0 @@
# ADOdb Documentation
ADOdb documentation is available in the following locations
- [Online](http://adodb.org/)
- [Download](https://sourceforge.net/projects/adodb/files/Documentation/) for offline use
## Legacy documentation
The old HTML files are available in
[GitHub](https://github.com/ADOdb/ADOdb/tree/8b8133771ecbe9c95e57abbe5dc3757f0226bfcd/docs),
or in the release zip/tarballs for version 5.20 and before on
[Sourceforge](https://sourceforge.net/projects/adodb/files/adodb-php5-only/).
## Changelog
The full historical [Changelog](changelog.md) is available on GitHub.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

-491
View File
@@ -1,491 +0,0 @@
# ADOdb Changelog - v5.x
Older changelogs:
[v4.x](changelog_v4.x.md),
[v3.x](changelog_v3.x.md),
[v2.x](changelog_v2.x.md).
## 5.20.9 - 21-Dec-2016
- mssql: fix syntax error in version matching regex #305
## 5.20.8 - 17-Dec-2016
- mssql: support MSSQL Server 2016 and later #294
- mssql: fix Find() returning no results. #298
- mssql: fix Sequence name forced to 'adodbseq'. #295, #300
- mssql: fix GenId() not returning next sequence value with SQL Server 2005/2008. #302
- mssql: fix drop/alter column with existing default constraint. #290
- mssql: fix PHP notice in MetaColumns(). #289
- oci8po: fix inconsistent variable binding in SelectLimit() #288
- oci8po: fix SelectLimit() with prepared statements #282
## 5.20.7 - 20-Sep-2016
- security: Fix SQL injection in PDO drivers qstr() method (CVE-2016-7405). #226
- oci8po: prevent segfault on PHP 7. #259
- pdo/mysql: Fix MetaTables() method. #275
## 5.20.6 - 31-Aug-2016
- security: Fix XSS vulnerability in old test script (CVE-2016-4855). #274
- adodb: Exit with error/exception when the ADOdb Extension is loaded. #269
- adodb: Fix truncated exception messages. #273
## 5.20.5 - 10-Aug-2016
- adodb: Fix fatal error when connecting with missing extension. #254
- adodb: Fix _adodb_getcount(). #236
- mssql: Destructor fails if recordset already closed. #268
- mssql: Use SQL server native data types if available. #234
- mysqli: Fix PHP notice in _close() method. #240
- pdo: Let driver handle SelectDB() and SQLDate() calls. #242
- xml: Fix PHP strict warning. #260
- xml: remove calls to 'unset($this)' (PHP 7.1 compatibility). #257
## 5.20.4 - 31-Mar-2016
- adodb: Fix BulkBind() param count validation. #199
- mysqli: fix PHP warning in recordset destructor. #217
- mysqli: cast port number to int when connecting (PHP7 compatibility). #218
## 5.20.3 - 01-Jan-2016
- mssql: PHP warning when closing recordset from destructor not fixed in v5.20.2. #180
## 5.20.2 - 27-Dec-2015
- adodb: Remove a couple leftover PHP 4.x constructors (PHP7 compatibility). #139
- db2ora: Remove deprecated preg_replace '/e' flag (PHP7 compatibility). #168
- mysql: MoveNext() now respects ADODB_ASSOC_CASE. #167
- mssql, mysql, informix: Avoid PHP warning when closing recordset from destructor. #170
## 5.20.1 - 06-Dec-2015
- adodb: Fix regression introduced in 5.20.0, causing a PHP Warning when
calling GetAssoc() on an empty recordset. See Github #162
- ADOConnection::Version() now handles SemVer. See Github #164
## 5.20.0 - 28-Nov-2015
- adodb: Fix regression introduced in v5.19, causing queries to return empty rows. See Github #20, #93, #95
- adodb: Fix regression introduced in v5.19 in GetAssoc() with ADODB_FETCH_ASSOC mode and '0' as data. See Github #102
- adodb: AutoExecute correctly handles empty result set in case of updates. See Github #13
- adodb: Fix regex in Version(). See Github #16
- adodb: Align method signatures to definition in parent class ADODB_DataDict. See Github #31
- adodb: Improve compatibility of ADORecordSet_empty, thanks to Sjan Evardsson. See Github #43
- adodb: fix ADODB_Session::open() failing after successful ADONewConnection() call, thanks to Sjan Evardsson. See Github #44
- adodb: Only include memcache library once for PHPUnit 4.x, thanks to Alan Farquharson. See Github #74
- adodb: Move() returns false when given row is < 0, thanks to Mike Benoit.
- adodb: Add support for pagination with complex queries, thanks to Mike Benoit. See Github #88
- adodb: Parse port out of hostname if specified in connection parameters, thanks to Andy Theuninck. See Github #63
- adodb: Fix inability to set values from 0 to null (and vice versa) with Active Record, thanks to Louis Johnson. See Github #71
- adodb: Fix PHP strict warning in ADODB_Active_Record::Reload(), thanks to Boštjan Žokš. See Github #75
- adodb: Add mssql's DATETIME2 type to ADOConnection::MetaType(), thanks to MarcelTO. See Github #80
- adodb: When flushing cache, initialize it if it is not set, thanks to Paul Haggart. See Github #57
- adodb: Define DB_AUTOQUERY_* constants in main include file. See Github #49
- adodb: Improve documentation of fetch mode and assoc case
- adodb: Improve logic to build the assoc case bind array
- adodb: Strict-standards compliance for function names. See Github #18, #142
- adodb: Remove old PHP 4.x constructors for compatibility with PHP 7. See Github #139
- adodb: Initialize charset in ADOConnection::SetCharSet. See Github #39
- adodb: Fix incorrect handling of input array in Execute(). See Github #146
- adodb: Release Recordset when raising exception. See Github #143
- adodb: Added new setConnectionParameter() method, currently implemented in mssqlnative driver only. See Github #158.
- adodb-lib: Optimize query pagination, thanks to Mike Benoit. See Github #110
- memcache: use include_once() to avoid issues with PHPUnit. See http://phplens.com/lens/lensforum/msgs.php?id=19489
- mssql_n: Allow use of prepared statements with driver. See Github #22
- mssqlnative: Use ADOConnection::outp instead of error_log. See Github #12
- mssqlnative: fix failure on Insert_ID() if the insert statement contains a semicolon in a value string, thanks to sketule. See Github #96
- mssqlnative: Fix "invalid parameter was passed to sqlsrv_configure" error, thanks to Ray Morris. See Github #103
- mssqlnative: Fix insert_ID() failing if server returns more than 1 row, thanks to gitjti. See Github #41
- mysql: prevent race conditions when creating/dropping sequences, thanks to MikeB. See Github #28
- mysql: Fix adodb_strip_order_by() bug causing SQL error for subqueries with order/limit clause, thanks to MikeB.
- mysql: workaround for HHVM behavior, thanks to Mike Benoit.
- mysqli: Fix qstr() when called without an active connection. See Github #11
- oci8: Fix broken quoting of table name in AddColumnSQL and AlterColumnSQL, thanks to Andreas Fernandez. see Github #67
- oci8: Allow oci8 driver to use lowercase field names in assoc mode. See Github #21
- oci8po: Prevent replacement of '?' within strings, thanks to Mark Newnham. See Github #132
- pdo: Added missing property (fixes PHP notices). see Github #56
- pdo: Align method signatures with parent class, thanks to Andy Theuninck. see Github #62
- pdo: new sqlsrv driver, thanks to MarcelTO. See Github #81
- pdo/mysql: New methods to make the driver behave more like mysql/mysqli, thanks to Andy Theuninck. see Github #40
- postgres: Stop using legacy function aliases
- postgres: Fix AlterColumnSQL when updating multiple columns, thanks to Jouni Ahto. See Github #72
- postgres: Fix support for HHVM 3.6, thanks to Mike Benoit. See Github #87
- postgres: Noblob optimization, thanks to Mike Benoit. See Github #112
- postgres7: fix system warning in MetaColumns() with schema. See http://phplens.com/lens/lensforum/msgs.php?id=19481
- sqlite3: ServerInfo() now returns driver's version
- sqlite3: Fix wrong connection parameter in _connect(), thanks to diogotoscano. See Github #51
- sqlite3: Fix FetchField, thanks to diogotoscano. See Github #53
- sqlite3: Fix result-less SQL statements executed twice. See Github #99
- sqlite3: use -1 for _numOfRows. See Github #151
- xmlschema: Fix ExtractSchema() when given $prefix and $stripprefix parameters, thanks to peterdd. See Github #92
- Convert languages files to UTF-8, thanks to Marc-Etienne Vargenau. See Github #32.
## 5.19 - 23-Apr-2014
**NOTE:**
This release suffers from a [known issue with Associative Fetch Mode](https://github.com/ADOdb/ADOdb/issues/20)
(i.e. when $ADODB_FETCH_MODE is set to ADODB_FETCH_ASSOC).
It causes recordsets to return empty strings (no data) when using some database drivers.
The problem has been reported on MSSQL, Interbase and Foxpro, but possibly affects
other database types as well; all drivers derived from the above are also impacted.
- adodb: GetRowAssoc will return null as required. See http://phplens.com/lens/lensforum/msgs.php?id=19289
- adodb: Fix GetRowAssoc bug introduced in 5.17, causing function to return data from previous fetch for NULL fields. See http://phplens.com/lens/lensforum/msgs.php?id=17539
- adodb: GetAssoc will return a zero-based array when 2nd column is null. See https://sourceforge.net/p/adodb/bugs/130/
- adodb: Execute no longer ignores single parameters evaluating to false. See https://sourceforge.net/p/adodb/patches/32/
- adodb: Fix LIMIT 1 clause in subquery gets stripped off. See http://phplens.com/lens/lensforum/msgs.php?id=17813
- adodb-lib: Fix columns quoting bug. See https://sourceforge.net/p/adodb/bugs/127/
- Added new ADODB_ASSOC_CASE_* constants. Thx to Damien Regad.
- sessions: changed lob handling to detect all variations of oci8 driver.
- ads: clear fields before fetching. See http://phplens.com/lens/lensforum/msgs.php?id=17539
- mssqlnative: fixed many FetchField compat issues. See http://phplens.com/lens/lensforum/msgs.php?id=18464. Also date format changed to remove timezone.
- mssqlnative: Numerous fixes and improvements by Mark Newnham
- Driver supports SQL Server 2005, 2008 and 2012
- Bigint data types mapped to I8 instead of I
- Reintroduced MetaColumns function
- On SQL Server 2012, makes use of new CREATE SEQUENCE statement
- FetchField caches metadata at initialization to improve performance
- etc.
- mssqlnative: Fix Insert ID on prepared statement, thanks to Mike Parks. See http://phplens.com/lens/lensforum/msgs.php?id=19079
- mssql: timestamp format changed to `Y-m-d\TH:i:s` (ISO 8601) to make them independent from DATEFORMAT setting, as recommended on
[Microsoft TechNet](http://technet.microsoft.com/en-us/library/ms180878%28v=sql.105%29.aspx#StringLiteralDateandTimeFormats).
- mysql/mysqli: Fix ability for MetaTables to filter by table name, broken since 5.15. See http://phplens.com/lens/lensforum/msgs.php?id=19359
- odbc: Fixed MetaTables and MetaPrimaryKeys definitions in odbc driver to match adoconnection class.
- odbc: clear fields before fetching. See http://phplens.com/lens/lensforum/msgs.php?id=17539
- oci8: GetRowAssoc now works in ADODB_FETCH_ASSOC fetch mode
- oci8: MetaType and MetaForeignKeys argument count are now strict-standards compliant
- oci8: Added trailing `;` on trigger creation for sequence fields, prevents occurence of ORA-24344
- oci8quercus: new oci8 driver with support for quercus jdbc data types.
- pdo: Fixed concat recursion bug in 5.3. See http://phplens.com/lens/lensforum/msgs.php?id=19285
- pgsql: Default driver (postgres/pgsql) is now postgres8
- pgsql: Fix output of BLOB (bytea) columns with PostgreSQL >= 9.0
- pgsql: Fix handling of DEFAULT NULL columns in AlterColumnSQL
- pgsql: Fix mapping of error message to ADOdb error codes
- pgsql: Reset parameter number in Param() method when $name == false
- postgres8: New class/type with correct behavior for _insertid(). See Github #8
- postgres9: Fixed assoc problem. See http://phplens.com/lens/lensforum/msgs.php?id=19296
- sybase: Removed redundant sybase_connect() call in _connect(). See Github #3
- sybase: Allow connection on custom port. See Github #9
- sybase: Fix null values returned with ASSOC fetch mode. See Github #10
- Added Composer support. See Github #7
## 5.18 - 3 Sep 2012
- datadict-postgres: Fixes bug in ALTER COL. See http://phplens.com/lens/lensforum/msgs.php?id=19202.
- datadict-postgres: fixed bugs in MetaType() checking $fieldobj properties.
- GetRowAssoc did not work with null values. Bug in 5.17.
- postgres9: New driver to better support PostgreSQL 9. Thx Glenn Herteg and Cacti team.
- sqlite3: Modified to support php 5.4. Thx Günter Weber [built.development#googlemail.com]
- adodb: When fetch mode is ADODB_FETCH_ASSOC, and we execute `$db->GetAssoc("select 'a','0'");` we get an error. Fixed. See http://phplens.com/lens/lensforum/msgs.php?id=19190
- adodb: Caching directory permissions now configurable using global variable $ADODB_CACHE_PERMS. Default value is 0771.
- mysqli: SetCharSet() did not return true (success) or false (fail) correctly. Fixed.
- mysqli: changed dataProvider to 'mysql' so that MetaError and other shared functions will work.
- mssqlnative: Prepare() did not work previously. Now calling Prepare() will work but the sql is not actually compiled. Unfortunately bind params are passed to sqlsrv_prepare and not to sqlsrv_execute. make Prepare() and empty function, and we still execute the unprepared stmt.
- mysql: FetchField(-1), turns it is is not possible to retrieve the max_length. Set to -1.
- mysql-perf: Fixed "SHOW INNODB STATUS". Change to "SHOW ENGINE INNODB STATUS"
## 5.17 - 18 May 2012
- Active Record: Removed trailing whitespace from adodb-active-record.inc.php.
- odbc: Added support for $database parameter in odbc Connect() function. E.g. $DB->Connect($dsn_without_db, $user, $pwd, $database).
Previously $database had to be left blank and the $dsn was used to pass in this parameter.
- oci8: Added better empty($rs) error handling to metaindexes().
- oci8: Changed to use newer oci API to support PHP 5.4.
- adodb.inc.php: Changed GetRowAssoc to more generic code that will work in all scenarios.
## 5.16 - 26 March 2012
- mysqli: extra mysqli_next_result() in close() removed. See http://phplens.com/lens/lensforum/msgs.php?id=19100
- datadict-oci8: minor typo in create sequence trigger fixed. See http://phplens.com/lens/lensforum/msgs.php?id=18879.
- security: safe date parsing changes. Does not impact security, these are code optimisations. Thx Saithis.
- postgres, oci8, oci8po, db2oci: Param() function parameters inconsistent with base class. $type='C' missing. Fixed.
- active-record: locked bug fixed. http://phplens.com/lens/lensforum/msgs.php?phplens_forummsg=new&id=19073
- mysql, mysqli and informix: added MetaProcedures. Metaprocedures allows to retrieve an array list of all procedures in database. http://phplens.com/lens/lensforum/msgs.php?id=18414
- Postgres7: added support for serial data type in MetaColumns().
## 5.15 - 19 Jan 2012
- pdo: fix ErrorMsg() to detect errors correctly. Thx Jens.
- mssqlnative: added another check for $this->fields array exists.
- mssqlnative: bugs in FetchField() fixed. See http://phplens.com/lens/lensforum/msgs.php?id=19024
- DBDate and DBTimeStamp had sql injection bug. Fixed. Thx Saithis
- mysql and mysqli: MetaTables() now identifies views and tables correctly.
- Added function adodb_time() to adodb-time.inc.php. Generates current time in unsigned integer format.
## 5.14 - 8 Sep 2011
- mysqli: fix php compilation bug.
- postgres: bind variables did not work properly. Fixed.
- postgres: blob handling bug in _decode. Fixed.
- ActiveRecord: if a null field was never updated, activerecord would still update the record. Fixed.
- ActiveRecord: 1 char length string never quoted. Fixed.
- LDAP: Connection string ldap:// and ldaps:// did not work. Fixed.
## 5.13 - 15 Aug 2011
- Postgres: Fix in 5.12 was wrong. Uses pg_unescape_bytea() correctly now in _decode.
- GetInsertSQL/GetUpdateSQL: Now $ADODB_QUOTE_FIELDNAMES allows you to define 'NATIVE', 'UPPER', 'LOWER'. If set to true, will default to 'UPPER'.
- mysqli: added support for persistent connections 'p:'.
- mssqlnative: ADODB_FETCH_BOTH did not work properly. Fixed.
- mssqlnative: return values for stored procedures where not returned! Fixed. See http://phplens.com/lens/lensforum/msgs.php?id=18919
- mssqlnative: timestamp and fetchfield bugs fixed. http ://phplens.com/lens/lensforum/msgs.php?id=18453
## 5.12 - 30 June 2011
- Postgres: Added information_schema support for postgresql.
- Postgres: Use pg_unescape_bytea() in _decode.
- Fix bulk binding with oci8. http://phplens.com/lens/lensforum/msgs.php?id=18786
- oci8 perf: added wait evt monitoring. Also db cache advice now handles multiple buffer pools properly.
- sessions2: Fixed setFetchMode problem.
- sqlite: Some DSN connection settings were not parsed correctly.
- mysqli: now GetOne obeys $ADODB_GETONE_EOF;
- memcache: compress option did not work. Fixed. See http://phplens.com/lens/lensforum/msgs.php?id=18899
## 5.11 - 5 May 2010
- mysql: Fixed GetOne() to return null if no records returned.
- oci8 perf: added stats on sga, rman, memory usage, and flash in performance tab.
- odbtp: Now you can define password in $password field of Connect()/PConnect(), and it will add it to DSN.
- Datadict: altering columns did not consider the scale of the column. Now it does.
- mssql: Fixed problem with ADODB_CASE_ASSOC causing multiple versions of column name appearing in recordset fields.
- oci8: Added missing & to refLob.
- oci8: Added obj->scale to FetchField().
- oci8: Now you can get column info of a table in a different schema, e.g. MetaColumns("schema.table") is supported.
- odbc_mssql: Fixed missing $metaDatabasesSQL.
- xmlschema: Changed declaration of create() to create($xmls) to fix compat problems. Also changed constructor adoSchema() to pass in variable instead of variable reference.
- ado5: Fixed ado5 exceptions to only display errors when $this->debug=true;
- Added DSN support to sessions2.inc.php.
- adodb-lib.inc.php. Fixed issue with _adodb_getcount() not using $secs2cache parameter.
- adodb active record. Fixed caching bug. See http://phplens.com/lens/lensforum/msgs.php?id=18288.
- db2: fixed ServerInfo().
- adodb_date: Added support for format 'e' for TZ as in adodb_date('e')
- Active Record: If you have a field which is a string field (with numbers in) and you add preceding 0's to it the adodb library does not pick up the fact that the field has changed because of the way php's == works (dodgily). The end result is that it never gets updated into the database - fix by Matthew Forrester (MediaEquals). [matthew.forrester#mediaequals.com]
- Fixes RowLock() and MetaIndexes() inconsistencies. See http://phplens.com/lens/lensforum/msgs.php?id=18236
- Active record support for postgrseql boolean. See http://phplens.com/lens/lensforum/msgs.php?id=18246
- By default, Execute 2D array is disabled for security reasons. Set $conn->bulkBind = true to enable. See http://phplens.com/lens/lensforum/msgs.php?id=18270. Note this breaks backward compat.
- MSSQL: fixes for 5.2 compat. http://phplens.com/lens/lensforum/msgs.php?id=18325
- Changed Version() to return a string instead of a float so it correctly returns 5.10 instead of 5.1.
## 5.10 - 10 Nov 2009
- Fixed memcache to properly support $rs->timeCreated.
- adodb-ado.inc.php: Added BigInt support for PHP5. Will return float instead to support large numbers. Thx nasb#mail.goo.ne.jp.
- adodb-mysqli.inc.php: mysqli_multi_query is now turned off by default. To turn it on, use $conn->multiQuery = true; This is because of the risks of sql injection. See http://phplens.com/lens/lensforum/msgs.php?id=18144
- New db2oci driver for db2 9.7 when using PL/SQL mode. Allows oracle style :0, :1, :2 bind parameters which are remapped to ? ? ?.
- adodb-db2.inc.php: fixed bugs in MetaTables. SYS owner field not checked properly. Also in $conn->Connect($dsn, null, null, $schema) and PConnect($dsn, null, null, $schema), we do a SET SCHEMA=$schema if successful connection.
- adodb-mysqli.inc.php: Now $rs->Close() closes all pending next resultsets. Thx Clifton mesmackgod#gmail.com
- Moved _CreateCache() from PConnect()/Connect() to CacheExecute(). Suggested by Dumka.
- Many bug fixes to adodb-pdo_sqlite.inc.php and new datadict-sqlite.inc.php. Thx Andrei B. [andreutz#mymail.ro]
- Removed usage of split (deprecated in php 5.3). Thx david#horizon-nigh.org.
- Fixed RowLock() parameters to comply with PHP5 strict mode in multiple drivers.
## 5.09 - 25 June 2009
- Active Record: You can force column names to be quoted in INSERT and UPDATE statements, typically because you are using reserved words as column names by setting ADODB_Active_Record::$_quoteNames = true;
- Added memcache and cachesecs to DSN. e.g.
``` php
# we have a memcache servers mem1,mem2 on port 8888, compression=off and cachesecs=120
$dsn = 'mysql://user:pwd@localhost/mydb?memcache=mem1,mem2:8888:0&cachesecs=120';
```
- Fixed up MetaColumns and MetaPrimaryIndexes() for php 5.3 compat. Thx http://adodb.pastebin.com/m52082b16
- The postgresql driver's OffsetDate() apparently does not work with postgres 8.3. Fixed.
- Added support for magic_quotes_sybase in qstr() and addq(). Thanks Eloy and Sam Moffat.
- The oci8 driver did not handle LOBs properly when binding. Fixed. See http://phplens.com/lens/lensforum/msgs.php?id=17991.
- Datadict: In order to support TIMESTAMP with subsecond accuracy, added to datadict the new TS type. Supported by mssql, postgresql and oci8 (oracle). Also changed oci8 $conn->sysTimeStamp to use 'SYSTIMESTAMP' instead of 'SYSDATE'. Should be backwards compat.
- Added support for PHP 5.1+ DateTime objects in DBDate and DBTimeStamp. This means that dates and timestamps will be managed by DateTime objects if you are running PHP 5.1+.
- Added new property to postgres64 driver to support returning I if type is unique int called $db->uniqueIisR, defaulting to true. See http://phplens.com/lens/lensforum/msgs.php?id=17963
- Added support for bindarray in adodb_GetActiveRecordsClass with SelectLimit in adodb-active-record.inc.php.
- Transactions now allowed in ado_access driver. Thx to petar.petrov.georgiev#gmail.com.
- Sessions2 garbage collection is now much more robust. We perform ORDER BY to prevent deadlock in adodb-sessions2.inc.php.
- Fixed typo in pdo_sqlite driver.
## 5.08a - 17 Apr 2009
- Fixes wrong version number string.
- Incorrect + in adodb-datadict.inc.php removed.
- Fixes missing OffsetDate() function in pdo. Thx paul#mantisforge.org.
## 5.08 - 17 Apr 2009
- adodb-sybase.inc.php driver. Added $conn->charSet support. Thx Luis Henrique Mulinari (luis.mulinari#gmail.com)
- adodb-ado5.inc.php. Fixed some bind param issues. Thx Jirka Novak.
- adodb-ado5.inc.php. Now has improved error handling.
- Fixed typo in adodb-xmlschema03.inc.php. See XMLS_EXISTING_DATA, line 1501. Thx james johnson.
- Made $inputarr optional for _query() in all drivers.
- Fixed spelling mistake in flushall() in adodb.inc.ophp.
- Fixed handling of quotes in adodb_active_record::doquote. Thx Jonathan Hohle (jhohle#godaddy.com).
- Added new index parameter to adodb_active_record::setdatabaseadaptor. Thx Jonathan Hohle
- Fixed & readcache() reference compat problem with php 5.3 in adodb.Thx Jonathan Hohle.
- Some minor $ADODB_CACHE_CLASS definition issues in adodb.inc.php.
- Added Reset() function to adodb_active_record. Thx marcus.
- Minor dsn fix for pdo_sqlite in adodb.inc.php. Thx Sergey Chvalyuk.
- Fixed adodb-datadict _CreateSuffix() inconsistencies. Thx Chris Miller.
- Option to delete old fields $dropOldFlds in datadict ChangeTableSQL($table, $flds, $tableOptions, $dropOldFlds=false) added. Thx Philipp Niethammer.
- Memcache caching did not expire properly. Fixed.
- MetaForeignKeys for postgres7 driver changed from adodb_movenext to $rs->MoveNext (also in 4.99)
- Added support for ldap and ldaps url format in ldap driver. E.g. ldap://host:port/dn?attributes?scope?filter?extensions
## 5.07 - 26 Dec 2008
- BeginTrans/CommitTrans/RollbackTrans return true/false correctly on success/failure now for mssql, odbc, oci8, mysqlt, mysqli, postgres, pdo.
- Replace() now quotes all non-null values including numeric ones.
- Postgresql qstr() now returns booleans as *true* and *false* without quotes.
- MetaForeignKeys in mysql and mysqli drivers had this problem: A table can have two foreign keys pointing to the same column in the same table. The original code will incorrectly report only the last column. Fixed. https://sourceforge.net/tracker/index.php?func=detail&aid=2287278&group_id=42718&atid=433976
- Passing in full ado connection string in $argHostname with ado drivers was failing in adodb5 due to bug. Fixed.
- Fixed memcachelib flushcache and flushall bugs. Also fixed possible timeCreated = 0 problem in readcache. (Also in adodb 4.992). Thanks AlexB_UK (alexbarnes#hotmail.com).
- Fixed a notice in adodb-sessions2.inc.php, in _conn(). Thx bober m.derlukiewicz#rocktech.remove_me.pl;
- ADOdb Active Record: Fixed some issues with incompatible fetch modes (ADODB_FETCH_ASSOC) causing problems in UpdateActiveTable().
- ADOdb Active Record: Added support for functions that support predefining one-to-many relationships:
_ClassHasMany ClassBelongsTo TableHasMany TableBelongsTo TableKeyHasMany TableKeyBelongsTo_.
- You can also define your child/parent class in these functions, instead of the default ADODB_Active_Record. Thx Arialdo Martini & Chris R for idea.
- ADOdb Active Record: HasMany hardcoded primary key to "id". Fixed.
- Many pdo and pdo-sqlite fixes from Sid Dunayer [sdunayer#interserv.com].
- CacheSelectLimit not working for mssql. Fixed. Thx AlexB.
- The rs2html function did not display hours in timestamps correctly. Now 24hr clock used.
- Changed ereg* functions to use preg* functions as ereg* is deprecated in PHP 5.3. Modified sybase and postgresql drivers.
## 5.06 - 16 Oct 2008
- Added driver adodb-pdo_sqlite.inc.php. Thanks Diogo Toscano (diogo#scriptcase.net) for the code.
- Added support for [one-to-many relationships](docs-active-record.htm#onetomany) with BelongsTo() and HasMany() in adodb_active_record.
- Added BINARY type to mysql.inc.php (also in 4.991).
- Added support for SelectLimit($sql,-1,100) in oci8. (also in 4.991).
- New $conn->GetMedian($table, $field, $where='') to get median account no. (also in 4.991)
- The rs2html() function in tohtml.inc.php did not handle dates with ':' in it properly. Fixed. (also in 4.991)
- Added support for connecting to oci8 using `$DB->Connect($ip, $user, $pwd, "SID=$sid");` (also in 4.991)
- Added mysql type 'VAR_STRING' to MetaType(). (also in 4.991)
- The session and session2 code supports setfetchmode assoc properly now (also in 4.991).
- Added concat support to pdo. Thx Andrea Baron.
- Changed db2 driver to use format `Y-m-d H-i-s` for datetime instead of `Y-m-d-H-i-s` which was legacy from odbc_db2 conversion.
- Removed vestigal break on adodb_tz_offset in adodb-time.inc.php.
- MetaForeignKeys did not work for views in MySQL 5. Fixed.
- Changed error handling in GetActiveRecordsClass.
- Added better support for using existing driver when $ADODB_NEWCONNECTION function returns false.
- In _CreateSuffix in adodb-datadict.inc.php, adding unsigned variable for mysql.
- In adodb-xmlschema03.inc.php, changed addTableOpt to include db name.
- If bytea blob in postgresql is null, empty string was formerly returned. Now null is returned.
- Changed db2 driver CreateSequence to support $start parameter.
- rs2html() now does not add nbsp to end if length of string > 0
- The oci8po FetchField() now only lowercases field names if ADODB_ASSOC_CASE is set to 0.
- New mssqlnative drivers for php. TQ Garrett Serack of M'soft. [Download](http://www.microsoft.com/downloads/details.aspx?FamilyId=61BF87E0-D031-466B-B09A-6597C21A2E2A&displaylang=en) mssqlnative extension. Note that this is still in beta.
- Fixed bugs in memcache support.
- You can now change the return value of GetOne if no records are found using the global variable $ADODB_GETONE_EOF. The default is null. To change it back to the pre-4.99/5.00 behaviour of false, set $ADODB_GETONE_EOF = false;
- In Postgresql 8.2/8.3 MetaForeignkeys did not work. Fixed William Kolodny William.Kolodny#gt-t.net
## 5.05 - 11 Jul 2008
Released together with [v4.990](changelog_v4.x.md#4990---11-jul-2008)
- Added support for multiple recordsets in mysqli , thanks to Geisel Sierote geisel#4up.com.br. See http://phplens.com/lens/lensforum/msgs.php?id=15917
- Malcolm Cook added new Reload() function to Active Record. See http://phplens.com/lens/lensforum/msgs.php?id=17474
- Thanks Zoltan Monori (monzol#fotoprizma.hu) for bug fixes in iterator, SelectLimit, GetRandRow, etc.
- Under heavy loads, the performance monitor for oci8 disables Ixora views.
- Fixed sybase driver SQLDate to use str_replace(). Also for adodb5, changed sybase driver UnixDate and UnixTimeStamp calls to static.
- Changed oci8 lob handler to use & reference `$this->_refLOBs[$numlob]['VAR'] = &$var`.
- We now strtolower the get_class() function in PEAR::isError() for php5 compat.
- CacheExecute did not retrieve cache recordsets properly for 5.04 (worked in 4.98). Fixed.
- New ADODB_Cache_File class for file caching defined in adodb.inc.php.
- Farsi language file contribution by Peyman Hooshmandi Raad (phooshmand#gmail.com)
- New API for creating your custom caching class which is stored in $ADODB_CACHE:
``` php
include "/path/to/adodb.inc.php";
$ADODB_CACHE_CLASS = 'MyCacheClass';
class MyCacheClass extends ADODB_Cache_File
{
function writecache($filename, $contents,$debug=false) {...}
function &readcache($filename, &$err, $secs2cache, $rsClass) { ...}
:
}
$DB = NewADOConnection($driver);
$DB->Connect(...); ## MyCacheClass created here and stored in $ADODB_CACHE global variable.
$data = $rs->CacheGetOne($sql); ## MyCacheClass is used here for caching...
```
- Memcache supports multiple pooled hosts now. Only if none of the pooled servers
can be contacted will a connect error be generated. Usage example below:
``` php
$db = NewADOConnection($driver);
$db->memCache = true; /// should we use memCache instead of caching in files
$db->memCacheHost = array($ip1, $ip2, $ip3); /// $db->memCacheHost = $ip1; still works
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)
$db->Connect(...);
$db->CacheExecute($sql);
```
## 5.04 - 13 Feb 2008
Released together with [v4.98](changelog_v4.x.md#498---13-feb-2008)
- Fixed adodb_mktime problem which causes a performance bottleneck in $hrs.
- Added mysqli support to adodb_getcount().
- Removed MYSQLI_TYPE_CHAR from MetaType().
## 5.03 - 22 Jan 2008
Released together with [v4.97](changelog_v4.x.md#497---22-jan-2008)
- Active Record: $ADODB_ASSOC_CASE=1 did not work properly. Fixed.
- Modified Fields() in recordset class to support display null fields in FetchNextObject().
- In ADOdb5, active record implementation, we now support column names with spaces in them - we autoconvert the spaces to _ using __set(). Thx Daniel Cook. http://phplens.com/lens/lensforum/msgs.php?id=17200
- Removed $arg3 from mysqli SelectLimit. See http://phplens.com/lens/lensforum/msgs.php?id=16243. Thx Zsolt Szeberenyi.
- Changed oci8 FetchField, which returns the max_length of BLOB/CLOB/NCLOB as 4000 (incorrectly) to -1.
- CacheExecute would sometimes return an error on Windows if it was unable to lock the cache file. This is harmless and has been changed to a warning that can be ignored. Also adodb_write_file() code revised.
- ADOdb perf code changed to only log sql if execution time >= 0.05 seconds. New $ADODB_PERF_MIN variable holds min sql timing. Any SQL with timing value below this and is not causing an error is not logged.
- Also adodb_backtrace() now traces 1 level deeper as sometimes actual culprit function is not displayed.
- Fixed a group by problem with adodb_getcount() for db's which are not postgres/oci8 based.
- Changed mssql driver Parameter() from SQLCHAR to SQLVARCHAR: case 'string': $type = SQLVARCHAR; break.
- Problem with mssql driver in php5 (for adodb 5.03) because some functions are not static. Fixed.
## 5.02 - 24 Sept 2007
Released together with [v4.96](changelog_v4.x.md#496---24-sept-2007)
- ADOdb perf for oci8 now has non-table-locking code when clearing the sql. Slower but better transparency. Added in 4.96a and 5.02a.
- Fix adodb count optimisation. Preg_match did not work properly. Also rewrote the ORDER BY stripping code in _adodb_getcount(), adodb-lib.inc.php.
- SelectLimit for oci8 not optimal for large recordsets when offset=0. Changed $nrows check.
- Active record optimizations. Added support for assoc arrays in Set().
- Now GetOne returns null if EOF (no records found), and false if error occurs. Use ErrorMsg()/ErrorNo() to get the error.
- Also CacheGetRow and CacheGetCol will return false if error occurs, or empty array() if EOF, just like GetRow and GetCol.
- Datadict now allows changing of types which are not resizable, eg. VARCHAR to TEXT in ChangeTableSQL. -- Mateo Tibaquirá
- Added BIT data type support to adodb-ado.inc.php and adodb-ado5.inc.php.
- Ldap driver did not return actual ldap error messages. Fixed.
- Implemented GetRandRow($sql, $inputarr). Optimized for Oci8.
- Changed adodb5 active record to use static SetDatabaseAdapter() and removed php4 constructor. Bas van Beek bas.vanbeek#gmail.com.
- Also in adodb5, changed adodb-session2 to use static function declarations in class. Thx Daniel Berlin.
- Added "Clear SQL Log" to bottom of Performance screen.
- Sessions2 code echo'ed directly to the screen in debug mode. Now uses ADOConnection::outp().
- In mysql/mysqli, qstr(null) will return the string `null` instead of empty quoted string `''`.
- postgresql optimizeTable in perf-postgres.inc.php added by Daniel Berlin (mail#daniel-berlin.de)
- Added 5.2.1 compat code for oci8.
- Changed @@identity to SCOPE_IDENTITY() for multiple mssql drivers. Thx Stefano Nari.
- Code sanitization introduced in 4.95 caused problems in European locales (as float 3.2 was typecast to 3,2). Now we only sanitize if is_numeric fails.
- Added support for customizing ADORecordset_empty using $this->rsPrefix.'empty'. By Josh Truwin.
- Added proper support for ALterColumnSQL for Postgresql in datadict code. Thx. Josh Truwin.
- Added better support for MetaType() in mysqli when using an array recordset.
- Changed parser for pgsql error messages in adodb-error.inc.php to case-insensitive regex.
## 5.01 - 17 May 2007
Released together with [v4.95](changelog_v4.x.md#495---17-may-2007)
- CacheFlush debug outp() passed in invalid parameters. Fixed.
- Added Thai language file for adodb. Thx Trirat Petchsingh rosskouk#gmail.com and Marcos Pont
- Added zerofill checking support to MetaColumns for mysql and mysqli.
- CacheFlush no longer deletes all files/directories. Only *.cache files deleted.
- DB2 timestamp format changed to `var $fmtTimeStamp = "'Y-m-d-H:i:s'";`
- Added some code sanitization to AutoExecute in adodb-lib.inc.php.
- Due to typo, all connections in adodb-oracle.inc.php would become persistent, even non-persistent ones. Fixed.
- Oci8 DBTimeStamp uses 24 hour time for input now, so you can perform string comparisons between 2 DBTimeStamp values.
- Some PHP4.4 compat issues fixed in adodb-session2.inc.php
- For ADOdb 5.01, fixed some adodb-datadict.inc.php MetaType compat issues with PHP5.
- The $argHostname was wiped out in adodb-ado5.inc.php. Fixed.
- Adodb5 version, added iterator support for adodb_recordset_empty.
- Adodb5 version,more error checking code now will use exceptions if available.
-531
View File
@@ -1,531 +0,0 @@
# ADOdb old Changelog - v2.x and older
See the [Current Changelog](changelog.md).
## 2.91 - 3 Jan 2003
- Revised PHP version checking to use $ADODB_PHPVER with legal values 0x4000, 0x4050, 0x4200, 0x4300.
- Added support for bytea fields and oid blobs in postgres by allowing BlobDecode() to detect and convert non-oid fields. Also added BlobEncode to postgres when you want to encode oid blobs.
- Added blobEncodeType property for connections to inform phpLens what encoding method to use for blobs.
- Added BlobDecode() and BlobEncode() to base ADOConnection class.
- Added umask() to _gencachename() when creating directories.
- Added charPage for ado drivers, so you can set the code page.
```
$conn->charPage = CP_UTF8;
$conn->Connect($dsn);
```
- Modified _seek in mysql to check for num rows=0.
- Added to metatypes new informix types for IDS 9.30\. Thx Fernando Ortiz.
- _maxrecordcount returned in CachePageExecute $rsreturn
- Fixed sybase cacheselectlimit( ) problems
- MetaColumns() max_length should use precision for types X and C for ms access. Fixed.
- Speedup of odbc non-SELECT sql statements.
- Added support in MetaColumns for Wide Char types for ODBC. We halve max_length if unicode/wide char.
- Added 'B' to types handled by GetUpdateSQL/GetInsertSQL.
- Fixed warning message in oci8 driver with $persist variable when using PConnect.
## 2.90 - 11 Dec 2002
- Mssql and mssqlpo and oci8po now support ADODB_ASSOC_CASE.
- Now MetaType() can accept a field object as the first parameter.
- New $arr = $db->ServerInfo( ) function. Returns $arr['description'] which is the string description, and $arr['version'].
- PostgreSQL and MSSQL speedups for insert/updates.
- Implemented new SetFetchMode() that removes the need to use $ADODB_FETCH_MODE. Each connection has independant fetchMode.
- ADODB_ASSOC_CASE now defaults to 2, use native defaults. This is because we would break backward compat for too many applications otherwise.
- Patched encrypted sessions to use replace()
- The qstr function supports quoting of nulls when escape character is \
- Rewrote bits and pieces of session code to check for time synch and improve reliability.
- Added property ADOConnection::hasTransactions = true/false;
- Added CreateSequence and DropSequence functions
- Found misplaced MoveNext() in adodb-postgres.inc.php. Fixed.
- Sybase SelectLimit not reliable because 'set rowcount' not cached - fixed.
- Moved ADOConnection to adodb-connection.inc.php and ADORecordSet to adodb-recordset.inc.php. This allows us to use doxygen to generate documentation. Doxygen doesn't like the classes in the main adodb.inc.php file for some mysterious reason.
## 2.50 - 14 Nov 2002
- Added transOff and transCnt properties for disabling (transOff = true) and tracking transaction status (transCnt>0).
- Added inputarray handling into _adodb_pageexecute_all_rows - "Ross Smith" RossSmith#bnw.com.
- Fixed postgresql inconsistencies in date handling.
- Added support for mssql_fetch_assoc.
- Fixed $ADODB_FETCH_MODE bug in odbc MetaTables() and MetaPrimaryKeys().
- Accidentally declared UnixDate() twice, making adodb incompatible with php 4.3.0\. Fixed.
- Fixed pager problems with some databases that returned -1 for _currentRow on MoveLast() by switching to MoveNext() in adodb-lib.inc.php.
- Also fixed uninited $discard in adodb-lib.inc.php.
## 2.43 - 25 Oct 2002
- Added ADODB_ASSOC_CASE constant to better support ibase and odbc field names.
- Added support for NConnect() for oracle OCINLogin.
- Fixed NumCols() bug.
- Changed session handler to use Replace() on write.
- Fixed oci8 SelectLimit aggregate function bug again.
- Rewrote pivoting code.
## 2.42 - 4 Oct 2002
- Fixed ibase_fetch() problem with nulls. Also interbase now does automatic blob decoding, and is backward compatible. Suggested by Heinz Hombergs heinz#hhombergs.de.
- Fixed postgresql MoveNext() problems when called repeatedly after EOF. Also suggested by Heinz Hombergs.
- PageExecute() does not rewrite queries if SELECT DISTINCT is used. Requested by hans#velum.net
- Added additional fixes to oci8 SelectLimit handling with aggregate functions - thx to Christian Bugge for reporting the problem.
## 2.41 - 2 Oct 2002
- Fixed ADODB_COUNTRECS bug in odbc. Thx to Joshua Zoshi jzoshi#hotmail.com.
- Increased buffers for adodb-csvlib.inc.php for extremely long sql from 8192 to 32000.
- Revised pivottable.inc.php code. Added better support for aggregate fields.
- Fixed mysql text/blob types problem in MetaTypes base class - thx to horacio degiorgi.
- Added SQLDate($fmt,$date) function, which allows an sql date format string to be generated - useful for group by's.
- Fixed bug in oci8 SelectLimit when offset>100.
## 2.40 - 4 Sept 2002
- Added new NLS_DATE_FORMAT property to oci8\. Suggested by Laurent NAVARRO ln#altidev.com
- Now use bind parameters in oci8 selectlimit for better performance.
- Fixed interbase replaceQuote for dialect != 1\. Thx to "BEGUIN Pierre-Henri - INFOCOB" phb#infocob.com.
- Added white-space check to QA.
- Changed unixtimestamp to support fractional seconds (we always round down/floor the seconds). Thanks to beezly#beezly.org.uk.
- Now you can set the trigger_error type your own user-defined type in adodb-errorhandler.inc.php. Suggested by Claudio Bustos clbustos#entelchile.net.
- Added recordset filters with rsfilter.inc.php.
$conn->_rs2rs does not create a new recordset when it detects it is of type array. Some trickery there as there seems to be a bug in Zend Engine
- Added render_pagelinks to adodb-pager.inc.php. Code by "Pablo Costa" pablo#cbsp.com.br.
- MetaType() speedup in adodb.inc.php by using hashing instead of switch. Best performance if constant arrays are supported, as they are in PHP5.
- adodb-session.php now updates only the expiry date if the crc32 check indicates that the data has not been modified.
## 2.31 - 20 Aug 2002
- Made changes to pivottable.inc.php due to daniel lucuzaeu's suggestions (we sum the pivottable column if desired).
- Fixed ErrorNo() in postgres so it does not depend on _errorMsg property.
- Robert Tuttle added support for oracle cursors. See ExecuteCursor().
- Fixed Replace() so it works with mysql when updating record where data has not changed. Reported by Cal Evans (cal#calevans.com).
## 2.30 - 1 Aug 2002
- Added pivottable.inc.php. Thanks to daniel.lucazeau#ajornet.com for the original concept.
- Added ADOConnection::outp($msg,$newline) to output error and debugging messages. Now you can override this using the ADODB_OUTP constant and use your own output handler.
- Changed == to === for 'null' comparison. Reported by ericquil#yahoo.com
- Fixed mssql SelectLimit( ) bug when distinct used.
## 2.30 - 1 Aug 2002
- New GetCol() and CacheGetCol() from ross#bnw.com that returns the first field as a 1 dim array.
- We have an empty recordset, but RecordCount() could return -1\. Fixed. Reported by "Jonathan Polansky" jonathan#polansky.com.
- We now check for session variable changes using strlen($sessval).crc32($sessval). Formerly we only used crc32().
- Informix SelectLimit() problem with $ADODB_COUNTRECS fixed.
- Fixed informix SELECT FIRST x DISTINCT, and not SELECT DISTINCT FIRST x - reported by F Riosa
- Now default adodb error handlers ignores error if @ used.
- If you set $conn->autoRollback=true, we auto-rollback persistent connections for odbc, mysql, oci8, mssql. Default for autoRollback is false. No need to do so for postgres. As interbase requires a transaction id (what a flawed api), we don't do it for interbase.
- Changed PageExecute() to use non-greedy preg_match when searching for "FROM" keyword.
## 2.20 - 9 July 2002
- Added CacheGetOne($secs2cache,$sql), CacheGetRow($secs2cache,$sql), CacheGetAll($secs2cache,$sql).
- Added $conn->OffsetDate($dayFraction,$date=false) to generate sql that calcs date offsets. Useful for scheduling appointments.
- Added connection properties: leftOuter, rightOuter that hold left and right outer join operators.
- Added connection property: ansiOuter to indicate whether ansi outer joins supported.
- New driver _mssqlpo_, the portable mssql driver, which converts string concat operator from || to +.
- Fixed ms access bug - SelectLimit() did not support ties - fixed.
- Karsten Kraus (Karsten.Kraus#web.de), contributed error-handling code to ADONewConnection. Unfortunately due to backward compat problems, had to rollback most of the changes.
- Added new parameter to GetAssoc() to allow returning an array of key-value pairs, ignoring any additional columns in the recordset. Off by default.
- Corrected mssql $conn->sysDate to return only date using convert().
- CacheExecute() improved debugging output.
- Changed rs2html() so newlines are converted to BR tags. Also optimized rs2html() based on feedback by "Jerry Workman" jerry#mtncad.com.
- Added support for Replace() with Interbase, using DELETE and INSERT.
- Some minor optimizations (mostly removing & references when passing arrays).
- Changed GenID() to allows id's larger than the size of an integer.
- Added force_session property to oci8 for better updateblob() support.
- Fixed PageExecute() which did not work properly with sql containing GROUP BY.
## 2.12 - 12 June 2002
- Added toexport.inc.php to export recordsets in CSV and tab-delimited format.
- CachePageExecute() does not work - fixed - thx John Huong.
- Interbase aliases not set properly in FetchField() - fixed. Thx Stefan Goethals.
- Added cache property to adodb pager class. The number of secs to cache recordsets.
- SQL rewriting bug in pageexecute() due to skipping of newlines due to missing /s modifier. Fixed.
- Max size of cached recordset due to a bug was 256000 bytes. Fixed.
- Speedup of 1st invocation of CacheExecute() by tuning code.
- We compare $rewritesql with $sql in pageexecute code in case of rewrite failure.
## 2.11 - 7 June 2002
- Fixed PageExecute() rewrite sql problem - COUNT(*) and ORDER BY don't go together with mssql, access and postgres. Thx to Alexander Zhukov alex#unipack.ru
- DB2 support for CHARACTER type added - thx John Huong huongch#bigfoot.com
- For ado, $argProvider not properly checked. Fixed - kalimero#ngi.it
- Added $conn->Replace() function for update with automatic insert if the record does not exist. Supported by all databases except interbase.
## 2.10 - 4 June 2002
- Added uniqueSort property to indicate mssql ORDER BY cols must be unique.
- Optimized session handler by crc32 the data. We only write if session data has changed.
- adodb_sess_read in adodb-session.php now returns ''correctly - thanks to Jorma Tuomainen, webmaster#wizactive.com
- Mssql driver did not throw EXECUTE errors correctly because ErrorMsg() and ErrorNo() called in wrong order. Pointed out by Alexios Fakos. Fixed.
- Changed ado to use client cursors. This fixes BeginTran() problems with ado.
- Added handling of timestamp type in ado.
- Added to ado_mssql support for insert_id() and affected_rows().
- Added support for mssql.datetimeconvert=0, available since php 4.2.0.
- Made UnixDate() less strict, so that the time is ignored if present.
- Changed quote() so that it checks for magic_quotes_gpc.
- Changed maxblobsize for odbc to default to 64000.
## 2.00 - 13 May 2002
- Added drivers _informix72_ for pre-7.3 versions, and _oci805_ for oracle 8.0.5, and postgres64 for postgresql 6.4 and earlier. The postgres and postgres7 drivers are now identical.
- Interbase now partially supports ADODB_FETCH_BOTH, by defaulting to ASSOC mode.
- Proper support for blobs in mssql. Also revised blob support code is base class. Now UpdateBlobFile() calls UpdateBlob() for consistency.
- Added support for changed odbc_fetch_into api in php 4.2.0 with $conn->_has_stupid_odbc_fetch_api_change.
- Fixed spelling of tablock locking hint in GenID( ) for mssql.
- Added RowLock( ) to several databases, including oci8, informix, sybase, etc. Fixed where error in mssql RowLock().
- Added sysDate and sysTimeStamp properties to most database drivers. These are the sql functions/constants for that database that return the current date and current timestamp, and are useful for portable inserts and updates.
- Support for RecordCount() caused date handling in sybase and mssql to break. Fixed, thanks to Toni Tunkkari, by creating derived classes for ADORecordSet_array for both databases. Generalized using arrayClass property. Also to support RecordCount(), changed metatype handling for ado drivers. Now the type returned in FetchField is no longer a number, but the 1-char data type returned by MetaType. At the same time, fixed a lot of date handling. Now mssql support dmy and mdy date formats. Also speedups in sybase and mssql with preg_match and ^ in date/timestamp handling. Added support in sybase and mssql for 24 hour clock in timestamps (no AM/PM).
- Extensive revisions to informix driver - thanks to Samuel CARRIERE samuel_carriere#hotmail.com
- Added $ok parameter to CommitTrans($ok) for easy rollbacks.
- Fixed odbc MetaColumns and MetaTables to save and restore $ADODB_FETCH_MODE.
- Some odbc drivers did not call the base connection class constructor. Fixed.
- Fixed regex for GetUpdateSQL() and GetInsertSQL() to support more legal character combinations.
## 1.99 - 21 April 2002
- Added emulated RecordCount() to all database drivers if $ADODB_COUNTRECS = true (which it is by default). Inspired by Cristiano Duarte (cunha17#uol.com.br).
- Unified stored procedure support for mssql and oci8\. Parameter() and PrepareSP() functions implemented.
- Added support for SELECT FIRST in informix, modified hasTop property to support this.
- Changed csv driver to handle updates/deletes/inserts properly (when Execute() returns true). Bind params also work now, and raiseErrorFn with csv driver. Added csv driver to QA process.
- Better error checking in oci8 UpdateBlob() and UpdateBlobFile().
- Added TIME type to MySQL - patch by Manfred h9125297#zechine.wu-wien.ac.at
- Prepare/Execute implemented for Interbase/Firebird
- Changed some regular expressions to be anchored by /^ $/ for speed.
- Added UnixTimeStamp() and UnixDate() to ADOConnection(). Now these functions are in both ADOConnection and ADORecordSet classes.
- Empty recordsets were not cached - fixed.
- Thanks to Gaetano Giunta (g.giunta#libero.it) for the oci8 code review. We didn't agree on everything, but i hoped we agreed to disagree!
## 1.90 - 6 April 2002
- Now all database drivers support fetch modes ADODB_FETCH_NUM and ADODB_FETCH_ASSOC, though still not fully tested. Eg. Frontbase, Sybase, Informix.
- NextRecordSet() support for mssql. Contributed by "Sven Axelsson" sven.axelsson#bokochwebb.se
- Added blob support for SQL Anywhere. Contributed by Wade Johnson wade#wadejohnson.de
- Fixed some security loopholes in server.php. Server.php also supports fetch mode.
- Generalized GenID() to support odbc and mssql drivers. Mssql no longer generates GUID's.
- Experimental RowLock($table,$where) for mssql.
- Properly implemented Prepare() in oci8 and ODBC.
- Added Bind() support to oci8 to support Prepare().
- Improved error handler. Catches CacheExecute() and GenID() errors now.
- Now if you are running php from the command line, debugging messages do not output html formating. Not 100% complete, but getting there.
## 1.81 - 22 March 2002
- Restored default $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT for backward compatibility.
- SelectLimit for oci8 improved - Our FIRST_ROWS optimization now does not overwrite existing hint.
- New Sybase SQL Anywhere driver. Contributed by Wade Johnson wade#wadejohnson.de
## 1.80 - 15 March 2002
- Redesigned directory structure of ADOdb files. Added new driver directory where all database drivers reside.
- Changed caching algorithm to create subdirectories. Now we scale better.
- Informix driver now supports insert_id(). Contribution by "Andrea Pinnisi" pinnisi#sysnet.it
- Added experimental ISO date and FetchField support for informix.
- Fixed a quoting bug in Execute() with bind parameters, causing problems with blobs.
- Mssql driver speedup by 10-15%.
- Now in CacheExecute($secs2cache,$sql,...), $secs2cache is optional. If missing, it will take the value defined in $connection->cacheSecs (default is 3600 seconds). Note that CacheSelectLimit(), the secs2cache is still compulsory - sigh.
- Sybase SQL Anywhere driver (using ODBC) contributed by Wade Johnson wade#wadejohnson.de
## 1.72 - 8 March 2002
- Added @ when returning Fields() to prevent spurious error - "Michael William Miller" mille562#pilot.msu.edu
- MetaDatabases() for postgres contributed by Phil pamelant#nerim.net
- Mitchell T. Young (mitch#youngfamily.org) contributed informix driver.
- Fixed rs2html() problem. I cannot reproduce, so probably a problem with pre PHP 4.1.0 versions, when supporting new ADODB_FETCH_MODEs.
- Mattia Rossi (mattia#technologist.com) contributed BlobDecode() and UpdateBlobFile() for postgresql using the postgres specific pg_lo_import()/pg_lo_open() - i don't use them but hopefully others will find this useful. See [this posting](http://phplens.com/lens/lensforum/msgs.php?id=1262) for an example of usage.
- Added UpdateBlobFile() for uploading files to a database.
- Made UpdateBlob() compatible with oci8po driver.
- Added noNullStrings support to oci8 driver. Oracle changes all ' ' strings to nulls, so you need to set strings to ' ' to prevent the nullifying of strings. $conn->noNullStrings = true; will do this for you automatically. This is useful when you define a char column as NOT NULL.
- Fixed UnixTimeStamp() bug - wasn't setting minutes and seconds properly. Patch from Agusti Fita i Borrell agusti#anglatecnic.com.
- Toni Tunkkari added patch for sybase dates. Problem with spaces in day part of date fixed.
## 1.71 - 18 Jan 2002
- Sequence start id support. Now $conn->Gen_ID('seqname', 50) to start sequence from 50.
- CSV driver fix for selectlimit, from Andreas - akaiser#vocote.de.
- Gam3r spotted that a global variable was undefined in the session handler.
- Mssql date regex had error. Fixed - reported by Minh Hoang vb_user#yahoo.com.
- DBTimeStamp() and DBDate() now accept iso dates and unix timestamps. This means that the PostgreSQL handling of dates in GetInsertSQL() and GetUpdateSQL() can be removed. Also if these functions are passed '' or null or false, we return a SQL null.
- GetInsertSQL() and GetUpdateSQL() now accept a new parameter, $magicq to indicate whether quotes should be inserted based on magic quote settings - suggested by dj#4ict.com.
- Reformated docs slightly based on suggestions by Chris Small.
## 1.65 - 28 Dec 2001
- Fixed borland_ibase class naming bug.
- Now instead of using $rs->fields[0] internally, we use reset($rs->fields) so that we are compatible with ADODB_FETCH_ASSOC mode. Reported by Nico S.
- Changed recordset constructor and _initrs() for oci8 so that it returns the field definitions even if no rows in the recordset. Reported by Rick Hickerson (rhickers#mv.mv.com).
- Improved support for postgresql in GetInsertSQL and GetUpdateSQL by "mike" mike#partner2partner.com and "Ryan Bailey" rebel#windriders.com
## 1.64 - 20 Dec 2001
- Danny Milosavljevic <danny.milo#gmx.net> added some patches for MySQL error handling and displaying default values.
- Fixed some ADODB_FETCH_BOTH inconsistencies in odbc and interbase.
- Added more tests to test suite to cover ADODB_FETCH_* and ADODB_ERROR_HANDLER.
- Added firebird (ibase) driver
- Added borland_ibase driver for interbase 6.5
## 1.63 - 13 Dec 2001
- Absolute to the adodb-lib.inc.php file not set properly. Fixed.
## 1.62 - 11 Dec 2001
- Major speedup of ADOdb for low-end web sites by reducing the php code loading and compiling cycle. We conditionally compile not so common functions. Moved csv code to adodb-csvlib.inc.php to reduce adodb.inc.php parsing. This file is loaded only when the csv/proxy driver is used, or CacheExecute() is run. Also moved PageExecute(), GetSelectSQL() and GetUpdateSQL() core code to adodb-lib.inc.php. This reduced the 70K main adodb.inc.php file to 55K, and since at least 20K of the file is comments, we have reduced 50K of code in adodb.inc.php to 35K. There should be 35% reduction in memory and thus 35% speedup in compiling the php code for the main adodb.inc.php file.
- Highly tuned SelectLimit() for oci8 for massive speed improvements on large files. Selecting 20 rows starting from the 20,000th row of a table is now 7 times faster. Thx to Tomas V V Cox.
- Allow . and # in table definitions in GetInsertSQL and GetUpdateSQL. See ADODB_TABLE_REGEX constant. Thx to Ari Kuorikoski.
- Added ADODB_PREFETCH_ROWS constant, defaulting to 10\. This determines the number of records to prefetch in a SELECT statement. Only used by oci8.
- Added high portability Oracle class called oci8po. This uses ? for bind variables, and lower cases column names.
- Now all database drivers support $ADODB_FETCH_MODE, including interbase, ado, and odbc: ADODB_FETCH_NUM and ADODB_FETCH_ASSOC. ADODB_FETCH_BOTH is not fully implemented for all database drivers.
## 1.61 - Nov 2001
- Added PO_RecordCount() and PO_Insert_ID(). PO stands for portable. Pablo Roca [pabloroca#mvps.org]
- GenID now returns 0 if not available. Safer is that you should check $conn->hasGenID for availability.
- M'soft ADO we now correctly close recordset in _close() peterd#telephonetics.co.uk
- MSSQL now supports GenID(). It generates a 16-byte GUID from mssql newid() function.
- Changed ereg_replace to preg_replace in SelectLimit. This is a fix for mssql. Ereg doesn't support t or n! Reported by marino Carlos xaplo#postnuke-espanol.org
- Added $recordset->connection. This is the ADOConnection object for the recordset. Works with cached and normal recordsets. Surprisingly, this had no affect on performance!
## 1.54 - 15 Nov 2001
- Fixed some more bugs in PageExecute(). I am getting sick of bug in this and will have to reconsider my QA here. The main issue is that I don't use PageExecute() and to check whether it is working requires a visual inspection of the html generated currently. It is possible to write a test script but it would be quite complicated :(
- More speedups of SelectLimit() for DB2, Oci8, access, vfp, mssql.
## 1.53 - 7 Nov 2001
- Added support for ADODB_FETCH_ASSOC for ado and odbc drivers.
- Tuned GetRowAssoc(false) in postgresql and mysql.
- Stephen Van Dyke contributed ADOdb icon, accepted with some minor mods.
- Enabled Affected_Rows() for postgresql
- Speedup for Concat() using implode() - Benjamin Curtis ben_curtis#yahoo.com
- Fixed some more bugs in PageExecute() to prevent infinite loops
## 1.52 - 5 Nov 2001
- Spelling error in CacheExecute() caused it to fail. $ql should be $sql in line 625!
- Added fixes for parsing [ and ] in GetUpdateSQL().
## 1.51 - 5 Nov 2001
- Oci8 SelectLimit() speedup by using OCIFetch().
- Oci8 was mistakenly reporting errors when $db->debug = true.
- If a connection failed with ODBC, it was not correctly reported - fixed.
- _connectionID was inited to -1, changed to false.
- Added $rs->FetchRow(), to simplify API, ala PEAR DB
- Added PEAR DB compat mode, which is still faster than PEAR! See adodb-pear.inc.php.
- Removed postgres pconnect debugging statement.
## 1.50 - 31 Oct 2001
- ADOdbConnection renamed to ADOConnection, and ADOdbFieldObject to ADOFieldObject.
- PageExecute() now checks for empty $rs correctly, and the errors in the docs on this subject have been fixed.
- odbc_error() does not return 6 digit error correctly at times. Implemented workaround.
- Added ADORecordSet_empty class. This will speedup INSERTS/DELETES/UPDATES because the return object created is much smaller.
- Added Prepare() to odbc, and oci8 (but doesn't work properly for oci8 still).
- Made pgsql a synonym for postgre7, and changed SELECT LIMIT to use OFFSET for compat with postgres 7.2.
- Revised adodb-cryptsession.php thanks to Ari.
- Set resources to false on _close, to force freeing of resources.
- Added adodb-errorhandler.inc.php, adodb-errorpear.inc.php and raiseErrorFn on Freek's urging.
- GetRowAssoc($toUpper=true): $toUpper added as default.
- Errors when connecting to a database were not captured formerly. Now we do it correctly.
## 1.40 - 19 September 2001
- PageExecute() to implement page scrolling added. Code and idea by Iván Oliva.
- Some minor postgresql fixes.
- Added sequence support using GenID() for postgresql, oci8, mysql, interbase.
- Added UpdateBlob support for interbase (untested).
- Added encrypted sessions (see adodb-cryptsession.php). By Ari Kuorikoski <kuoriari#finebyte.com>
## 1.31 - 21 August 2001
- Many bug fixes thanks to "GaM3R (Cameron)" <gamr#outworld.cx>. Some session changes due to Gam3r.
- Fixed qstr() to quote also.
- rs2html() now pretty printed.
- Jonathan Younger <jyounger#unilab.com> contributed the great idea GetUpdateSQL() and GetInsertSQL() which generates SQL to update and insert into a table from a recordset. Modify the recordset fields array, then can this function to generate the SQL (the SQL is not executed).
- Nicola Fankhauser <nicola.fankhauser#couniq.com> found some bugs in date handling for mssql.
- Added minimal Oracle support for LOBs. Still under development.
- Added $ADODB_FETCH_MODE so you can control whether recordsets return arrays which are numeric, associative or both. This is a global variable you set. Currently only MySQL, Oci8, Postgres drivers support this.
- PostgreSQL properly closes recordsets now. Reported by several people.
- Added UpdateBlob() for Oracle. A hack to make it easier to save blobs.
- Oracle timestamps did not display properly. Fixed.
## 1.20 - 6 June 2001
- Now Oracle can connect using tnsnames.ora or server and service name
- Extensive Oci8 speed optimizations. Oci8 code revised to support variable binding, and /*+ FIRST_ROWS */ hint.
- Worked around some 4.0.6 bugs in odbc_fetch_into().
- Paolo S. Asioli paolo.asioli#libero.it suggested GetRowAssoc().
- Escape quotes for oracle wrongly set to '. Now '' is used.
- Variable binding now works in ODBC also.
- Jumped to version 1.20 because I don't like 13 :-)
## 1.12 - 6 June 2001
- Changed $ADODB_DIR to ADODB_DIR constant to plug a security loophole.
- Changed _close() to close persistent connections also. Prevents connection leaks.
- Major revision of oracle and oci8 drivers. Added OCI_RETURN_NULLS and OCI_RETURN_LOBS to OCIFetchInto(). BLOB, CLOB and VARCHAR2 recognition in MetaType() improved. MetaColumns() returns columns in correct sort order.
- Interbase timestamp input format was wrong. Fixed.
## 1.11 - 20 May 2001
- Improved file locking for Windows.
- Probabilistic flushing of cache to avoid avalanche updates when cache timeouts.
- Cached recordset timestamp not saved in some scenarios. Fixed.
## 1.10 - 19 May 2001
- Added caching. CacheExecute() and CacheSelectLimit().
- Added csv driver. See [http://php.weblogs.com/ADODB_csv](http://php.weblogs.com/adodb_csv).
- Fixed SelectLimit(), SELECT TOP not working under certain circumstances.
- Added better Frontbase support of MetaTypes() by Frank M. Kromann.
## 1.01 - 24 April 2001
- Fixed SelectLimit bug. not quoted properly.
- SelectLimit: SELECT TOP -1 * FROM TABLE not support by Microsoft. Fixed.
- GetMenu improved by glen.davies#cce.ac.nz to support multiple hilited items
- FetchNextObject() did not work with only 1 record returned. Fixed bug reported by $tim#orotech.net
- Fixed mysql field max_length problem. Fix suggested by Jim Nicholson (jnich#att.com)
## 1.00 - 16 April 2001
- Given some brilliant suggestions on how to simplify ADOdb by akul. You no longer need to setup $ADODB_DIR yourself, and ADOLoadCode() is automatically called by ADONewConnection(), simplifying the startup code.
- FetchNextObject() added. Suggested by Jakub Marecek. This makes FetchObject() obsolete, as this is more flexible and powerful.
- Misc fixes to SelectLimit() to support Access (top must follow distinct) and Fields() in the array recordset. From Reinhard Balling.
## 0.96 - 27 Mar 2001
- ADOConnection Close() did not return a value correctly. Thanks to akul#otamedia.com.
- When the horrible magic_quotes is enabled, back-slash () is changed to double-backslash (\). This doesn't make sense for Microsoft/Sybase databases. We fix this in qstr().
- Fixed Sybase date problem in UnixDate() thanks to Toni Tunkkari. Also fixed MSSQL problem in UnixDate() - thanks to milhouse31#hotmail.com.
- MoveNext() moved to leaf classes for speed in MySQL/PostgreSQL. 10-15% speedup.
- Added null handling in bindInputArray in Execute() -- Ron Baldwin suggestion.
- Fixed some option tags. Thanks to john#jrmstudios.com.
## 0.95 - 13 Mar 2001
- Added postgres7 database driver which supports LIMIT and other version 7 stuff in the future.
- Added SelectLimit to ADOConnection to simulate PostgreSQL's "select * from table limit 10 offset 3". Added helper function GetArrayLimit() to ADORecordSet.
- Fixed mysql metacolumns bug. Thanks to Freek Dijkstra (phpeverywhere#macfreek.com).
- Also many PostgreSQL changes by Freek. He almost rewrote the whole PostgreSQL driver!
- Added fix to input parameters in Execute for non-strings by Ron Baldwin.
- Added new metatype, X for TeXt. Formerly, metatype B for Blob also included text fields. Now 'B' is for binary/image data. 'X' for textual data.
- Fixed $this->GetArray() in GetRows().
- Oracle and OCI8: 1st parameter is always blank -- now warns if it is filled.
- Now _hasLimit_ and _hasTop_ added to indicate whether SELECT * FROM TABLE LIMIT 10 or SELECT TOP 10 * FROM TABLE are supported.
## 0.94 - 04 Feb 2001
- Added ADORecordSet::GetRows() for compatibility with Microsoft ADO. Synonym for GetArray().
- Added new metatype 'R' to represent autoincrement numbers.
- Added ADORecordSet.FetchObject() to return a row as an object.
- Finally got a Linux box to test PostgreSql. Many fixes.
- Fixed copyright misspellings in 0.93.
- Fixed mssql MetaColumns type bug.
- Worked around odbc bug in PHP4 for sessions.
- Fixed many documentation bugs (affected_rows, metadatabases, qstr).
- Fixed MySQL timestamp format (removed comma).
- Interbase driver did not call ibase_pconnect(). Fixed.
## 0.93 - 18 Jan 2002
- Fixed GetMenu bug.
- Simplified Interbase commit and rollback.
- Default behaviour on closing a connection is now to rollback all active transactions.
- Added field object handling for array recordset for future XML compatibility.
- Added arr2html() to convert array to html table.
## 0.92 - 2 Jan 2002
- Interbase Commit and Rollback should be working again.
- Changed initialisation of ADORecordSet. This is internal and should not affect users. We are doing this to support cached recordsets in the future.
- Implemented ADORecordSet_array class. This allows you to simulate a database recordset with an array.
- Added UnixDate() and UnixTimeStamp() to ADORecordSet.
## 0.91 - 21 Dec 2000
- Fixed ODBC so ErrorMsg() is working.
- Worked around ADO unrecognised null (0x1) value problem in COM.
- Added Sybase support for FetchField() type
- Removed debugging code and unneeded html from various files
- Changed to javadoc style comments to adodb.inc.php.
- Added maxsql as synonym for mysqlt
- Now ODBC downloads first 8K of blob by default
## 0.90 - 15 Nov 2000
- Lots of testing of Microsoft ADO. Should be more stable now.
- Added $ADODB_COUNTREC. Set to false for high speed selects.
- Added Sybase support. Contributed by Toni Tunkkari (toni.tunkkari#finebyte.com). Bug in Sybase API: GetFields is unable to determine date types.
- Changed behaviour of RecordSet.GetMenu() to support size parameter (listbox) properly.
- Added emptyDate and emptyTimeStamp to RecordSet class that defines how to represent empty dates.
- Added MetaColumns($table) that returns an array of ADOFieldObject's listing the columns of a table.
- Added transaction support for PostgresSQL -- thanks to "Eric G. Werk" egw#netguide.dk.
- Added adodb-session.php for session support.
## 0.80 - 30 Nov 2000
- Added support for charSet for interbase. Implemented MetaTables for most databases. PostgreSQL more extensively tested.
## 0.71 - 22 Nov 2000
- Switched from using require_once to include/include_once for backward compatability with PHP 4.02 and earlier.
## 0.70 - 15 Nov 2000
- Calls by reference have been removed (call_time_pass_reference=Off) to ensure compatibility with future versions of PHP, except in Oracle 7 driver due to a bug in php_oracle.dll.
- PostgreSQL database driver contributed by Alberto Cerezal (acerezalp#dbnet.es).
- Oci8 driver for Oracle 8 contributed by George Fourlanos (fou#infomap.gr).
- Added _mysqlt_ database driver to support MySQL 3.23 which has transaction support.
- Oracle default date format (DD-MON-YY) did not match ADOdb default date format (which is YYYY-MM-DD). Use ALTER SESSION to force the default date.
- Error message checking is now included in test suite.
- MoveNext() did not check EOF properly -- fixed.
## 0.60 - 8 Nov 2000
- Fixed some constructor bugs in ODBC and ADO. Added ErrorNo function to ADOConnection class.
## 0.51 - 18 Oct 2000
- Fixed some interbase bugs.
## 0.50 - 16 Oct 2000
- Interbase commit/rollback changed to be compatible with PHP 4.03\.
- CommitTrans( ) will now return true if transactions not supported.
- Conversely RollbackTrans( ) will return false if transactions not supported.
## 0.46 - 12 Oct 2000
- Many Oracle compatibility issues fixed.
## 0.40 - 26 Sept 2000
- Many bug fixes
- Now Code for BeginTrans, CommitTrans and RollbackTrans is working. So is the Affected_Rows and Insert_ID. Added above functions to test.php.
- ADO type handling was busted in 0.30\. Fixed.
- Generalised Move( ) so it works will all databases, including ODBC.
## 0.30 - 18 Sept 2000
- Renamed ADOLoadDB to ADOLoadCode. This is clearer.
- Added BeginTrans, CommitTrans and RollbackTrans functions.
- Added Affected_Rows() and Insert_ID(), _affectedrows() and _insertID(), ListTables(), ListDatabases(), ListColumns().
- Need to add New_ID() and hasInsertID and hasAffectedRows, autoCommit
## 0.20 - 12 Sept 2000
- Added support for Microsoft's ADO.
- Added new field to ADORecordSet -- canSeek
- Added new parameter to _fetch($ignore_fields = false). Setting to true will not update fields array for faster performance.
- Added new field to ADORecordSet/ADOConnection -- dataProvider to indicate whether a class is derived from odbc or ado.
- Changed class ODBCFieldObject to ADOFieldObject -- not documented currently.
- Added benchmark.php and testdatabases.inc.php to the test suite.
- Added to ADORecordSet FastForward( ) for future high speed scrolling. Not documented.
- Realised that ADO's Move( ) uses relative positioning. ADOdb uses absolute.
## 0.10 - 9 Sept 2000
- First release
-242
View File
@@ -1,242 +0,0 @@
# ADOdb old Changelog - v3.x
See the [Current Changelog](changelog.md).
Older changelogs:
[v2.x](changelog_v2.x.md).
## 3.94 - 11 Oct 2003
- Create trigger in datadict-oci8.inc.php did not work, because all cr/lf's must be removed.
- ErrorMsg()/ErrorNo() did not work for many databases when logging enabled. Fixed.
- Removed global variable $ADODB_LOGSQL as it does not work properly with multiple connections.
- Added SQLDate support for sybase. Thx to Chris Phillipson
- Postgresql checking of pgsql resultset resource was incorrect. Fix by Bharat Mediratta bharat#menalto.com. Same patch applied to _insertid and _affectedrows for adodb-postgres64.inc.php.
- Added support for NConnect for postgresql.
- Added Sybase data dict support. Thx to Chris Phillipson
- Extensive improvements in $perf->UI(), eg. Explain now opens in new window, we show scripts which call sql, etc.
- Perf Monitor UI works with magic quotes enabled.
- rsPrefix was declared twice. Removed.
- Oci8 stored procedure support, eg. "begin func(); end;" was incorrect in _query. Fixed.
- Tiraboschi Massimiliano contributed italian language file.
- Fernando Ortiz, fortiz#lacorona.com.mx, contributed informix performance monitor.
- Added _varchar (varchar arrays) support for postgresql. Reported by PREVOT Stéphane.
## 3.92 - 22 Sept 2003
- Added GetAssoc and CacheGetAssoc to connection object.
- Removed TextMax and CharMax functions from adodb.inc.php.
- HasFailedTrans() returned false when trans failed. Fixed.
- Moved perf driver classes into adodb/perf/*.php.
- Misc improvements to performance monitoring, including UI().
- RETVAL in mssql Parameter(), we do not append @ now.
- Added Param($name) to connection class, returns '?' or ":$name", for defining bind parameters portably.
- LogSQL traps affected_rows() and saves its value properly now. Also fixed oci8 _stmt and _affectedrows() bugs.
- Session code timestamp check for oci8 works now. Formerly default NLS_DATE_FORMAT stripped off time portion. Thx to Tony Blair (tonanbarbarian#hotmail.com). Also added new $conn->datetime field to oci8, controls whether MetaType() returns 'D' ($this->datetime==false) or 'T' ($this->datetime == true) for DATE type.
- Fixed bugs in adodb-cryptsession.inc.php and adodb-session-clob.inc.php.
- Fixed misc bugs in adodb_key_exists, GetInsertSQL() and GetUpdateSQL().
- Tuned include_once handling to reduce file-system checking overhead.
## 3.91 - 9 Sept 2003
- Only released to InterAkt
- Added LogSQL() for sql logging and $ADODB_NEWCONNECTION to override factory for driver instantiation.
- Added IfNull($field,$ifNull) function, thx to johnwilk#juno.com
- Added portable substr support.
- Now rs2html() has new parameter, $echo. Set to false to return $html instead of echoing it.
## 3.90 - 5 Sept 2003
- First beta of performance monitoring released.
- MySQL supports MetaTable() masking.
- Fixed key_exists() bug in adodb-lib.inc.php
- Added sp_executesql Prepare() support to mssql.
- Added bind support to db2.
- Added swedish language file - Christian Tiberg" christian#commsoft.nu
- Bug in drop index for mssql data dict fixed. Thx to Gert-Rainer Bitterlich.
- Left join setting for oci8 was wrong. Thx to johnwilk#juno.com
## 3.80 - 27 Aug 2003
- Patch for PHP 4.3.3 cached recordset csv2rs() fread loop incompatibility.
- Added matching mask for MetaTables. Only for oci8, mssql and postgres currently.
- Rewrite of "oracle" driver connection code, merging with "oci8", by Gaetano.
- Added better debugging for Smart Transactions.
- Postgres DBTimeStamp() was wrongly using TO_DATE. Changed to TO_TIMESTAMP.
- ADODB_FETCH_CASE check pushed to ADONewConnection to allow people to define it after including adodb.inc.php.
- Added portugese (brazilian) to languages. Thx to "Levi Fukumori".
- Removed arg3 parameter from Execute/SelectLimit/Cache* functions.
- Execute() now accepts 2-d array as $inputarray. Also changed docs of fnExecute() to note change in sql query counting with 2-d arrays.
- Added MONEY to MetaType in PostgreSQL.
- Added more debugging output to CacheFlush().
## 3.72 - 9 Aug 2003
- Added qmagic($str), which is a qstr($str) that auto-checks for magic quotes and does the right thing...
- Fixed CacheFlush() bug - Thx to martin#gmx.de
- Walt Boring contributed MetaForeignKeys for postgres7.
- _fetch() called _BlobDecode() wrongly in interbase. Fixed.
- adodb_time bug fixed with dates after 2038 fixed by Jason Pell. http://phplens.com/lens/lensforum/msgs.php?id=6980
## 3.71 - 4 Aug 2003
- The oci8 driver, MetaPrimaryKeys() did not check the owner correctly when $owner == false.
- Russian language file contributed by "Cyrill Malevanov" cyrill#malevanov.spb.ru.
- Spanish language file contributed by "Horacio Degiorgi" horaciod#codigophp.com.
- Error handling in oci8 bugfix - if there was an error in Execute(), then when calling ErrorNo() and/or ErrorMsg(), the 1st call would return the error, but the 2nd call would return no error.
- Error handling in odbc bugfix. ODBC would always return the last error, even if it happened 5 queries ago. Now we reset the errormsg to '' and errorno to 0 everytime before CacheExecute() and Execute().
## 3.70 - 29 July 2003
- Added new SQLite driver. Tested on PHP 4.3 and PHP 5.
- Added limited "sapdb" driver support - mainly date support.
- The oci8 driver did not identify NUMBER with no defined precision correctly.
- Added ADODB_FORCE_NULLS, if set, then PHP nulls are converted to SQL nulls in GetInsertSQL/GetUpdateSQL.
- DBDate() and DBTimeStamp() format for postgresql had problems. Fixed.
- Added tableoptions to ChangeTableSQL(). Thx to Mike Benoit.
- Added charset support to postgresql. Thx to Julian Tarkhanov.
- Changed OS check for MS-Windows to prevent confusion with darWIN (MacOS)
- Timestamp format for db2 was wrong. Changed to yyyy-mm-dd-hh.mm.ss.nnnnnn.
- adodb-cryptsession.php includes wrong. Fixed.
- Added MetaForeignKeys(). Supported by mssql, odbc_mssql and oci8.
- Fixed some oci8 MetaColumns/MetaPrimaryKeys bugs. Thx to Walt Boring.
- adodb_getcount() did not init qryRecs to 0\. Missing "WHERE" clause checking in GetUpdateSQL fixed. Thx to Sebastiaan van Stijn.
- Added support for only 'VIEWS' and "TABLES" in MetaTables. From Walt Boring.
- Upgraded to adodb-xmlschema.inc.php 0.0.2.
- NConnect for mysql now returns value. Thx to Dennis Verspuij.
- ADODB_FETCH_BOTH support added to interbase/firebird.
- Czech language file contributed by Kamil Jakubovic jake#host.sk.
- PostgreSQL BlobDecode did not use _connectionID properly. Thx to Juraj Chlebec.
- Added some new initialization stuff for Informix. Thx to "Andrea Pinnisi" pinnisi#sysnet.it
- ADODB_ASSOC_CASE constant wrong in sybase _fetch(). Fixed.
## 3.60 - 16 June 2003
- We now SET CONCAT_NULL_YIELDS_NULL OFF for odbc_mssql driver to be compat with mssql driver.
- The property $emptyDate missing from connection class. Also changed 1903 to constant (TIMESTAMP_FIRST_YEAR=100). Thx to Sebastiaan van Stijn.
- ADOdb speedup optimization - we now return all arrays by reference.
- Now DBDate() and DBTimeStamp() now accepts the string 'null' as a parameter. Suggested by vincent.
- Added GetArray() to connection class.
- Added not_null check in informix metacolumns().
- Connection parameters for postgresql did not work correctly when port was defined.
- DB2 is now a tested driver, making adodb 100% compatible. Extensive changes to odbc driver for DB2, including implementing serverinfo() and SQLDate(), switching to SQL_CUR_USE_ODBC as the cursor mode, and lastAffectedRows and SelectLimit() fixes.
- The odbc driver's FetchField() field names did not obey ADODB_ASSOC_CASE. Fixed.
- Some bugs in adodb_backtrace() fixed.
- Added "INT IDENTITY" type to adorecordset::MetaType() to support odbc_mssql properly.
- MetaColumns() for oci8, mssql, odbc revised to support scale. Also minor revisions to odbc MetaColumns() for vfp and db2 compat.
- Added unsigned support to mysql datadict class. Thx to iamsure.
- Infinite loop in mssql MoveNext() fixed when ADODB_FETCH_ASSOC used. Thx to Josh R, Night_Wulfe#hotmail.com.
- ChangeTableSQL contributed by Florian Buzin.
- The odbc_mssql driver now sets CONCAT_NULL_YIELDS_NULL OFF for compat with mssql driver.
## 3.50 - 19 May 2003
- Fixed mssql compat with FreeTDS. FreeTDS does not implement mssql_fetch_assoc().
- Merged back connection and recordset code into adodb.inc.php.
- ADOdb sessions using oracle clobs contributed by achim.gosse#ddd.de. See adodb-session-clob.php.
- Added /s modifier to preg_match everywhere, which ensures that regex does not stop at /n. Thx Pao-Hsi Huang.
- Fixed error in metacolumns() for mssql.
- Added time format support for SQLDate.
- Image => B added to metatype.
- MetaType now checks empty($this->blobSize) instead of empty($this).
- Datadict has beta support for informix, sybase (mapped to mssql), db2 and generic (which is a fudge).
- BlobEncode for postgresql uses pg_escape_bytea, if available. Needed for compat with 7.3.
- Added $ADODB_LANG, to support multiple languages in MetaErrorMsg().
- Datadict can now parse table definition as declarative text.
- For DataDict, oci8 autoincrement trigger missing semi-colon. Fixed.
- For DataDict, when REPLACE flag enabled, drop sequence in datadict for autoincrement field in postgres and oci8.s
- Postgresql defaults to template1 database if no database defined in connect/pconnect.
- We now clear _resultid in postgresql if query fails.
## 3.40 - 19 May 2003
- Added insert_id for odbc_mssql.
- Modified postgresql UpdateBlobFile() because it did not work in safe mode.
- Now connection object is passed to raiseErrorFn as last parameter. Needed by StartTrans().
- Added StartTrans() and CompleteTrans(). It is recommended that you do not modify transOff, but use the above functions.
- oci8po now obeys ADODB_ASSOC_CASE settings.
- Added virtualized error codes, using PEAR DB equivalents. Requires you to manually include adodb-error.inc.php yourself, with MetaError() and MetaErrorMsg($errno).
- GetRowAssoc for mysql and pgsql were flawed. Fix by Ross Smith.
- Added to datadict types I1, I2, I4 and I8\. Changed datadict type 'T' to map to timestamp instead of datetime for postgresql.
- Error handling in ExecuteSQLArray(), adodb-datadict.inc.php did not work.
- We now auto-quote postgresql connection parameters when building connection string.
- Added session expiry notification.
- We now test with odbc mysql - made some changes to odbc recordset constructor.
- MetaColumns now special cases access and other databases for odbc.
## 3.31 - 17 March 2003
- Added row checking for _fetch in postgres.
- Added Interval type to MetaType for postgres.
- Remapped postgres driver to call postgres7 driver internally.
- Adorecordset_array::getarray() did not return array when nRows >= 0.
- Postgresql: at times, no error message returned by pg_result_error() but error message returned in pg_last_error(). Recoded again.
- Interbase blob's now use chunking for updateblob.
- Move() did not set EOF correctly. Reported by Jorma T.
- We properly support mysql timestamp fields when we are creating mysql tables using the data-dict interface.
- Table regex includes backticks character now.
## 3.30 - 3 March 2003
- Added $ADODB_EXTENSION and $ADODB_COMPAT_FETCH constant.
- Made blank1stItem configurable using syntax "value:text" in GetMenu/GetMenu2. Thx to Gabriel Birke.
- Previously ADOdb differed from the Microsoft standard because it did not define what to set $this->fields when EOF was reached. Now at EOF, ADOdb sets $this->fields to false for all databases, which is consist with Microsoft's implementation. Postgresql and mysql have always worked this way (in 3.11 and earlier). If you are experiencing compatibility problems (and you are not using postgresql nor mysql) on upgrading to 3.30, try setting the global variables $ADODB_COUNTRECS = true (which is the default) and $ADODB_FETCH_COMPAT = true (this is a new global variable).
- We now check both pg_result_error and pg_last_error as sometimes pg_result_error does not display anything. Iman Mayes
- We no longer check for magic quotes gpc in Quote().
- Misc fixes for table creation in adodb-datadict.inc.php. Thx to iamsure.
- Time calculations use adodb_time library for all negative timestamps due to problems in Red Hat 7.3 or later. Formerly, only did this for Windows.
- In mssqlpo, we now check if $sql in _query is a string before we change || to +. This is to support prepared stmts.
- Move() and MoveLast() internals changed to support to support EOF and $this->fields change.
- Added ADODB_FETCH_BOTH support to mssql. Thx to Angel Fradejas afradejas#mediafusion.es
- We now check if link resource exists before we run mysql_escape_string in qstr().
- Before we flock in csv code, we check that it is not a http url.
## 3.20 - 17 Feb 2003
- Added new Data Dictionary classes for creating tables and indexes. Warning - this is very much alpha quality code. The API can still change. See adodb/tests/test-datadict.php for more info.
- We now ignore $ADODB_COUNTRECS for mysql, because PHP truncates incomplete recordsets when mysql_unbuffered_query() is called a second time.
- Now postgresql works correctly when $ADODB_COUNTRECS = false.
- Changed _adodb_getcount to properly support SELECT DISTINCT.
- Discovered that $ADODB_COUNTRECS=true has some problems with prepared queries - suspect PHP bug.
- Now GetOne and GetRow run in $ADODB_COUNTRECS=false mode for better performance.
- Added support for mysql_real_escape_string() and pg_escape_string() in qstr().
- Added an intermediate variable for mysql _fetch() and MoveNext() to store fields, to prevent overwriting field array with boolean when mysql_fetch_array() returns false.
- Made arrays for getinsertsql and getupdatesql case-insensitive. Suggested by Tim Uckun" tim#diligence.com
## 3.11 - 11 Feb 2003
- Added check for ADODB_NEVER_PERSIST constant in PConnect(). If defined, then PConnect() will actually call non-persistent Connect().
- Modified interbase to properly work with Prepare().
- Added $this->ibase_timefmt to allow you to change the date and time format.
- Added support for $input_array parameter in CacheFlush().
- Added experimental support for dbx, which was then removed when i found that it was slower than using native calls.
- Added MetaPrimaryKeys for mssql and ibase/firebird.
- Added new $trim parameter to GetCol and CacheGetCol
- Uses updated adodb-time.inc.php 0.06.
## 3.10 - 27 Jan 2003
- Added adodb_date(), adodb_getdate(), adodb_mktime() and adodb-time.inc.php.
- For interbase, added code to handle unlimited number of bind parameters. From Daniel Hasan daniel#hasan.cl.
- Added BlobDecode and UpdateBlob for informix. Thx to Fernando Ortiz.
- Added constant ADODB_WINDOWS. If defined, means that running on Windows.
- Added constant ADODB_PHPVER which stores php version as a hex num. Removed $ADODB_PHPVER variable.
- Felho Bacsi reported a minor white-space regular expression problem in GetInsertSQL.
- Modified ADO to use variant to store _affectedRows
- Changed ibase to use base class Replace(). Modified base class Replace() to support ibase.
- Changed odbc to auto-detect when 0 records returned is wrong due to bad odbc drivers.
- Changed mssql to use datetimeconvert ini setting only when 4.30 or later (does not work in 4.23).
- ExecuteCursor($stmt, $cursorname, $params) now accepts a new $params array of additional bind parameters -- William Lovaton walovaton#yahoo.com.mx.
- Added support for sybase_unbuffered_query if ADODB_COUNTRECS == false. Thx to chuck may.
- Fixed FetchNextObj() bug. Thx to Jorma Tuomainen.
- We now use SCOPE_IDENTITY() instead of @@IDENTITY for mssql - thx to marchesini#eside.it
- Changed postgresql movenext logic to prevent illegal row number from being passed to pg_fetch_array().
- Postgresql initrs bug found by "Bogdan RIPA" bripa#interakt.ro $f1 accidentally named $f
## 3.00 - 6 Jan 2003
- Fixed adodb-pear.inc.php syntax error.
- Improved _adodb_getcount() to use SELECT COUNT(*) FROM ($sql) for languages that accept it.
- Fixed _adodb_getcount() caching error.
- Added sql to retrive table and column info for odbc_mssql.
-109
View File
@@ -1,109 +0,0 @@
## 4.990/5.05 - 11 Jul 2008
- Added support for multiple recordsets in mysqli Geisel Sierote <geisel#4up.com.br>. See http://phplens.com/lens/lensforum/msgs.php?id=15917
- Malcolm Cook added new Reload() function to Active Record. See http://phplens.com/lens/lensforum/msgs.php?id=17474
- Thanks Zoltan Monori [monzol#fotoprizma.hu] for bug fixes in iterator, SelectLimit, GetRandRow, etc.
- Under heavy loads, the performance monitor for oci8 disables Ixora views.
- Fixed sybase driver SQLDate to use str_replace(). Also for adodb5, changed sybase driver UnixDate and UnixTimeStamp calls to static.
- Changed oci8 lob handler to use &amp; reference $this-&gt;_refLOBs[$numlob]['VAR'] = &amp;$var.
- We now strtolower the get_class() function in PEAR::isError() for php5 compat.
- CacheExecute did not retrieve cache recordsets properly for 5.04 (worked in 4.98). Fixed.
- New ADODB_Cache_File class for file caching defined in adodb.inc.php.
- Farsi language file contribution by Peyman Hooshmandi Raad (phooshmand#gmail.com)
- New API for creating your custom caching class which is stored in $ADODB_CACHE:
```
include "/path/to/adodb.inc.php";
$ADODB_CACHE_CLASS = 'MyCacheClass';
class MyCacheClass extends ADODB_Cache_File
{
function writecache($filename, $contents,$debug=false){...}
function &readcache($filename, &$err, $secs2cache, $rsClass){ ...}
:
}
$DB = NewADOConnection($driver);
$DB->Connect(...); ## MyCacheClass created here and stored in $ADODB_CACHE global variable.
$data = $rs->CacheGetOne($sql); ## MyCacheClass is used here for caching...
```
- Memcache supports multiple pooled hosts now. Only if none of the pooled servers can be contacted will a connect error be generated. Usage example below:
```
$db = NewADOConnection($driver);
$db->memCache = true; /// should we use memCache instead of caching in files
$db->memCacheHost = array($ip1, $ip2, $ip3); /// $db->memCacheHost = $ip1; still works
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)
$db->Connect(...);
$db->CacheExecute($sql);
```
## 4.98/5.04 - 13 Feb 2008
- Fixed adodb_mktime problem which causes a performance bottleneck in $hrs.
- Added mysqli support to adodb_getcount().
- Removed MYSQLI_TYPE_CHAR from MetaType().
## 4.97/5.03 - 22 Jan 2008
- Active Record: $ADODB_ASSOC_CASE=1 did not work properly. Fixed.
- Modified Fields() in recordset class to support display null fields in FetchNextObject().
- In ADOdb5, active record implementation, we now support column names with spaces in them - we autoconvert the spaces to _ using __set(). Thx Daniel Cook. http://phplens.com/lens/lensforum/msgs.php?id=17200
- Removed $arg3 from mysqli SelectLimit. See http://phplens.com/lens/lensforum/msgs.php?id=16243. Thx Zsolt Szeberenyi.
- Changed oci8 FetchField, which returns the max_length of BLOB/CLOB/NCLOB as 4000 (incorrectly) to -1.
- CacheExecute would sometimes return an error on Windows if it was unable to lock the cache file. This is harmless and has been changed to a warning that can be ignored. Also adodb_write_file() code revised.
- ADOdb perf code changed to only log sql if execution time &gt;= 0.05 seconds. New $ADODB_PERF_MIN variable holds min sql timing. Any SQL with timing value below this and is not causing an error is not logged.
- Also adodb_backtrace() now traces 1 level deeper as sometimes actual culprit function is not displayed.
- Fixed a group by problem with adodb_getcount() for db's which are not postgres/oci8 based.
- Changed mssql driver Parameter() from SQLCHAR to SQLVARCHAR: case 'string': $type = SQLVARCHAR; break.
- Problem with mssql driver in php5 (for adodb 5.03) because some functions are not static. Fixed.
## 4.96/5.02 - 24 Sept 2007
ADOdb perf for oci8 now has non-table-locking code when clearing the sql. Slower but better transparency. Added in 4.96a and 5.02a.
Fix adodb count optimisation. Preg_match did not work properly. Also rewrote the ORDER BY stripping code in _adodb_getcount(), adodb-lib.inc.php.
SelectLimit for oci8 not optimal for large recordsets when offset=0. Changed $nrows check.
Active record optimizations. Added support for assoc arrays in Set().
Now GetOne returns null if EOF (no records found), and false if error occurs. Use ErrorMsg()/ErrorNo() to get the error.
Also CacheGetRow and CacheGetCol will return false if error occurs, or empty array() if EOF, just like GetRow and GetCol.
Datadict now allows changing of types which are not resizable, eg. VARCHAR to TEXT in ChangeTableSQL. -- Mateo Tibaquirá
Added BIT data type support to adodb-ado.inc.php and adodb-ado5.inc.php.
Ldap driver did not return actual ldap error messages. Fixed.
Implemented GetRandRow($sql, $inputarr). Optimized for Oci8.
Changed adodb5 active record to use static SetDatabaseAdapter() and removed php4 constructor. Bas van Beek bas.vanbeek#gmail.com.
Also in adodb5, changed adodb-session2 to use static function declarations in class. Thx Daniel Berlin.
Added "Clear SQL Log" to bottom of Performance screen.
Sessions2 code echo'ed directly to the screen in debug mode. Now uses ADOConnection::outp().
In mysql/mysqli, qstr(null) will return the string "null" instead of empty quoted string "''".
postgresql optimizeTable in perf-postgres.inc.php added by Daniel Berlin (mail#daniel-berlin.de)
Added 5.2.1 compat code for oci8.
Changed @@identity to SCOPE_IDENTITY() for multiple mssql drivers. Thx Stefano Nari.
Code sanitization introduced in 4.95 caused problems in European locales (as float 3.2 was typecast to 3,2). Now we only sanitize if is_numeric fails.
Added support for customizing ADORecordset_empty using $this-&gt;rsPrefix.'empty'. By Josh Truwin.
Added proper support for ALterColumnSQL for Postgresql in datadict code. Thx. Josh Truwin.
Added better support for MetaType() in mysqli when using an array recordset.
Changed parser for pgsql error messages in adodb-error.inc.php to case-insensitive regex.
## 4.95/5.01 - 17 May 2007
CacheFlush debug outp() passed in invalid parameters. Fixed.
Added Thai language file for adodb. Thx Trirat Petchsingh rosskouk#gmail.com
and Marcos Pont
Added zerofill checking support to MetaColumns for mysql and mysqli.
CacheFlush no longer deletes all files/directories. Only *.cache files
deleted.
DB2 timestamp format changed to var $fmtTimeStamp =
&quot;'Y-m-d-H:i:s'&quot;;
Added some code sanitization to AutoExecute in adodb-lib.inc.php.
Due to typo, all connections in adodb-oracle.inc.php would become
persistent, even non-persistent ones. Fixed.
Oci8 DBTimeStamp uses 24 hour time for input now, so you can perform string
comparisons between 2 DBTimeStamp values.
Some PHP4.4 compat issues fixed in adodb-session2.inc.php
For ADOdb 5.01, fixed some adodb-datadict.inc.php MetaType compat issues
with PHP5.
The $argHostname was wiped out in adodb-ado5.inc.php. Fixed.
Adodb5 version, added iterator support for adodb_recordset_empty.
Adodb5 version,more error checking code now will use exceptions if
available.
-722
View File
@@ -1,722 +0,0 @@
# ADOdb old Changelog - v4.x
See the [Current Changelog](changelog.md).
Older changelogs:
[v3.x](changelog_v3.x.md),
[v2.x](changelog_v2.x.md).
## 4.990 - 11 Jul 2008
- Added support for multiple recordsets in mysqli Geisel Sierote <geisel#4up.com.br>. See http://phplens.com/lens/lensforum/msgs.php?id=15917
- Malcolm Cook added new Reload() function to Active Record. See http://phplens.com/lens/lensforum/msgs.php?id=17474
- Thanks Zoltan Monori [monzol#fotoprizma.hu] for bug fixes in iterator, SelectLimit, GetRandRow, etc.
- Under heavy loads, the performance monitor for oci8 disables Ixora views.
- Fixed sybase driver SQLDate to use str_replace(). Also for adodb5, changed sybase driver UnixDate and UnixTimeStamp calls to static.
- Changed oci8 lob handler to use &amp; reference $this-&gt;_refLOBs[$numlob]['VAR'] = &amp;$var.
- We now strtolower the get_class() function in PEAR::isError() for php5 compat.
- CacheExecute did not retrieve cache recordsets properly for 5.04 (worked in 4.98). Fixed.
- New ADODB_Cache_File class for file caching defined in adodb.inc.php.
- Farsi language file contribution by Peyman Hooshmandi Raad (phooshmand#gmail.com)
- New API for creating your custom caching class which is stored in $ADODB_CACHE:
```
include "/path/to/adodb.inc.php";
$ADODB_CACHE_CLASS = 'MyCacheClass';
class MyCacheClass extends ADODB_Cache_File
{
function writecache($filename, $contents,$debug=false){...}
function &readcache($filename, &$err, $secs2cache, $rsClass){ ...}
:
}
$DB = NewADOConnection($driver);
$DB->Connect(...); ## MyCacheClass created here and stored in $ADODB_CACHE global variable.
$data = $rs->CacheGetOne($sql); ## MyCacheClass is used here for caching...
```
- Memcache supports multiple pooled hosts now. Only if none of the pooled servers can be contacted will a connect error be generated. Usage example below:
```
$db = NewADOConnection($driver);
$db->memCache = true; /// should we use memCache instead of caching in files
$db->memCacheHost = array($ip1, $ip2, $ip3); /// $db->memCacheHost = $ip1; still works
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)
$db->Connect(...);
$db->CacheExecute($sql);
```
## 4.98 - 13 Feb 2008
- Fixed adodb_mktime problem which causes a performance bottleneck in $hrs.
- Added mysqli support to adodb_getcount().
- Removed MYSQLI_TYPE_CHAR from MetaType().
## 4.97 - 22 Jan 2008
- Active Record: $ADODB_ASSOC_CASE=1 did not work properly. Fixed.
- Modified Fields() in recordset class to support display null fields in FetchNextObject().
- In ADOdb5, active record implementation, we now support column names with spaces in them - we autoconvert the spaces to `_` using `__set()`. Thx Daniel Cook. http://phplens.com/lens/lensforum/msgs.php?id=17200
- Removed $arg3 from mysqli SelectLimit. See http://phplens.com/lens/lensforum/msgs.php?id=16243. Thx Zsolt Szeberenyi.
- Changed oci8 FetchField, which returns the max_length of BLOB/CLOB/NCLOB as 4000 (incorrectly) to -1.
- CacheExecute would sometimes return an error on Windows if it was unable to lock the cache file. This is harmless and has been changed to a warning that can be ignored. Also adodb_write_file() code revised.
- ADOdb perf code changed to only log sql if execution time &gt;= 0.05 seconds. New $ADODB_PERF_MIN variable holds min sql timing. Any SQL with timing value below this and is not causing an error is not logged.
- Also adodb_backtrace() now traces 1 level deeper as sometimes actual culprit function is not displayed.
- Fixed a group by problem with adodb_getcount() for db's which are not postgres/oci8 based.
- Changed mssql driver Parameter() from SQLCHAR to SQLVARCHAR: case 'string': $type = SQLVARCHAR; break.
- Problem with mssql driver in php5 (for adodb 5.03) because some functions are not static. Fixed.
## 4.96 - 24 Sept 2007
- ADOdb perf for oci8 now has non-table-locking code when clearing the sql. Slower but better transparency. Added in 4.96a and 5.02a.
- Fix adodb count optimisation. Preg_match did not work properly. Also rewrote the ORDER BY stripping code in _adodb_getcount(), adodb-lib.inc.php.
- SelectLimit for oci8 not optimal for large recordsets when offset=0. Changed $nrows check.
- Active record optimizations. Added support for assoc arrays in Set().
- Now GetOne returns null if EOF (no records found), and false if error occurs. Use ErrorMsg()/ErrorNo() to get the error.
- Also CacheGetRow and CacheGetCol will return false if error occurs, or empty array() if EOF, just like GetRow and GetCol.
- Datadict now allows changing of types which are not resizable, eg. VARCHAR to TEXT in ChangeTableSQL. -- Mateo Tibaquirá
- Added BIT data type support to adodb-ado.inc.php and adodb-ado5.inc.php.
- Ldap driver did not return actual ldap error messages. Fixed.
- Implemented GetRandRow($sql, $inputarr). Optimized for Oci8.
- Changed adodb5 active record to use static SetDatabaseAdapter() and removed php4 constructor. Bas van Beek bas.vanbeek#gmail.com.
- Also in adodb5, changed adodb-session2 to use static function declarations in class. Thx Daniel Berlin.
- Added "Clear SQL Log" to bottom of Performance screen.
- Sessions2 code echo'ed directly to the screen in debug mode. Now uses ADOConnection::outp().
- In mysql/mysqli, qstr(null) will return the string "null" instead of empty quoted string "''".
- postgresql optimizeTable in perf-postgres.inc.php added by Daniel Berlin (mail#daniel-berlin.de)
- Added 5.2.1 compat code for oci8.
- Changed @@identity to SCOPE_IDENTITY() for multiple mssql drivers. Thx Stefano Nari.
- Code sanitization introduced in 4.95 caused problems in European locales (as float 3.2 was typecast to 3,2). Now we only sanitize if is_numeric fails.
- Added support for customizing ADORecordset_empty using $this-&gt;rsPrefix.'empty'. By Josh Truwin.
- Added proper support for ALterColumnSQL for Postgresql in datadict code. Thx. Josh Truwin.
- Added better support for MetaType() in mysqli when using an array recordset.
- Changed parser for pgsql error messages in adodb-error.inc.php to case-insensitive regex.
## 4.95 - 17 May 2007
- CacheFlush debug outp() passed in invalid parameters. Fixed.
- Added Thai language file for adodb. Thx Trirat Petchsingh rosskouk#gmail.com and Marcos Pont
- Added zerofill checking support to MetaColumns for mysql and mysqli.
- CacheFlush no longer deletes all files directories. Only `*.cache` files deleted.
- DB2 timestamp format changed to var $fmtTimeStamp = 'Y-m-d-H:i:s';
- Added some code sanitization to AutoExecute in adodb-lib.inc.php.
- Due to typo, all connections in adodb-oracle.inc.php would become persistent, even non-persistent ones. Fixed.
- Oci8 DBTimeStamp uses 24 hour time for input now, so you can perform string comparisons between 2 DBTimeStamp values.
- Some PHP4.4 compat issues fixed in adodb-session2.inc.php
- For ADOdb 5.01, fixed some adodb-datadict.inc.php MetaType compat issues with PHP5.
- The $argHostname was wiped out in adodb-ado5.inc.php. Fixed.
- Adodb5 version, added iterator support for adodb_recordset_empty.
- Adodb5 version,more error checking code now will use exceptions if available.
## 4.94 - 23 Jan 2007
- Active Record: $ADODB_ASSOC_CASE=2 did not work properly. Fixed. Thx gmane#auxbuss.com.
- mysqli had bugs in BeginTrans() and EndTrans(). Fixed.
- Improved error handling when no database is connected for oci8. Thx Andy Hassall.
- Names longer than 30 chars in oci8 datadict will be changed to random name. Thx Eugenio. http://phplens.com/lens/lensforum/msgs.php?id=16182
- Added var $upperCase = 'ucase' to access and ado_access drivers. Thx Renato De Giovanni renato#cria.org.br
- Postgres64 driver, if preparing plan failed in _query, did not handle error properly. Fixed. See http://phplens.com/lens/lensforum/msgs.php?id=16131.
- Fixed GetActiveRecordsClass() reference bug. See http://phplens.com/lens/lensforum/msgs.php?id=16120
- Added handling of nulls in adodb-ado_mssql.inc.php for qstr(). Thx to Felix Rabinovich.
- Adodb-dict contributions by Gaetano
- Support for INDEX in data-dict. Example: idx_ev1. The ability to define indexes using the INDEX keyword was added in ADOdb 4.94. The following example features mutiple indexes, including a compound index idx_ev1.
```
event_id I(11) NOTNULL AUTOINCREMENT PRIMARY,
event_type I(4) NOTNULL
event_start_date T DEFAULT NULL **INDEX id_esd**,
event_end_date T DEFAULT '0000-00-00 00:00:00' **INDEX id_eted**,
event_parent I(11) UNSIGNED NOTNULL DEFAULT 0 **INDEX id_evp**,
event_owner I(11) DEFAULT 0 **INDEX idx_ev1**,
event_project I(11) DEFAULT 0 **INDEX idx_ev1**,
event_times_recuring I(11) UNSIGNED NOTNULL DEFAULT 0,
event_icon C(20) DEFAULT 'obj/event',
event_description X
```
- Prevents the generated SQL from including double drop-sequence statements for REPLACE case of tables with autoincrement columns (on those dbs that emulate it via sequences)
- makes any date defined as DEFAULT value for D and T columns work cross-database, not just the "sysdate" value (as long as it is specified using adodb standard format). See above example.
- Fixed pdo's GetInsertID() support. Thx Ricky Su.
- oci8 Prepare() now sets error messages if an error occurs.
- Added 'PT_BR' to SetDateLocale() -- brazilian portugese.
- charset in oci8 was not set correctly on `*Connect()`
- ADOConnection::Transpose() now appends as first column the field names.
- Added $ADODB_QUOTE_FIELDNAMES. If set to true, will autoquote field names in AutoExecute(),GetInsertSQL(), GetUpdateSQL().
- Transpose now adds the field names as the first column after transposition.
- Added === check in ADODB_SetDatabaseAdapter for $db, adodb-active-record.inc.php. Thx Christian Affolter.
- Added ErrorNo() to adodb-active-record.inc.php. Thx ante#novisplet.com.
## 4.93 - 10 Oct 2006
- Added support for multiple database connections in performance monitoring code (adodb-perf.inc.php). Now all sql in multiple database connections can be saved into one database ($ADODB_LOG_CONN).
- Added MetaIndexes() to odbc_mssql.
- Added connection property $db->null2null = 'null'. In autoexecute/getinsertsql/getupdatesql, this value will be converted to a null. Set this to a funny invalid value if you do not want null conversion. See http://phplens.com/lens/lensforum/msgs.php?id=15902.
- Path disclosure problem in mysqli fixed. Thx Andy.
- Fixed typo in session_schema2.xml.
- Changed INT in oci8 to return correct precision in $fld->max_length, MetaColumns(). Thx Eloy Lafuente Plaza.
- Patched postgres64 _connect to handle serverinfo(). see http://phplens.com/lens/lensforum/msgs.php?id=15887.
- Added pdo fix for null columns. See http://phplens.com/lens/lensforum/msgs.php?id=15889
- For stored procedures, missing connection id now passed into mssql_query(). Thx Ecsy (ecsy#freemail.hu).
## 4.92a - 30 Aug 2006
- Syntax error in postgres7 driver. Thx Eloy Lafuente Plaza.
- Minor bug fixes - adodb informix 10 types added to adodb.inc.php. Thx Fernando Ortiz.
## 4.92 - 29 Aug 2006
- Better odbtp date support.
- Added IgnoreErrors() to bypass default error handling.
- The _adodb_getcount() function in adodb-lib.inc.php, some ORDER BY bug fixes.
- For ibase and firebird, set $sysTimeStamp = "CURRENT_TIMESTAMP".
- Fixed postgres connection bug: http://phplens.com/lens/lensforum/msgs.php?id=11057.
- Changed CacheSelectLimit() to flush cache when $secs2cache==-1 due to complaints from other users.
- Added support for using memcached with CacheExecute/CacheSelectLimit. Requires memcache module PECL extension. Usage:
```
$db = NewADOConnection($driver);
$db->memCache = true; /// should we use memCache instead of caching in files
$db->memCacheHost = "126.0.1.1"; /// memCache host
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)
$db->Connect(...);
$db->CacheExecute($sql);
```
- Implemented Transpose() for recordsets. Recordset must be retrieved using ADODB_FETCH_NUM. First column becomes the column name.
```
$db = NewADOConnection('mysql');
$db->Connect(...);
$db->SetFetchMode(ADODB_FETCH_NUM);
$rs = $db->Execute('select productname,productid,unitprice from products limit 10');
$rs2 = $db->Transpose($rs);
rs2html($rs2);
```
## 4.91 - 2 Aug 2006
- Major session code rewrite... See session docs.
- PDO bindinputarray() was not set properly for MySQL (changed from true to false).
- Changed CacheSelectLimit() to re-cache when $secs2cache==0. This is one way to flush the cache when SelectLimit is called.
- Added to quotes to mysql and mysqli: "SHOW COLUMNS FROM \`%s\`";
- Removed accidental optgroup handling in GetMenu(). Fixed ibase _BlobDecode for php5 compat, and also mem alloc issues for small blobs, thx salvatori#interia.pl
- Mysql driver OffsetDate() speedup, useful for adodb-sessions.
- Fix for GetAssoc() PHP5 compat. See http://phplens.com/lens/lensforum/msgs.php?id=15425
- Active Record - If inserting a record and the value of a primary key field is null, then we do not insert that field in as we assume it is an auto-increment field. Needed by mssql.
- Changed postgres7 MetaForeignKeys() see http://phplens.com/lens/lensforum/msgs.php?id=15531
- DB2 will now return db2_conn_errormsg() when it is a connection error.
## 4.90 - 8 June 2006
- Changed adodb_countrec() in adodb-lib.inc.php to allow LIMIT to be used as a speedup to reduce no of records counted.
- Added support for transaction modes for postgres and oci8 with SetTransactionMode(). These transaction modes affect all subsequent transactions of that connection.
- Thanks to Halmai Csongor for suggestion.
- Removed `$off = $fieldOffset - 1` line in db2 driver, FetchField(). Tx Larry Menard.
- Added support for PHP5 objects as Execute() bind parameters using `__toString` (eg. Simple-XML). Thx Carl-Christian Salvesen.
- Rounding in tohtml.inc.php did not work properly. Fixed.
- MetaIndexes in postgres fails when fields are deleted then added in again because the attnum has gaps in it. See http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976. Fixed.
- MetaForeignkeys in mysql and mysqli did not work when fetchMode==ADODB_FETCH_ASSOC used. Fixed.
- Reference error in AutoExecute() fixed.
- Added macaddr postgres type to MetaType. Maps to 'C'.
- Added to `_connect()` in adodb-ado5.inc.php support for $database and $dataProvider parameters. Thx Larry Menard.
- Added support for sequences in adodb-ado_mssql.inc.php. Thx Larry Menard.
- Added ADODB_SESSION_READONLY.
- Added session expiryref support to crc32 mode, and in LOB code.
- Clear `_errorMsg` in postgres7 driver, so that ErrorMsg() displays properly when no error occurs.
- Added BindDate and BindTimeStamp
## 4.81 - 3 May 2006
- Fixed variable ref errors in adodb-ado5.inc.php in _query().
- Mysqli setcharset fix using method_exists().
- The adodb-perf.inc.php CreateLogTable() code now works for user-defined table names.
- Error in ibase_blob_open() fixed. See http://phplens.com/lens/lensforum/msgs.php?id=14997
## 4.80 - 8 Mar 2006
- Added activerecord support.
- Added mysql `$conn->compat323 = true` if you want MySQL 3.23 compat enabled. Fixes GetOne() Select-Limit problems.
- Added adodb-xmlschema03.inc.php to support XML Schema version 3 and updated adodb-datadict.htm docs.
- Better memory management in Execute. Thx Mike Fedyk.
## 4.72 - 21 Feb 2006
- Added 'new' DSN parameter for NConnect().
- Pager now sanitizes $PHP_SELF to protect against XSS. Thx to James Bercegay and others.
- ADOConnection::MetaType changed to setup $rs->connection correctly.
- New native DB2 driver contributed by Larry Menard, Dan Scott, Andy Staudacher, Bharat Mediratta.
- The mssql CreateSequence() did not BEGIN TRANSACTION correctly. Fixed. Thx Sean Lee.
- The _adodb_countrecs() function in adodb-lib.inc.php has been revised to handle more ORDER BY variations.
## 4.71 - 24 Jan 2006
- Fixes postgresql security issue related to binary strings. Thx to Andy Staudacher.
- Several DSN bugs found:
1. Fix bugs in DSN connections introduced in 4.70 when underscores are found in the DSN.
2. DSN with _ did not work properly in PHP5 (fine in PHP4). Fixed.
3. Added support for PDO DSN connections in NewADOConnection(), and database parameter in PDO::Connect().
- The oci8 datetime flag not correctly implemented in ADORecordSet_array. Fixed.
- Added BlobDelete() to postgres, as a counterpoint to UpdateBlobFile().
- Fixed GetInsertSQL() to support oci8po.
- Fixed qstr() issue with postgresql with \0 in strings.
- Fixed some datadict driver loading issues in _adodb_getdriver().
- Added register shutdown function session_write_close in adodb-session.inc.php for PHP 5 compat. See http://phplens.com/lens/lensforum/msgs.php?id=14200.
## 4.70 - 6 Jan 2006
- Many fixes from Danila Ulyanov to ibase, oci8, postgres, mssql, odbc_oracle, odbtp, etc drivers.
- Changed usage of binary hint in adodb-session.inc.php for mysql. See http://phplens.com/lens/lensforum/msgs.php?id=14160
- Fixed invalid variable reference problem in undomq(), adodb-perf.inc.php.
- Fixed http://phplens.com/lens/lensforum/msgs.php?id=14254 in adodb-perf.inc.php, `_DBParameter()` settings of fetchmode was wrong.
- Fixed security issues in server.php and tmssql.php discussed by Andreas Sandblad in a Secunia security advisory. Added `$ACCEPTIP = 127.0.0.1` and changed suggested root password to something more secure.
- Changed pager to close recordset after RenderLayout().
## 4.68 - 25 Nov 2005
- PHP 5 compat for mysqli. MetaForeignKeys repeated twice and MYSQLI_BINARY_FLAG missing.
- PHP 5.1 support for postgresql bind parameters using ? did not work if >= 10 parameters. Fixed. Thx to Stanislav Shramko.
- Lots of PDO improvements.
- Spelling error fixed in mysql MetaForeignKeys, $associative parameter.
## 4.67 - 16 Nov 2005
- Postgresql not_null flag not set to false correctly. Thx Cristian MARIN.
- We now check in Replace() if key is in fieldArray. Thx Sébastien Vanvelthem.
- `_file_get_contents()` function was missing in xmlschema. fixed.
- Added week in year support to SQLDate(), using 'W' flag. Thx Spider.
- In sqlite metacolumns was repeated twice, causing PHP 5 problems. Fixed.
- Made debug output XHTML compliant.
## 4.66 - 28 Sept 2005
- ExecuteCursor() in oci8 did not clean up properly on failure. Fixed.
- Updated xmlschema.dtd, by "Alec Smecher" asmecher#smecher.bc.ca
- Hardened SelectLimit, typecasting nrows and offset to integer.
- Fixed misc bugs in AutoExecute() and GetInsertSQL().
- Added $conn->database as the property holding the database name. The older $conn->databaseName is retained for backward compat.
- Changed _adodb_backtrace() compat check to use function_exists().
- Bug in postgresql MetaIndexes fixed. Thx Kevin Jamieson.
- Improved OffsetDate for MySQL, reducing rounding error.
- Metacolumns added to sqlite. Thx Mark Newnham.
- PHP 4.4 compat fixes for GetAssoc().
- Added postgresql bind support for php 5.1. Thx Cristiano da Cunha Duarte
- OffsetDate() fixes for postgresql, typecasting strings to date or timestamp.
- DBTimeStamp formats for mssql, odbc_mssql and postgresql made to conform with other db's.
- Changed PDO constants from PDO_ to PDO:: to support latest spec.
## 4.65 - 22 July 2005
- Reverted 'X' in mssql datadict to 'TEXT' to be compat with mssql driver. However now you can set $datadict->typeX = 'varchar(4000)' or 'TEXT' or 'CLOB' for mssql and oci8 drivers.
- Added charset support when using DSN for Oracle.
- _adodb_getmenu did not use fieldcount() to get number of fields. Fixed.
- MetaForeignKeys() for mysql/mysqli contributed by Juan Carlos Gonzalez.
- MetaDatabases() now correctly returns an array for mysqli driver. Thx Cristian MARIN.
- CompleteTrans(false) did not return false. Fixed. Thx to JMF.
- AutoExecute() did not work with Oracle. Fixed. Thx José Moreira.
- MetaType() added to connection object.
- More PHP 4.4 reference return fixes. Thx Ryan C Bonham and others.
## 4.64 - 20 June 2005
- In datadict, if the default field value is set to '', then it is not applied when the field is created. Fixed by Eugenio.
- MetaPrimaryKeys for postgres did not work because of true/false change in 4.63. Fixed.
- Tested ocifetchstatement in oci8. Rejected at the end.
- Added port to dsn handling. Supported in postgres, mysql, mysqli,ldap.
- Added 'w' and 'l' to mysqli SQLDate().
- Fixed error handling in ldap _connect() to be more consistent. Also added ErrorMsg() handling to ldap.
- Added support for union in _adodb_getcount, adodb-lib.inc.php for postgres and oci8.
- rs2html() did not work with null dates properly.
- PHP 4.4 reference return fixes.
## 4.63 - 18 May 2005
- Added $nrows<0 check to mysqli's SelectLimit().
- Added OptimizeTable() and OptimizeTables() in adodb-perf.inc.php. By Markus Staab.
- PostgreSQL inconsistencies fixed. true and false set to TRUE and FALSE, and boolean type in datadict-postgres.inc.php set to 'L' => 'BOOLEAN'. Thx Kevin Jamieson.
- New adodb_session_create_table() function in adodb-session.inc.php. By Markus Staab.
- Added null check to UserTimeStamp().
- Fixed typo in mysqlt driver in adorecordset. Thx to Andy Staudacher.
- GenID() had a bug in the raiseErrorFn handling. Fixed. Thx Marcos Pont.
- Datadict name quoting now handles ( ) in index fields correctly - they aren't part of the index field.
- Performance monitoring:
1. oci8 Ixora checks moved down;
2. expensive sql changed so that only those sql with count(*)>1 are shown;
3. changed sql1 field to a length+crc32 checksum - this breaks backward compat.
- We remap firebird15 to firebird in data dictionary.
## 4.62 - 2 Apr 2005
- Added 'w' (dow as 0-6 or 1-7) and 'l' (dow as string) for SQLDate for oci8, postgres and mysql.
- Rolled back MetaType() changes for mysqli done in prev version.
- Datadict change by chris, cblin#tennaxia.com data mappings from:
```
oci8: X->varchar(4000) XL->CLOB
mssql: X->XL->TEXT
mysql: X->XL->LONGTEXT
fbird: X->XL->varchar(4000)
```
to:
```
oci8: X->varchar(4000) XL->CLOB
mssql: X->VARCHAR(4000) XL->TEXT
mysql: X->TEXT XL->LONGTEXT
fbird: X->VARCHAR(4000) XL->VARCHAR(32000)
```
- Added $connection->disableBlobs to postgresql to improve performance when no bytea is used (2-5% improvement).
- Removed all HTTP_* vars.
- Added $rs->tableName to be set before calling AutoExecute().
- Alex Rootoff rootoff#pisem.net contributed ukrainian language file.
- Added new mysql_option() support using $conn->optionFlags array.
- Added support for ldap_set_option() using the $LDAP_CONNECT_OPTIONS global variable. Contributed by Josh Eldridge.
- Added LDAP_* constant definitions to ldap.
- Added support for boolean bind variables. We use $conn->false and $conn->true to hold values to set false/true to.
- We now do not close the session connection in adodb-session.inc.php as other objects could be using this connection.
- We now strip off `\0` at end of Ixora SQL strings in $perf->tohtml() for oci8.
## 4.61 - 23 Feb 2005
- MySQLi added support for mysqli_connect_errno() and mysqli_connect_error().
- Massive improvements to alpha PDO driver.
- Quote string bind parameters logged by performance monitor for easy type checking. Thx Jason Judge.
- Added support for $role when connecting with Interbase/firebird.
- Added support for enum recognition in MetaColumns() mysql and mysqli. Thx Amedeo Petrella.
- The sybase_ase driver contributed by Interakt Online. Thx Cristian Marin cristic#interaktonline.com.
- Removed not_null, has_default, and default_value from ADOFieldObject.
- Sessions code, fixed quoting of keys when handling LOBs in session write() function.
- Sessions code, added adodb_session_regenerate_id(), to reduce risk of session hijacking by changing session cookie dynamically. Thx Joe Li.
- Perf monitor, polling for CPU did not work for PHP 4.3.10 and 5.0.0-5.0.3 due to PHP bugs, so we special case these versions.
- Postgresql, UpdateBlob() added code to handle type==CLOB.
## 4.60 - 24 Jan 2005
- Implemented PEAR DB's autoExecute(). Simplified design because I don't like using constants when strings work fine.
- _rs2serialize will now update $rs->sql and $rs->oldProvider.
- Added autoExecute().
- Added support for postgres8 driver. Currently just remapped to postgres7 driver.
- Changed oci8 _query(), so that OCIBindByName() sets the length to -1 if element size is > 4000. This provides better support for LONGs.
- Added SetDateLocale() support for netherlands (Nl).
- Spelling error in pivot code ($iff should be $iif).
- mysql insert_id() did not work with mysql 3.x. Fixed.
- `\r\n` not converted to spaces correctly in exporting data. Fixed.
- _nconnect() in mysqli did not return value correctly. Fixed.
- Arne Eckmann contributed danish language file.
- Added clone() support to FetchObject() for PHP5.
- Removed SQL_CUR_USE_ODBC from odbc_mssql.
## 4.55 - 5 Jan 2005
- Found bug in Execute() with bind params for db's that do not support binding natively.
- DropSequence() now correctly uses default parameter.
- Now Execute() ignores locale for floats, so 1.23 is NEVER converted to 1,23.
- SetFetchMode() not properly saved in adodb-perf, suspicious sql and expensive sql. Fixed.
- Added INET to postgresql metatypes. Thx motzel.
- Allow oracle hints to work when counting with _adodb_getcount in adodb-lib.inc.php. Thx Chris Wrye.
- Changed mysql insert_id() to use SELECT LAST_INSERT_ID().
- If alter col in datadict does not modify col type/size of actual col, then it is removed from alter col code. By Mark Newham. Not perfect as MetaType() !== ActualType().
- Added handling of view fields in metacolumns() for postgresql. Thx Renato De Giovanni.
- Added to informix MetaPrimaryKeys and MetaColumns fixes for null bit. Thx to Cecilio Albero.
- Removed obsolete connection_timeout() from perf code.
- Added support for arrayClass in adodb-csv.inc.php.
- RSFilter now accepts methods of the form $array($obj, 'methodname'). Thx to blake#near-time.com.
- Changed CacheFlush to `$cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/';`
- For better cursor concurrency, added code to free ref cursors in oci8 when $rs->Close() is called. Note that CLose() is called internally by the Get* functions too.
- Added IIF support for access when pivoting. Thx Volodia Krupach.
- Added mssql datadict support for timestamp. Thx Alexios.
- Informix pager fix. By Mario Ramirez.
- ADODB_TABLE_REGEX now includes ':'. By Mario Ramirez.
- Mark Newnham contributed MetaIndexes for oci8 and db2.
## 4.54 - 5 Nov 2004
- Now you can set $db->charSet = ?? before doing a Connect() in oci8.
- Added adodbFetchMode to sqlite.
- Perf code, added a string typecast to substr in adodb_log_sql().
- Postgres: Changed BlobDecode() to use po_loread, added new $maxblobsize parameter, and now it returns the blob instead of sending it to stdout - make sure to mention that as a compat warning. Also added $db->IsOID($oid) function; uses a heuristic, not guaranteed to work 100%.
- Contributed arabic language file by "El-Shamaa, Khaled" k.el-shamaa#cgiar.org
- PHP5 exceptions did not handle @ protocol properly. Fixed.
- Added ifnull handling for postgresql (using coalesce).
- Added metatables() support for Postgresql 8.0 (no longer uses pg_% dictionary tables).
- Improved Sybase ErrorMsg() function. By Gaetano Giunta.
- Improved oci8 SelectLimit() to use Prepare(). By Cristiano Duarte.
- Type-cast $row parameter in ifx_fetch_row() to int. Thx stefan bodgan.
- Ralf becker contributed improvements in postgresql, sapdb, mysql data dictionary handling:
- MySql and Postgres MetaType was reporting every int column which was part of a primary key and unique as serial
- Postgres was not reporting the scale of decimal types
- MaxDB was padding the defaults of none-string types with spaces
- MySql now correctly converts enum columns to varchar
- Ralf also changed Postgresql datadict:
- you cant add NOT NULL columns in postgres in one go, they need to be added as NULL and then altered to NOT NULL
- AlterColumnSQL could not change a varchar column with numbers into an integer column, postgres need an explicit conversation
- a re-created sequence was not set to the correct value, if the name was the old name (no implicit sequence), now always the new name of the implicit sequence is used
- Sergio Strampelli added extra $intoken check to Lens_ParseArgs() in datadict code.
## 4.53 - 28 Sept 2004
- FetchMode cached in recordset is sometimes mapped to native db fetchMode. Normally this does not matter, but when using cached recordsets, we need to switch back to using adodb fetchmode. So we cache this in $rs->adodbFetchMode if it differs from the db's fetchMode.
- For informix we now set canSeek = false driver because stefan bodgan tells me that seeking doesn't work.
- SetDateLocale() never worked till now ;-) Thx david#tomato.it
- Set $_bindInputArray = true in sapdb driver. Required for clob support.
- Fixed some PEAR::DB emulation issues with isError() and isWarning. Thx to Gert-Rainer Bitterlich.
- Empty() used in getupdatesql without strlen() check. Fixed.
- Added unsigned detection to mysql and mysqli drivers. Thx to dan cech.
- Added hungarian language file. Thx to Halászvári Gábor.
- Improved fieldname-type formatting of datadict SQL generated (adding $widespacing parameter to _GenField).
- Datadict oci8 DROP CONSTRAINTS misspelt. Fixed. Thx Mark Newnham.
- Changed odbtp to dynamically change databaseType based on connection, eg. from 'odbtp' to 'odbtp_mssql' when connecting to mssql database.
- In datadict, MySQL I4 was wrongly mapped to MEDIUMINT, which is actually I3. Fixed.
- Fixed mysqli MetaType() recognition. Mysqli returns numeric types unlike mysql extension. Thx Francesco Riosa.
- VFP odbc driver curmode set wrongly, causing problems with memo fields. Fixed.
- Odbc driver did not recognize odbc version 2 driver date types properly. Fixed. Thx Bostjan.
- ChangeTableSQL() fixes to datadict-db2.inc.php by Mark Newnham.
- Perf monitoring with odbc improved. Now we try in perf code to manually set the sysTimeStamp using date() if sysTimeStamp is empty.
- All ADO errors are thrown as exceptions in PHP5. So we added exception handling to ado in PHP5 by creating new adodb-ado5.inc.php driver.
- Added IsConnected(). Returns true if connection object connected. By Luca.Gioppo.
- "Ralf Becker" RalfBecker#digitalROCK.de contributed new sapdb data-dictionary driver and a large patch that implements field and table renaming for oracle, mssql, postgresql, mysql and sapdb. See the new RenameTableSQL() and RenameColumnSQL() functions.
- We now check ExecuteCursor to see if PrepareSP was initially called.
- Changed oci8 datadict to use MODIFY for $dd->alterCol. Thx Mark Newnham.
## 4.52 - 10 Aug 2004
- Bug found in Replace() when performance logging enabled, introduced in ADOdb 4.50. Fixed.
- Replace() checks update stmt. If update stmt fails, we now return immediately. Thx to alex.
- Added support for $ADODB_FORCE_TYPE in GetUpdateSQL/GetInsertSQL. Thx to niko.
- Added ADODB_ASSOC_CASE support to postgres/postgres7 driver.
- Support for DECLARE stmt in oci8. Thx Lochbrunner.
## 4.51 - 29 July 2004
- Added adodb-xmlschema 1.0.2. Thx dan and richard.
- Added new adorecordset_ext_* classes. If ADOdb extension installed for mysql, mysqlt and oci8 (but not oci8po), we use the superfast ADOdb extension code for movenext.
- Added schema support to mssql and odbc_mssql MetaPrimaryKeys().
- Patched MSSQL driver to support PHP NULL and Boolean values while binding the input array parameters in the _query() function. By Stephen Farmer.
- Added support for clob's for mssql, UpdateBlob(). Thx to gfran#directa.com.br
- Added normalize support for postgresql (true=lowercase table name, or false=case-sensitive table names) to MetaColumns($table, $normalize=true).
- PHP5 variant dates in ADO not working. Fixed in adodb-ado.inc.php.
- Constant ADODB_FORCE_NULLS was not working properly for many releases (for GetUpdateSQL). Fixed. Also GetUpdateSQL strips off ORDER BY now - thx Elieser Leão.
- Perf Monitor for oci8 now dynamically highlights optimizer_* params if too high/low.
- Added dsn support to NewADOConnection/ADONewConnection.
- Fixed out of page bounds bug in _adodb_pageexecute_all_rows() Thx to "Sergio Strampelli" sergio#rir.it
- Speedup of movenext for mysql and oci8 drivers.
- Moved debugging code _adodb_debug_execute() to adodb-lib.inc.php.
- Fixed postgresql bytea detection bug. See http://phplens.com/lens/lensforum/msgs.php?id=9849.
- Fixed ibase datetimestamp typo in PHP5. Thx stefan.
- Removed whitespace at end of odbtp drivers.
- Added db2 metaprimarykeys fix.
- Optimizations to MoveNext() for mysql and oci8. Misc speedups to Get* functions.
## 4.50 - 6 July 2004
- Bumped it to 4.50 to avoid confusion with PHP 4.3.x series.
- Added db2 metatables and metacolumns extensions.
- Added alpha PDO driver. Very buggy, only works with odbc.
- Tested mysqli. Set poorAffectedRows = true. Cleaned up movenext() and _fetch().
- PageExecute does not work properly with php5 (return val not a variable). Reported Dmytro Sychevsky sych#php.com.ua. Fixed.
- MetaTables() for mysql, $showschema parameter was not backward compatible with older versions of adodb. Fixed.
- Changed mysql GetOne() to work with mysql 3.23 when using with non-select stmts (e.g. SHOW TABLES).
- Changed TRIG_ prefix to a variable in datadict-oci8.inc.php. Thx to Luca.Gioppo#csi.it.
- New to adodb-time code. We allow you to define your own daylights savings function, adodb_daylight_sv for pre-1970 dates. If the function is defined (somewhere in an include), then you can correct for daylights savings. See http://phplens.com/phpeverywhere/node/view/16#daylightsavings for more info.
- New sqlitepo driver. This is because assoc mode does not work like other drivers in sqlite. Namely, when selecting (joining) multiple tables, in assoc mode the table names are included in the assoc keys in the "sqlite" driver. In "sqlitepo" driver, the table names are stripped from the returned column names. When this results in a conflict, the first field get preference. Contributed by Herman Kuiper herman#ozuzo.net
- Added $forcenull parameter to GetInsertSQL/GetUpdateSQL. Idea by Marco Aurelio Silva.
- More XHTML changes for GetMenu. By Jeremy Evans.
- Fixes some ibase date issues. Thx to stefan bogdan.
- Improvements to mysqli driver to support $ADODB_COUNTRECS.
- Fixed adodb-csvlib.inc.php problem when reading stream from socket. We need to poll stream continiously.
## 4.23 - 16 June 2004
- New interbase/firebird fixes thx to Lester Caine. Driver fixes a problem with getting field names in the result array, and corrects a couple of data conversions. Also we default to dialect3 for firebird. Also ibase sysDate property was wrong. Changed to cast as timestamp.
- The datadict driver is set up to give quoted tables and fields as this was the only way round reserved words being used as field names in TikiWiki. TikiPro is tidying that up, and I hope to be able to produce a build of THAT which uses what I consider proper UPPERCASE field and table names. The conversion of TikiWiki to ADOdb helped in that, but until the database is completely tidied up in TikiPro ...
- Modified _gencachename() to include fetchmode in name hash. This means you should clear your cache directory after installing this release as the cache name algorithm has changed.
- Now Cache* functions work in safe mode, because we do not create sub-directories in the $ADODB_CACHE_DIR in safe mode. In non-safe mode we still create sub-directories. Done by modifying _gencachename().
- Added $gmt parameter (true/false) to UserDate and UserTimeStamp in connection class, to force conversion of input (in local time) to be converted to UTC/GMT.
- Mssql datadict did not support INT types properly (no size param allowed). Added _GetSize() to datadict-mssql.inc.php.
- For borland_ibase, BeginTrans(), changed:
```
$this->_transactionID = $this->_connectionID;
```
to
```
$this->_transactionID = ibase_trans($this->ibasetrans, $this->_connectionID);
```
- Fixed typo in mysqi_field_seek(). Thx to Sh4dow (sh4dow#php.pl).
- LogSQL did not work with Firebird/Interbase. Fixed.
- Postgres: made errorno() handling more consistent. Thx to Michael Jahn, Michael.Jahn#mailbox.tu-dresden.de.
- Added informix patch to better support metatables, metacolumns by "Cecilio Albero" c-albero#eos-i.com
- Cyril Malevanov contributed patch to oci8 to support passing of LOB parameters:
```
$text = 'test test test';
$sql = "declare rs clob; begin :rs := lobinout(:sa0); end;";
$stmt = $conn -> PrepareSP($sql);
$conn -> InParameter($stmt,$text,'sa0', -1, OCI_B_CLOB);
$rs = '';
$conn -> OutParameter($stmt,$rs,'rs', -1, OCI_B_CLOB);
$conn -> Execute($stmt);
echo "return = ".$rs."<br>";</pre>
```
As he says, the LOBs limitations are:
- use OCINewDescriptor before binding
- if Param is IN, uses save() before each execute. This is done automatically for you.
- if Param is OUT, uses load() after each execute. This is done automatically for you.
- when we bind $var as LOB, we create new descriptor and return it as a Bind Result, so if we want to use OUT parameters, we have to store somewhere &$var to load() data from LOB to it.
- IN OUT params are not working now (should not be a big problem to fix it)
- now mass binding not working too (I've wrote about it before)</pre>
- Simplified Connect() and PConnect() error handling.
- When extension not loaded, Connect() and PConnect() will return null. On connect error, the fns will return false.
- CacheGetArray() added to code.
- Added Init() to adorecordset_empty().
- Changed postgres64 driver, MetaColumns() to not strip off quotes in default value if :: detected (type-casting of default).
- Added test: if (!defined('ADODB_DIR')) die(). Useful to prevent hackers from detecting file paths.
- Changed metaTablesSQL to ignore Postgres 7.4 information schemas (sql_*).
- New polish language file by Grzegorz Pacan
- Added support for UNION in _adodb_getcount().
- Added security check for ADODB_DIR to limit path disclosure issues. Requested by postnuke team.
- Added better error message support to oracle driver. Thx to Gaetano Giunta.
- Added showSchema support to mysql.
- Bind in oci8 did not handle $name=false properly. Fixed.
- If extension not loaded, Connect(), PConnect(), NConnect() will return null.
## 4.22 - 15 Apr 2004
- Moved docs to own adodb/docs folder.
- Fixed session bug when quoting compressed/encrypted data in Replace().
- Netezza Driver and LDAP drivers contributed by Josh Eldridge.
- GetMenu now uses rtrim() on values instead of trim().
- Changed MetaColumnNames to return an associative array, keys being the field names in uppercase.
- Suggested fix to adodb-ado.inc.php affected_rows to support PHP5 variants. Thx to Alexios Fakos.
- Contributed bulgarian language file by Valentin Sheiretsky valio#valio.eu.org.
- Contributed romanian language file by stefan bogdan.
- GetInsertSQL now checks for table name (string) in $rs, and will create a recordset for that table automatically. Contributed by Walt Boring. Also added OCI_B_BLOB in bind on Walt's request - hope it doesn't break anything :-)
- Some minor postgres speedups in `_initrs()`.
- ChangeTableSQL checks now if MetaColumns returns empty. Thx Jason Judge.
- Added ADOConnection::Time(), returns current database time in unix timestamp format, or false.
## 4.21 - 20 Mar 2004
- We no longer in SelectLimit for VFP driver add SELECT TOP X unless an ORDER BY exists.
- Pim Koeman contributed dutch language file adodb-nl.inc.php.
- Rick Hickerson added CLOB support to db2 datadict.
- Added odbtp driver. Thx to "stefan bogdan" sbogdan#rsb.ro.
- Changed PrepareSP() 2nd parameter, $cursor, to default to true (formerly false). Fixes oci8 backward compat problems with OUT params.
- Fixed month calculation error in adodb-time.inc.php. 2102-June-01 appeared as 2102-May-32.
- Updated PHP5 RC1 iterator support. API changed, hasMore() renamed to valid().
- Changed internal format of serialized cache recordsets. As we store a version number, this should be backward compatible.
- Error handling when driver file not found was flawed in ADOLoadCode(). Fixed.
## 4.20 - 27 Feb 2004
- Updated to AXMLS 1.01.
- MetaForeignKeys for postgres7 modified by Edward Jaramilla, works on pg 7.4.
- Now numbers accepts function calls or sequences for GetInsertSQL/GetUpdateSQL numeric fields.
- Changed quotes of 'delete from $perf_table' to "". Thx Kehui (webmaster#kehui.net)
- Added ServerInfo() for ifx, and putenv trim fix. Thx Fernando Ortiz.
- Added addq(), which is analogous to addslashes().
- Tested with php5b4. Fix some php5 compat problems with exceptions and sybase.
- Carl-Christian Salvesen added patch to mssql _query to support binds greater than 4000 chars.
- Mike suggested patch to PHP5 exception handler. $errno must be numeric.
- Added double quotes (") to ADODB_TABLE_REGEX.
- For oci8, Prepare(...,$cursor), $cursor's meaning was accidentally inverted in 4.11. This causes problems with ExecuteCursor() too, which calls Prepare() internally. Thx to William Lovaton.
- Now dateHasTime property in connection object renamed to datetime for consistency. This could break bc.
- Csongor Halmai reports that db2 SelectLimit with input array is not working. Fixed..
## 4.11 - 27 Jan 2004
- Csongor Halmai reports db2 binding not working. Reverted back to emulated binding.
- Dan Cech modifies datadict code. Adds support for DropIndex. Minor cleanups.
- Table misspelt in perf-oci8.inc.php. Changed v$conn_cache_advice to v$db_cache_advice. Reported by Steve W.
- UserTimeStamp and DBTimeStamp did not handle YYYYMMDDHHMMSS format properly. Reported by Mike Muir. Fixed.
- Changed oci8 Prepare(). Does not auto-allocate OCINewCursor automatically, unless 2nd param is set to true. This will break backward compat, if Prepare/Execute is used instead of ExecuteCursor. Reported by Chris Jones.
- Added InParameter() and OutParameter(). Wrapper functions to Parameter(), but nicer because they are self-documenting.
- Added 'R' handling in ActualType() to datadict-mysql.inc.php
- Added ADOConnection::SerializableRS($rs). Returns a recordset that can be serialized in a session.
- Added "Run SQL" to performance UI().
- Misc spelling corrections in adodb-mysqli.inc.php, adodb-oci8.inc.php and datadict-oci8.inc.php, from Heinz Hombergs.
- MetaIndexes() for ibase contributed by Heinz Hombergs.
## 4.10 - 12 Jan 2004
- Dan Cech contributed extensive changes to data dictionary to support name quoting (with `\``), and drop table/index.
- Informix added cursorType property. Default remains IFX_SCROLL, but you can change to 0 (non-scrollable cursor) for performance.
- Added ADODB_View_PrimaryKeys() for returning view primary keys to MetaPrimaryKeys().
- Simplified chinese file, adodb-cn.inc.php from cysoft.
- Added check for ctype_alnum in adodb-datadict.inc.php. Thx to Jason Judge.
- Added connection parameter to ibase Prepare(). Fix by Daniel Hassan.
- Added nameQuote for quoting identifiers and names to connection obj. Requested by Jason Judge. Also the data dictionary parser now detects `field name` and generates column names with spaces correctly.
- BOOL type not recognised correctly as L. Fixed.
- Fixed paths in ADODB_DIR for session files, and back-ported it to 4.05 (15 Dec 2003)
- Added Schema to postgresql MetaTables. Thx to col#gear.hu
- Empty postgresql recordsets that had blob fields did not set EOF properly. Fixed.
- CacheSelectLimit internal parameters to SelectLimit were wrong. Thx to Nio.
- Modified adodb_pr() and adodb_backtrace() to support command-line usage (eg. no html).
- Fixed some fr and it lang errors. Thx to Gaetano G.
- Added contrib directory, with adodb rs to xmlrpc convertor by Gaetano G.
- Fixed array recordset bugs when `_skiprow1` is true. Thx to Gaetano G.
- Fixed pivot table code when count is false.
## 4.05 - 13 Dec 2003
- Added MetaIndexes to data-dict code - thx to Dan Cech.
- Rewritten session code by Ross Smith. Moved code to adodb/session directory.
- Added function exists check on connecting to most drivers, so we don't crash with the unknown function error.
- Smart Transactions failed with GenID() when it no seq table has been created because the sql statement fails. Fix by Mark Newnham.
- Added $db->length, which holds name of function that returns strlen.
- Fixed error handling for bad driver in ADONewConnection - passed too few params to error-handler.
- Datadict did not handle types like 16.0 properly in _GetSize. Fixed.
- Oci8 driver SelectLimit() bug &= instead of =& used. Thx to Swen Thümmler.
- Jesse Mullan suggested not flushing outp when output buffering enabled. Due to Apache 2.0 bug. Added.
- MetaTables/MetaColumns return ref bug with PHP5 fixed in adodb-datadict.inc.php.
- New mysqli driver contributed by Arjen de Rijke. Based on adodb 3.40 driver. Then jlim added BeginTrans, CommitTrans, RollbackTrans, IfNull, SQLDate. Also fixed return ref bug.
- $ADODB_FLUSH added, if true then force flush in debugging outp. Default is false. In earlier versions, outp defaulted to flush, which is not compat with apache 2.0.
- Mysql driver's GenID() function did not work when when sql logging is on. Fixed.
- $ADODB_SESSION_TBL not declared as global var. Not available if adodb-session.inc.php included in function. Fixed.
- The input array not passed to Execute() in _adodb_getcount(). Fixed.
## 4.04 - 13 Nov 2003
- Switched back to foreach - faster than list-each.
- Fixed bug in ado driver - wiping out $this->fields with date fields.
- Performance Monitor, View SQL, Explain Plan did not work if strlen($SQL)>max($_GET length). Fixed.
- Performance monitor, oci8 driver added memory sort ratio.
- Added random property, returns SQL to generate a floating point number between 0 and 1;
## 4.03 - 6 Nov 2003
- The path to adodb-php4.inc.php and adodb-iterators.inc.php was not setup properly.
- Patched SQLDate in interbase to support hours/mins/secs. Thx to ari kuorikoski.
- Force autorollback for pgsql persistent connections - apparently pgsql did not autorollback properly before 4.3.4. See http://bugs.php.net/bug.php?id=25404
## 4.02 - 5 Nov 2003
- Some errors in adodb_error_pg() fixed. Thx to Styve.
- Spurious Insert_ID() error was generated by LogSQL(). Fixed.
- Insert_ID was interfering with Affected_Rows() and Replace() when LogSQL() enabled. Fixed.
- More foreach loops optimized with list/each.
- Null dates not handled properly in ADO driver (it becomes 31 Dec 1969!).
- Heinz Hombergs contributed patches for mysql MetaColumns - adding scale, made interbase MetaColumns work with firebird/interbase, and added lang/adodb-de.inc.php.
- Added INFORMIXSERVER environment variable.
- Added $ADODB_ANSI_PADDING_OFF for interbase/firebird.
- PHP 5 beta 2 compat check. Foreach (Iterator) support. Exceptions support.
## 4.01 - 23 Oct 2003
- Fixed bug in rs2html(), tohtml.inc.php, that generated blank table cells.
- Fixed insert_id() incorrectly generated when logsql() enabled.
- Modified PostgreSQL _fixblobs to use list/each instead of foreach.
- Informix ErrorNo() implemented correctly.
- Modified several places to use list/each, including GetRowAssoc().
- Added UserTimeStamp() to connection class.
- Added $ADODB_ANSI_PADDING_OFF for oci8po.
## 4.00 - 20 Oct 2003
- Upgraded adodb-xmlschema to 1 Oct 2003 snapshot.
- Fix to rs2html warning message. Thx to Filo.
- Fix for odbc_mssql/mssql SQLDate(), hours was wrong.
- Added MetaColumns and MetaPrimaryKeys for sybase. Thx to Chris Phillipson.
- Added autoquoting to datadict for MySQL and PostgreSQL. Suggestion by Karsten Dambekalns
-88
View File
@@ -1,88 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Access data driver. Requires ODBC. Works only on MS Windows.
*/
if (!defined('_ADODB_ODBC_LAYER')) {
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
if (!defined('_ADODB_ACCESS')) {
define('_ADODB_ACCESS',1);
class ADODB_access extends ADODB_odbc {
var $databaseType = 'access';
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
var $fmtDate = "#Y-m-d#";
var $fmtTimeStamp = "#Y-m-d h:i:sA#"; // note not comma
var $_bindInputArray = false; // strangely enough, setting to true does not work reliably
var $sysDate = "FORMAT(NOW,'yyyy-mm-dd')";
var $sysTimeStamp = 'NOW';
var $hasTransactions = false;
var $upperCase = 'ucase';
function __construct()
{
global $ADODB_EXTENSION;
$ADODB_EXTENSION = false;
parent::__construct();
}
function Time()
{
return time();
}
function BeginTrans() { return false;}
function IfNull( $field, $ifNull )
{
return " IIF(IsNull($field), $ifNull, $field) "; // if Access
}
/*
function MetaTables()
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = odbc_tables($this->_connectionID);
$rs = new ADORecordSet_odbc($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$arr = $rs->GetArray();
//print_pre($arr);
$arr2 = array();
for ($i=0; $i < sizeof($arr); $i++) {
if ($arr[$i][2] && $arr[$i][3] != 'SYSTEM TABLE')
$arr2[] = $arr[$i][2];
}
return $arr2;
}*/
}
class ADORecordSet_access extends ADORecordSet_odbc {
var $databaseType = "access";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}// class
}
-660
View File
@@ -1,660 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft ADO data driver. Requires ADO. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
define("_ADODB_ADO_LAYER", 1 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
class ADODB_ado extends ADOConnection {
var $databaseType = "ado";
var $_bindInputArray = false;
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
var $replaceQuote = "''"; // string to use to replace quotes
var $dataProvider = "ado";
var $hasAffectedRows = true;
var $adoParameterType = 201; // 201 = long varchar, 203=long wide varchar, 205 = long varbinary
var $_affectedRows = false;
var $_thisTransactions;
var $_cursor_type = 3; // 3=adOpenStatic,0=adOpenForwardOnly,1=adOpenKeyset,2=adOpenDynamic
var $_cursor_location = 3; // 2=adUseServer, 3 = adUseClient;
var $_lock_type = -1;
var $_execute_option = -1;
var $poorAffectedRows = true;
var $charPage;
function __construct()
{
$this->_affectedRows = new VARIANT;
}
function ServerInfo()
{
if (!empty($this->_connectionID)) $desc = $this->_connectionID->provider;
return array('description' => $desc, 'version' => '');
}
function _affectedrows()
{
if (PHP_VERSION >= 5) return $this->_affectedRows;
return $this->_affectedRows->value;
}
// you can also pass a connection string like this:
//
// $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB');
function _connect($argHostname, $argUsername, $argPassword, $argProvider= 'MSDASQL')
{
$u = 'UID';
$p = 'PWD';
if (!empty($this->charPage))
$dbc = new COM('ADODB.Connection',null,$this->charPage);
else
$dbc = new COM('ADODB.Connection');
if (! $dbc) return false;
/* special support if provider is mssql or access */
if ($argProvider=='mssql') {
$u = 'User Id'; //User parameter name for OLEDB
$p = 'Password';
$argProvider = "SQLOLEDB"; // SQL Server Provider
// not yet
//if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
//use trusted conection for SQL if username not specified
if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
} else if ($argProvider=='access')
$argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider
if ($argProvider) $dbc->Provider = $argProvider;
if ($argUsername) $argHostname .= ";$u=$argUsername";
if ($argPassword)$argHostname .= ";$p=$argPassword";
if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version");
// @ added below for php 4.0.1 and earlier
@$dbc->Open((string) $argHostname);
$this->_connectionID = $dbc;
$dbc->CursorLocation = $this->_cursor_location;
return $dbc->State > 0;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL')
{
return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider);
}
/*
adSchemaCatalogs = 1,
adSchemaCharacterSets = 2,
adSchemaCollations = 3,
adSchemaColumns = 4,
adSchemaCheckConstraints = 5,
adSchemaConstraintColumnUsage = 6,
adSchemaConstraintTableUsage = 7,
adSchemaKeyColumnUsage = 8,
adSchemaReferentialContraints = 9,
adSchemaTableConstraints = 10,
adSchemaColumnsDomainUsage = 11,
adSchemaIndexes = 12,
adSchemaColumnPrivileges = 13,
adSchemaTablePrivileges = 14,
adSchemaUsagePrivileges = 15,
adSchemaProcedures = 16,
adSchemaSchemata = 17,
adSchemaSQLLanguages = 18,
adSchemaStatistics = 19,
adSchemaTables = 20,
adSchemaTranslations = 21,
adSchemaProviderTypes = 22,
adSchemaViews = 23,
adSchemaViewColumnUsage = 24,
adSchemaViewTableUsage = 25,
adSchemaProcedureParameters = 26,
adSchemaForeignKeys = 27,
adSchemaPrimaryKeys = 28,
adSchemaProcedureColumns = 29,
adSchemaDBInfoKeywords = 30,
adSchemaDBInfoLiterals = 31,
adSchemaCubes = 32,
adSchemaDimensions = 33,
adSchemaHierarchies = 34,
adSchemaLevels = 35,
adSchemaMeasures = 36,
adSchemaProperties = 37,
adSchemaMembers = 38
*/
function MetaTables($ttype = false, $showSchema = false, $mask = false)
{
$arr= array();
$dbc = $this->_connectionID;
$adors=@$dbc->OpenSchema(20);//tables
if ($adors){
$f = $adors->Fields(2);//table/view name
$t = $adors->Fields(3);//table type
while (!$adors->EOF){
$tt=substr($t->value,0,6);
if ($tt!='SYSTEM' && $tt !='ACCESS')
$arr[]=$f->value;
//print $f->value . ' ' . $t->value.'<br>';
$adors->MoveNext();
}
$adors->Close();
}
return $arr;
}
function MetaColumns($table, $normalize=true)
{
$table = strtoupper($table);
$arr = array();
$dbc = $this->_connectionID;
$adors=@$dbc->OpenSchema(4);//tables
if ($adors){
$t = $adors->Fields(2);//table/view name
while (!$adors->EOF){
if (strtoupper($t->Value) == $table) {
$fld = new ADOFieldObject();
$c = $adors->Fields(3);
$fld->name = $c->Value;
$fld->type = 'CHAR'; // cannot discover type in ADO!
$fld->max_length = -1;
$arr[strtoupper($fld->name)]=$fld;
}
$adors->MoveNext();
}
$adors->Close();
}
$false = false;
return empty($arr) ? $false : $arr;
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
{
$dbc = $this->_connectionID;
$false = false;
// return rs
if ($inputarr) {
if (!empty($this->charPage))
$oCmd = new COM('ADODB.Command',null,$this->charPage);
else
$oCmd = new COM('ADODB.Command');
$oCmd->ActiveConnection = $dbc;
$oCmd->CommandText = $sql;
$oCmd->CommandType = 1;
// Map by http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmthcreateparam.asp
// Check issue http://bugs.php.net/bug.php?id=40664 !!!
while(list(, $val) = each($inputarr)) {
$type = gettype($val);
$len=strlen($val);
if ($type == 'boolean')
$this->adoParameterType = 11;
else if ($type == 'integer')
$this->adoParameterType = 3;
else if ($type == 'double')
$this->adoParameterType = 5;
elseif ($type == 'string')
$this->adoParameterType = 202;
else if (($val === null) || (!defined($val)))
$len=1;
else
$this->adoParameterType = 130;
// name, type, direction 1 = input, len,
$p = $oCmd->CreateParameter('name',$this->adoParameterType,1,$len,$val);
$oCmd->Parameters->Append($p);
}
$p = false;
$rs = $oCmd->Execute();
$e = $dbc->Errors;
if ($dbc->Errors->Count > 0) return $false;
return $rs;
}
$rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option);
if ($dbc->Errors->Count > 0) return $false;
if (! $rs) return $false;
if ($rs->State == 0) {
$true = true;
return $true; // 0 = adStateClosed means no records returned
}
return $rs;
}
function BeginTrans()
{
if ($this->transOff) return true;
if (isset($this->_thisTransactions))
if (!$this->_thisTransactions) return false;
else {
$o = $this->_connectionID->Properties("Transaction DDL");
$this->_thisTransactions = $o ? true : false;
if (!$o) return false;
}
@$this->_connectionID->BeginTrans();
$this->transCnt += 1;
return true;
}
function CommitTrans($ok=true)
{
if (!$ok) return $this->RollbackTrans();
if ($this->transOff) return true;
@$this->_connectionID->CommitTrans();
if ($this->transCnt) @$this->transCnt -= 1;
return true;
}
function RollbackTrans() {
if ($this->transOff) return true;
@$this->_connectionID->RollbackTrans();
if ($this->transCnt) @$this->transCnt -= 1;
return true;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if (!$this->_connectionID) return "No connection established";
$errc = $this->_connectionID->Errors;
if (!$errc) return "No Errors object found";
if ($errc->Count == 0) return '';
$err = $errc->Item($errc->Count-1);
return $err->Description;
}
function ErrorNo()
{
$errc = $this->_connectionID->Errors;
if ($errc->Count == 0) return 0;
$err = $errc->Item($errc->Count-1);
return $err->NativeError;
}
// returns true or false
function _close()
{
if ($this->_connectionID) $this->_connectionID->Close();
$this->_connectionID = false;
return true;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_ado extends ADORecordSet {
var $bind = false;
var $databaseType = "ado";
var $dataProvider = "ado";
var $_tarr = false; // caches the types
var $_flds; // and field objects
var $canSeek = true;
var $hideErrors = true;
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id,$mode);
}
// returns the field object
function FetchField($fieldOffset = -1) {
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
$rs = $this->_queryID;
$f = $rs->Fields($fieldOffset);
$o->name = $f->Name;
$t = $f->Type;
$o->type = $this->MetaType($t);
$o->max_length = $f->DefinedSize;
$o->ado_type = $t;
//print "off=$off name=$o->name type=$o->type len=$o->max_length<br>";
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
$rs = $this->_queryID;
$this->_numOfRows = $rs->RecordCount;
$f = $rs->Fields;
$this->_numOfFields = $f->Count;
}
// should only be used to move forward as we normally use forward-only cursors
function _seek($row)
{
$rs = $this->_queryID;
// absoluteposition doesn't work -- my maths is wrong ?
// $rs->AbsolutePosition->$row-2;
// return true;
if ($this->_currentRow > $row) return false;
@$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
return true;
}
/*
OLEDB types
enum DBTYPEENUM
{ DBTYPE_EMPTY = 0,
DBTYPE_NULL = 1,
DBTYPE_I2 = 2,
DBTYPE_I4 = 3,
DBTYPE_R4 = 4,
DBTYPE_R8 = 5,
DBTYPE_CY = 6,
DBTYPE_DATE = 7,
DBTYPE_BSTR = 8,
DBTYPE_IDISPATCH = 9,
DBTYPE_ERROR = 10,
DBTYPE_BOOL = 11,
DBTYPE_VARIANT = 12,
DBTYPE_IUNKNOWN = 13,
DBTYPE_DECIMAL = 14,
DBTYPE_UI1 = 17,
DBTYPE_ARRAY = 0x2000,
DBTYPE_BYREF = 0x4000,
DBTYPE_I1 = 16,
DBTYPE_UI2 = 18,
DBTYPE_UI4 = 19,
DBTYPE_I8 = 20,
DBTYPE_UI8 = 21,
DBTYPE_GUID = 72,
DBTYPE_VECTOR = 0x1000,
DBTYPE_RESERVED = 0x8000,
DBTYPE_BYTES = 128,
DBTYPE_STR = 129,
DBTYPE_WSTR = 130,
DBTYPE_NUMERIC = 131,
DBTYPE_UDT = 132,
DBTYPE_DBDATE = 133,
DBTYPE_DBTIME = 134,
DBTYPE_DBTIMESTAMP = 135
ADO Types
adEmpty = 0,
adTinyInt = 16,
adSmallInt = 2,
adInteger = 3,
adBigInt = 20,
adUnsignedTinyInt = 17,
adUnsignedSmallInt = 18,
adUnsignedInt = 19,
adUnsignedBigInt = 21,
adSingle = 4,
adDouble = 5,
adCurrency = 6,
adDecimal = 14,
adNumeric = 131,
adBoolean = 11,
adError = 10,
adUserDefined = 132,
adVariant = 12,
adIDispatch = 9,
adIUnknown = 13,
adGUID = 72,
adDate = 7,
adDBDate = 133,
adDBTime = 134,
adDBTimeStamp = 135,
adBSTR = 8,
adChar = 129,
adVarChar = 200,
adLongVarChar = 201,
adWChar = 130,
adVarWChar = 202,
adLongVarWChar = 203,
adBinary = 128,
adVarBinary = 204,
adLongVarBinary = 205,
adChapter = 136,
adFileTime = 64,
adDBFileTime = 137,
adPropVariant = 138,
adVarNumeric = 139
*/
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
if (!is_numeric($t)) return $t;
switch ($t) {
case 0:
case 12: // variant
case 8: // bstr
case 129: //char
case 130: //wc
case 200: // varc
case 202:// varWC
case 128: // bin
case 204: // varBin
case 72: // guid
if ($len <= $this->blobSize) return 'C';
case 201:
case 203:
return 'X';
case 128:
case 204:
case 205:
return 'B';
case 7:
case 133: return 'D';
case 134:
case 135: return 'T';
case 11: return 'L';
case 16:// adTinyInt = 16,
case 2://adSmallInt = 2,
case 3://adInteger = 3,
case 4://adBigInt = 20,
case 17://adUnsignedTinyInt = 17,
case 18://adUnsignedSmallInt = 18,
case 19://adUnsignedInt = 19,
case 20://adUnsignedBigInt = 21,
return 'I';
default: return 'N';
}
}
// time stamp not supported yet
function _fetch()
{
$rs = $this->_queryID;
if (!$rs or $rs->EOF) {
$this->fields = false;
return false;
}
$this->fields = array();
if (!$this->_tarr) {
$tarr = array();
$flds = array();
for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
$f = $rs->Fields($i);
$flds[] = $f;
$tarr[] = $f->Type;
}
// bind types and flds only once
$this->_tarr = $tarr;
$this->_flds = $flds;
}
$t = reset($this->_tarr);
$f = reset($this->_flds);
if ($this->hideErrors) $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null
for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
//echo "<p>",$t,' ';var_dump($f->value); echo '</p>';
switch($t) {
case 135: // timestamp
if (!strlen((string)$f->value)) $this->fields[] = false;
else {
if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value);
// VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00
$val=(float) variant_cast($f->value,VT_R8)*3600*24-2209161600;
else
$val = $f->value;
$this->fields[] = adodb_date('Y-m-d H:i:s',$val);
}
break;
case 133:// A date value (yyyymmdd)
if ($val = $f->value) {
$this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
} else
$this->fields[] = false;
break;
case 7: // adDate
if (!strlen((string)$f->value)) $this->fields[] = false;
else {
if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value);
else $val = $f->value;
if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val);
else $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
}
break;
case 1: // null
$this->fields[] = false;
break;
case 6: // currency is not supported properly;
ADOConnection::outp( '<b>'.$f->Name.': currency type not supported by PHP</b>');
$this->fields[] = (float) $f->value;
break;
case 11: //BIT;
$val = "";
if(is_bool($f->value)) {
if($f->value==true) $val = 1;
else $val = 0;
}
if(is_null($f->value)) $val = null;
$this->fields[] = $val;
break;
default:
$this->fields[] = $f->value;
break;
}
//print " $f->value $t, ";
$f = next($this->_flds);
$t = next($this->_tarr);
} // for
if ($this->hideErrors) error_reporting($olde);
@$rs->MoveNext(); // @ needed for some versions of PHP!
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc();
}
return true;
}
function NextRecordSet()
{
$rs = $this->_queryID;
$this->_queryID = $rs->NextRecordSet();
//$this->_queryID = $this->_QueryId->NextRecordSet();
if ($this->_queryID == null) return false;
$this->_currentRow = -1;
$this->_currentPage = -1;
$this->bind = false;
$this->fields = false;
$this->_flds = false;
$this->_tarr = false;
$this->_inited = false;
$this->Init();
return true;
}
function _close() {
$this->_flds = false;
@$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
$this->_queryID = false;
}
}
-708
View File
@@ -1,708 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft ADO data driver. Requires ADO. Works only on MS Windows. PHP5 compat version.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
define("_ADODB_ADO_LAYER", 1 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
class ADODB_ado extends ADOConnection {
var $databaseType = "ado";
var $_bindInputArray = false;
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
var $replaceQuote = "''"; // string to use to replace quotes
var $dataProvider = "ado";
var $hasAffectedRows = true;
var $adoParameterType = 201; // 201 = long varchar, 203=long wide varchar, 205 = long varbinary
var $_affectedRows = false;
var $_thisTransactions;
var $_cursor_type = 3; // 3=adOpenStatic,0=adOpenForwardOnly,1=adOpenKeyset,2=adOpenDynamic
var $_cursor_location = 3; // 2=adUseServer, 3 = adUseClient;
var $_lock_type = -1;
var $_execute_option = -1;
var $poorAffectedRows = true;
var $charPage;
function __construct()
{
$this->_affectedRows = new VARIANT;
}
function ServerInfo()
{
if (!empty($this->_connectionID)) $desc = $this->_connectionID->provider;
return array('description' => $desc, 'version' => '');
}
function _affectedrows()
{
if (PHP_VERSION >= 5) return $this->_affectedRows;
return $this->_affectedRows->value;
}
// you can also pass a connection string like this:
//
// $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB');
function _connect($argHostname, $argUsername, $argPassword,$argDBorProvider, $argProvider= '')
{
// two modes
// - if $argProvider is empty, we assume that $argDBorProvider holds provider -- this is for backward compat
// - if $argProvider is not empty, then $argDBorProvider holds db
if ($argProvider) {
$argDatabasename = $argDBorProvider;
} else {
$argDatabasename = '';
if ($argDBorProvider) $argProvider = $argDBorProvider;
else if (stripos($argHostname,'PROVIDER') === false) /* full conn string is not in $argHostname */
$argProvider = 'MSDASQL';
}
try {
$u = 'UID';
$p = 'PWD';
if (!empty($this->charPage))
$dbc = new COM('ADODB.Connection',null,$this->charPage);
else
$dbc = new COM('ADODB.Connection');
if (! $dbc) return false;
/* special support if provider is mssql or access */
if ($argProvider=='mssql') {
$u = 'User Id'; //User parameter name for OLEDB
$p = 'Password';
$argProvider = "SQLOLEDB"; // SQL Server Provider
// not yet
//if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
//use trusted conection for SQL if username not specified
if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
} else if ($argProvider=='access')
$argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider
if ($argProvider) $dbc->Provider = $argProvider;
if ($argProvider) $argHostname = "PROVIDER=$argProvider;DRIVER={SQL Server};SERVER=$argHostname";
if ($argDatabasename) $argHostname .= ";DATABASE=$argDatabasename";
if ($argUsername) $argHostname .= ";$u=$argUsername";
if ($argPassword)$argHostname .= ";$p=$argPassword";
if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version");
// @ added below for php 4.0.1 and earlier
@$dbc->Open((string) $argHostname);
$this->_connectionID = $dbc;
$dbc->CursorLocation = $this->_cursor_location;
return $dbc->State > 0;
} catch (exception $e) {
if ($this->debug) echo "<pre>",$argHostname,"\n",$e,"</pre>\n";
}
return false;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL')
{
return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider);
}
/*
adSchemaCatalogs = 1,
adSchemaCharacterSets = 2,
adSchemaCollations = 3,
adSchemaColumns = 4,
adSchemaCheckConstraints = 5,
adSchemaConstraintColumnUsage = 6,
adSchemaConstraintTableUsage = 7,
adSchemaKeyColumnUsage = 8,
adSchemaReferentialContraints = 9,
adSchemaTableConstraints = 10,
adSchemaColumnsDomainUsage = 11,
adSchemaIndexes = 12,
adSchemaColumnPrivileges = 13,
adSchemaTablePrivileges = 14,
adSchemaUsagePrivileges = 15,
adSchemaProcedures = 16,
adSchemaSchemata = 17,
adSchemaSQLLanguages = 18,
adSchemaStatistics = 19,
adSchemaTables = 20,
adSchemaTranslations = 21,
adSchemaProviderTypes = 22,
adSchemaViews = 23,
adSchemaViewColumnUsage = 24,
adSchemaViewTableUsage = 25,
adSchemaProcedureParameters = 26,
adSchemaForeignKeys = 27,
adSchemaPrimaryKeys = 28,
adSchemaProcedureColumns = 29,
adSchemaDBInfoKeywords = 30,
adSchemaDBInfoLiterals = 31,
adSchemaCubes = 32,
adSchemaDimensions = 33,
adSchemaHierarchies = 34,
adSchemaLevels = 35,
adSchemaMeasures = 36,
adSchemaProperties = 37,
adSchemaMembers = 38
*/
function MetaTables($ttype = false, $showSchema = false, $mask = false)
{
$arr= array();
$dbc = $this->_connectionID;
$adors=@$dbc->OpenSchema(20);//tables
if ($adors){
$f = $adors->Fields(2);//table/view name
$t = $adors->Fields(3);//table type
while (!$adors->EOF){
$tt=substr($t->value,0,6);
if ($tt!='SYSTEM' && $tt !='ACCESS')
$arr[]=$f->value;
//print $f->value . ' ' . $t->value.'<br>';
$adors->MoveNext();
}
$adors->Close();
}
return $arr;
}
function MetaColumns($table, $normalize=true)
{
$table = strtoupper($table);
$arr= array();
$dbc = $this->_connectionID;
$adors=@$dbc->OpenSchema(4);//tables
if ($adors){
$t = $adors->Fields(2);//table/view name
while (!$adors->EOF){
if (strtoupper($t->Value) == $table) {
$fld = new ADOFieldObject();
$c = $adors->Fields(3);
$fld->name = $c->Value;
$fld->type = 'CHAR'; // cannot discover type in ADO!
$fld->max_length = -1;
$arr[strtoupper($fld->name)]=$fld;
}
$adors->MoveNext();
}
$adors->Close();
}
return $arr;
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
{
try { // In PHP5, all COM errors are exceptions, so to maintain old behaviour...
$dbc = $this->_connectionID;
// return rs
$false = false;
if ($inputarr) {
if (!empty($this->charPage))
$oCmd = new COM('ADODB.Command',null,$this->charPage);
else
$oCmd = new COM('ADODB.Command');
$oCmd->ActiveConnection = $dbc;
$oCmd->CommandText = $sql;
$oCmd->CommandType = 1;
while(list(, $val) = each($inputarr)) {
$type = gettype($val);
$len=strlen($val);
if ($type == 'boolean')
$this->adoParameterType = 11;
else if ($type == 'integer')
$this->adoParameterType = 3;
else if ($type == 'double')
$this->adoParameterType = 5;
elseif ($type == 'string')
$this->adoParameterType = 202;
else if (($val === null) || (!defined($val)))
$len=1;
else
$this->adoParameterType = 130;
// name, type, direction 1 = input, len,
$p = $oCmd->CreateParameter('name',$this->adoParameterType,1,$len,$val);
$oCmd->Parameters->Append($p);
}
$p = false;
$rs = $oCmd->Execute();
$e = $dbc->Errors;
if ($dbc->Errors->Count > 0) return $false;
return $rs;
}
$rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option);
if ($dbc->Errors->Count > 0) return $false;
if (! $rs) return $false;
if ($rs->State == 0) {
$true = true;
return $true; // 0 = adStateClosed means no records returned
}
return $rs;
} catch (exception $e) {
}
return $false;
}
function BeginTrans()
{
if ($this->transOff) return true;
if (isset($this->_thisTransactions))
if (!$this->_thisTransactions) return false;
else {
$o = $this->_connectionID->Properties("Transaction DDL");
$this->_thisTransactions = $o ? true : false;
if (!$o) return false;
}
@$this->_connectionID->BeginTrans();
$this->transCnt += 1;
return true;
}
function CommitTrans($ok=true)
{
if (!$ok) return $this->RollbackTrans();
if ($this->transOff) return true;
@$this->_connectionID->CommitTrans();
if ($this->transCnt) @$this->transCnt -= 1;
return true;
}
function RollbackTrans() {
if ($this->transOff) return true;
@$this->_connectionID->RollbackTrans();
if ($this->transCnt) @$this->transCnt -= 1;
return true;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if (!$this->_connectionID) return "No connection established";
$errmsg = '';
try {
$errc = $this->_connectionID->Errors;
if (!$errc) return "No Errors object found";
if ($errc->Count == 0) return '';
$err = $errc->Item($errc->Count-1);
$errmsg = $err->Description;
}catch(exception $e) {
}
return $errmsg;
}
function ErrorNo()
{
$errc = $this->_connectionID->Errors;
if ($errc->Count == 0) return 0;
$err = $errc->Item($errc->Count-1);
return $err->NativeError;
}
// returns true or false
function _close()
{
if ($this->_connectionID) $this->_connectionID->Close();
$this->_connectionID = false;
return true;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_ado extends ADORecordSet {
var $bind = false;
var $databaseType = "ado";
var $dataProvider = "ado";
var $_tarr = false; // caches the types
var $_flds; // and field objects
var $canSeek = true;
var $hideErrors = true;
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id,$mode);
}
// returns the field object
function FetchField($fieldOffset = -1) {
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
$rs = $this->_queryID;
if (!$rs) return false;
$f = $rs->Fields($fieldOffset);
$o->name = $f->Name;
$t = $f->Type;
$o->type = $this->MetaType($t);
$o->max_length = $f->DefinedSize;
$o->ado_type = $t;
//print "off=$off name=$o->name type=$o->type len=$o->max_length<br>";
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
$rs = $this->_queryID;
try {
$this->_numOfRows = $rs->RecordCount;
} catch (Exception $e) {
$this->_numOfRows = -1;
}
$f = $rs->Fields;
$this->_numOfFields = $f->Count;
}
// should only be used to move forward as we normally use forward-only cursors
function _seek($row)
{
$rs = $this->_queryID;
// absoluteposition doesn't work -- my maths is wrong ?
// $rs->AbsolutePosition->$row-2;
// return true;
if ($this->_currentRow > $row) return false;
@$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
return true;
}
/*
OLEDB types
enum DBTYPEENUM
{ DBTYPE_EMPTY = 0,
DBTYPE_NULL = 1,
DBTYPE_I2 = 2,
DBTYPE_I4 = 3,
DBTYPE_R4 = 4,
DBTYPE_R8 = 5,
DBTYPE_CY = 6,
DBTYPE_DATE = 7,
DBTYPE_BSTR = 8,
DBTYPE_IDISPATCH = 9,
DBTYPE_ERROR = 10,
DBTYPE_BOOL = 11,
DBTYPE_VARIANT = 12,
DBTYPE_IUNKNOWN = 13,
DBTYPE_DECIMAL = 14,
DBTYPE_UI1 = 17,
DBTYPE_ARRAY = 0x2000,
DBTYPE_BYREF = 0x4000,
DBTYPE_I1 = 16,
DBTYPE_UI2 = 18,
DBTYPE_UI4 = 19,
DBTYPE_I8 = 20,
DBTYPE_UI8 = 21,
DBTYPE_GUID = 72,
DBTYPE_VECTOR = 0x1000,
DBTYPE_RESERVED = 0x8000,
DBTYPE_BYTES = 128,
DBTYPE_STR = 129,
DBTYPE_WSTR = 130,
DBTYPE_NUMERIC = 131,
DBTYPE_UDT = 132,
DBTYPE_DBDATE = 133,
DBTYPE_DBTIME = 134,
DBTYPE_DBTIMESTAMP = 135
ADO Types
adEmpty = 0,
adTinyInt = 16,
adSmallInt = 2,
adInteger = 3,
adBigInt = 20,
adUnsignedTinyInt = 17,
adUnsignedSmallInt = 18,
adUnsignedInt = 19,
adUnsignedBigInt = 21,
adSingle = 4,
adDouble = 5,
adCurrency = 6,
adDecimal = 14,
adNumeric = 131,
adBoolean = 11,
adError = 10,
adUserDefined = 132,
adVariant = 12,
adIDispatch = 9,
adIUnknown = 13,
adGUID = 72,
adDate = 7,
adDBDate = 133,
adDBTime = 134,
adDBTimeStamp = 135,
adBSTR = 8,
adChar = 129,
adVarChar = 200,
adLongVarChar = 201,
adWChar = 130,
adVarWChar = 202,
adLongVarWChar = 203,
adBinary = 128,
adVarBinary = 204,
adLongVarBinary = 205,
adChapter = 136,
adFileTime = 64,
adDBFileTime = 137,
adPropVariant = 138,
adVarNumeric = 139
*/
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
if (!is_numeric($t)) return $t;
switch ($t) {
case 0:
case 12: // variant
case 8: // bstr
case 129: //char
case 130: //wc
case 200: // varc
case 202:// varWC
case 128: // bin
case 204: // varBin
case 72: // guid
if ($len <= $this->blobSize) return 'C';
case 201:
case 203:
return 'X';
case 128:
case 204:
case 205:
return 'B';
case 7:
case 133: return 'D';
case 134:
case 135: return 'T';
case 11: return 'L';
case 16:// adTinyInt = 16,
case 2://adSmallInt = 2,
case 3://adInteger = 3,
case 4://adBigInt = 20,
case 17://adUnsignedTinyInt = 17,
case 18://adUnsignedSmallInt = 18,
case 19://adUnsignedInt = 19,
case 20://adUnsignedBigInt = 21,
return 'I';
default: return 'N';
}
}
// time stamp not supported yet
function _fetch()
{
$rs = $this->_queryID;
if (!$rs or $rs->EOF) {
$this->fields = false;
return false;
}
$this->fields = array();
if (!$this->_tarr) {
$tarr = array();
$flds = array();
for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
$f = $rs->Fields($i);
$flds[] = $f;
$tarr[] = $f->Type;
}
// bind types and flds only once
$this->_tarr = $tarr;
$this->_flds = $flds;
}
$t = reset($this->_tarr);
$f = reset($this->_flds);
if ($this->hideErrors) $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null
for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
//echo "<p>",$t,' ';var_dump($f->value); echo '</p>';
switch($t) {
case 135: // timestamp
if (!strlen((string)$f->value)) $this->fields[] = false;
else {
if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value);
// VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00
$val= (float) variant_cast($f->value,VT_R8)*3600*24-2209161600;
else
$val = $f->value;
$this->fields[] = adodb_date('Y-m-d H:i:s',$val);
}
break;
case 133:// A date value (yyyymmdd)
if ($val = $f->value) {
$this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
} else
$this->fields[] = false;
break;
case 7: // adDate
if (!strlen((string)$f->value)) $this->fields[] = false;
else {
if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value);
else $val = $f->value;
if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val);
else $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
}
break;
case 1: // null
$this->fields[] = false;
break;
case 20:
case 21: // bigint (64 bit)
$this->fields[] = (float) $f->value; // if 64 bit PHP, could use (int)
break;
case 6: // currency is not supported properly;
ADOConnection::outp( '<b>'.$f->Name.': currency type not supported by PHP</b>');
$this->fields[] = (float) $f->value;
break;
case 11: //BIT;
$val = "";
if(is_bool($f->value)) {
if($f->value==true) $val = 1;
else $val = 0;
}
if(is_null($f->value)) $val = null;
$this->fields[] = $val;
break;
default:
$this->fields[] = $f->value;
break;
}
//print " $f->value $t, ";
$f = next($this->_flds);
$t = next($this->_tarr);
} // for
if ($this->hideErrors) error_reporting($olde);
@$rs->MoveNext(); // @ needed for some versions of PHP!
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc();
}
return true;
}
function NextRecordSet()
{
$rs = $this->_queryID;
$this->_queryID = $rs->NextRecordSet();
//$this->_queryID = $this->_QueryId->NextRecordSet();
if ($this->_queryID == null) return false;
$this->_currentRow = -1;
$this->_currentPage = -1;
$this->bind = false;
$this->fields = false;
$this->_flds = false;
$this->_tarr = false;
$this->_inited = false;
$this->Init();
return true;
}
function _close() {
$this->_flds = false;
try {
@$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
} catch (Exception $e) {
}
$this->_queryID = false;
}
}
@@ -1,50 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Access ADO data driver. Requires ADO and ODBC. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ADO_LAYER')) {
if (PHP_VERSION >= 5) include(ADODB_DIR."/drivers/adodb-ado5.inc.php");
else include(ADODB_DIR."/drivers/adodb-ado.inc.php");
}
class ADODB_ado_access extends ADODB_ado {
var $databaseType = 'ado_access';
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
var $fmtDate = "#Y-m-d#";
var $fmtTimeStamp = "#Y-m-d h:i:sA#";// note no comma
var $sysDate = "FORMAT(NOW,'yyyy-mm-dd')";
var $sysTimeStamp = 'NOW';
var $upperCase = 'ucase';
/*function BeginTrans() { return false;}
function CommitTrans() { return false;}
function RollbackTrans() { return false;}*/
}
class ADORecordSet_ado_access extends ADORecordSet_ado {
var $databaseType = "ado_access";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
@@ -1,150 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft SQL Server ADO data driver. Requires ADO and MSSQL client.
Works only on MS Windows.
Warning: Some versions of PHP (esp PHP4) leak memory when ADO/COM is used.
Please check http://bugs.php.net/ for more info.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ADO_LAYER')) {
if (PHP_VERSION >= 5) include(ADODB_DIR."/drivers/adodb-ado5.inc.php");
else include(ADODB_DIR."/drivers/adodb-ado.inc.php");
}
class ADODB_ado_mssql extends ADODB_ado {
var $databaseType = 'ado_mssql';
var $hasTop = 'top';
var $hasInsertID = true;
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
var $sysTimeStamp = 'GetDate()';
var $leftOuter = '*=';
var $rightOuter = '=*';
var $ansiOuter = true; // for mssql7 or later
var $substr = "substring";
var $length = 'len';
var $_dropSeqSQL = "drop table %s";
//var $_inTransaction = 1; // always open recordsets, so no transaction problems.
function _insertid()
{
return $this->GetOne('select SCOPE_IDENTITY()');
}
function _affectedrows()
{
return $this->GetOne('select @@rowcount');
}
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
$this->Execute('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
return;
}
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
function qstr($s,$magic_quotes=false)
{
$s = ADOConnection::qstr($s, $magic_quotes);
return str_replace("\0", "\\\\000", $s);
}
function MetaColumns($table, $normalize=true)
{
$table = strtoupper($table);
$arr= array();
$dbc = $this->_connectionID;
$osoptions = array();
$osoptions[0] = null;
$osoptions[1] = null;
$osoptions[2] = $table;
$osoptions[3] = null;
$adors=@$dbc->OpenSchema(4, $osoptions);//tables
if ($adors){
while (!$adors->EOF){
$fld = new ADOFieldObject();
$c = $adors->Fields(3);
$fld->name = $c->Value;
$fld->type = 'CHAR'; // cannot discover type in ADO!
$fld->max_length = -1;
$arr[strtoupper($fld->name)]=$fld;
$adors->MoveNext();
}
$adors->Close();
}
$false = false;
return empty($arr) ? $false : $arr;
}
function CreateSequence($seq='adodbseq',$start=1)
{
$this->Execute('BEGIN TRANSACTION adodbseq');
$start -= 1;
$this->Execute("create table $seq (id float(53))");
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
if (!$ok) {
$this->Execute('ROLLBACK TRANSACTION adodbseq');
return false;
}
$this->Execute('COMMIT TRANSACTION adodbseq');
return true;
}
function GenID($seq='adodbseq',$start=1)
{
//$this->debug=1;
$this->Execute('BEGIN TRANSACTION adodbseq');
$ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
if (!$ok) {
$this->Execute("create table $seq (id float(53))");
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
if (!$ok) {
$this->Execute('ROLLBACK TRANSACTION adodbseq');
return false;
}
$this->Execute('COMMIT TRANSACTION adodbseq');
return $start;
}
$num = $this->GetOne("select id from $seq");
$this->Execute('COMMIT TRANSACTION adodbseq');
return $num;
// in old implementation, pre 1.90, we returned GUID...
//return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) AS 'Char'");
}
} // end class
class ADORecordSet_ado_mssql extends ADORecordSet_ado {
var $databaseType = 'ado_mssql';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
-784
View File
@@ -1,784 +0,0 @@
<?php
/*
(c) 2000-2014 John Lim (jlim#natsoft.com.my). All rights reserved.
Portions Copyright (c) 2007-2009, iAnywhere Solutions, Inc.
All rights reserved. All unpublished rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
NOTE: This driver requires the Advantage PHP client libraries, which
can be downloaded for free via:
http://devzone.advantagedatabase.com/dz/content.aspx?key=20
DELPHI FOR PHP USERS:
The following steps can be taken to utilize this driver from the
CodeGear Delphi for PHP product:
1 - See note above, download and install the Advantage PHP client.
2 - Copy the following files to the Delphi for PHP\X.X\php\ext directory:
ace32.dll
axcws32.dll
adsloc32.dll
php_advantage.dll (rename the existing php_advantage.dll.5.x.x file)
3 - Add the following line to the Delphi for PHP\X.X\php\php.ini.template file:
extension=php_advantage.dll
4 - To use: enter "ads" as the DriverName on a connection component, and set
a Host property similar to "DataDirectory=c:\". See the Advantage PHP
help file topic for ads_connect for details on connection path options
and formatting.
5 - (optional) - Modify the Delphi for PHP\X.X\vcl\packages\database.packages.php
file and add ads to the list of strings returned when registering the
Database object's DriverName property.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
define("_ADODB_ADS_LAYER", 2 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
class ADODB_ads extends ADOConnection {
var $databaseType = "ads";
var $fmt = "'m-d-Y'";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $concat_operator = '';
var $replaceQuote = "''"; // string to use to replace quotes
var $dataProvider = "ads";
var $hasAffectedRows = true;
var $binmode = ODBC_BINMODE_RETURN;
var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
// breaking backward-compat
//var $longreadlen = 8000; // default number of chars to return for a Blob/Long field
var $_bindInputArray = false;
var $curmode = SQL_CUR_USE_DRIVER; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
var $_genSeqSQL = "create table %s (id integer)";
var $_autocommit = true;
var $_haserrorfunctions = true;
var $_has_stupid_odbc_fetch_api_change = true;
var $_lastAffectedRows = 0;
var $uCaseTables = true; // for meta* functions, uppercase table names
function __construct()
{
$this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
}
// returns true or false
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('ads_connect')) return null;
if ($this->debug && $argDatabasename && $this->databaseType != 'vfp') {
ADOConnection::outp("For Advantage Connect(), $argDatabasename is not used. Place dsn in 1st parameter.");
}
if (isset($php_errormsg)) $php_errormsg = '';
if ($this->curmode === false) $this->_connectionID = ads_connect($argDSN,$argUsername,$argPassword);
else $this->_connectionID = ads_connect($argDSN,$argUsername,$argPassword,$this->curmode);
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
return $this->_connectionID != false;
}
// returns true or false
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('ads_connect')) return null;
if (isset($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
if ($this->debug && $argDatabasename) {
ADOConnection::outp("For PConnect(), $argDatabasename is not used. Place dsn in 1st parameter.");
}
// print "dsn=$argDSN u=$argUsername p=$argPassword<br>"; flush();
if ($this->curmode === false) $this->_connectionID = ads_connect($argDSN,$argUsername,$argPassword);
else $this->_connectionID = ads_pconnect($argDSN,$argUsername,$argPassword,$this->curmode);
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
if ($this->_connectionID && $this->autoRollback) @ads_rollback($this->_connectionID);
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
return $this->_connectionID != false;
}
// returns the Server version and Description
function ServerInfo()
{
if (!empty($this->host) && ADODB_PHPVER >= 0x4300) {
$stmt = $this->Prepare('EXECUTE PROCEDURE sp_mgGetInstallInfo()');
$res = $this->Execute($stmt);
if(!$res)
print $this->ErrorMsg();
else{
$ret["version"]= $res->fields[3];
$ret["description"]="Advantage Database Server";
return $ret;
}
}
else {
return ADOConnection::ServerInfo();
}
}
// returns true or false
function CreateSequence($seqname = 'adodbseq', $start = 1)
{
$res = $this->Execute("CREATE TABLE $seqname ( ID autoinc( 1 ) ) IN DATABASE");
if(!$res){
print $this->ErrorMsg();
return false;
}
else
return true;
}
// returns true or false
function DropSequence($seqname = 'adodbseq')
{
$res = $this->Execute("DROP TABLE $seqname");
if(!$res){
print $this->ErrorMsg();
return false;
}
else
return true;
}
// returns the generated ID or false
// checks if the table already exists, else creates the table and inserts a record into the table
// and gets the ID number of the last inserted record.
function GenID($seqname = 'adodbseq', $start = 1)
{
$go = $this->Execute("select * from $seqname");
if (!$go){
$res = $this->Execute("CREATE TABLE $seqname ( ID autoinc( 1 ) ) IN DATABASE");
if(!res){
print $this->ErrorMsg();
return false;
}
}
$res = $this->Execute("INSERT INTO $seqname VALUES( DEFAULT )");
if(!$res){
print $this->ErrorMsg();
return false;
}
else{
$gen = $this->Execute("SELECT LastAutoInc( STATEMENT ) FROM system.iota");
$ret = $gen->fields[0];
return $ret;
}
}
function ErrorMsg()
{
if ($this->_haserrorfunctions) {
if ($this->_errorMsg !== false) return $this->_errorMsg;
if (empty($this->_connectionID)) return @ads_errormsg();
return @ads_errormsg($this->_connectionID);
} else return ADOConnection::ErrorMsg();
}
function ErrorNo()
{
if ($this->_haserrorfunctions) {
if ($this->_errorCode !== false) {
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
}
if (empty($this->_connectionID)) $e = @ads_error();
else $e = @ads_error($this->_connectionID);
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
// so we check and patch
if (strlen($e)<=2) return 0;
return $e;
} else return ADOConnection::ErrorNo();
}
function BeginTrans()
{
if (!$this->hasTransactions) return false;
if ($this->transOff) return true;
$this->transCnt += 1;
$this->_autocommit = false;
return ads_autocommit($this->_connectionID,false);
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$this->_autocommit = true;
$ret = ads_commit($this->_connectionID);
ads_autocommit($this->_connectionID,true);
return $ret;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$this->_autocommit = true;
$ret = ads_rollback($this->_connectionID);
ads_autocommit($this->_connectionID,true);
return $ret;
}
// Returns tables,Views or both on succesfull execution. Returns
// tables by default on succesfull execustion.
function &MetaTables($ttype = false, $showSchema = false, $mask = false)
{
$recordSet1 = $this->Execute("select * from system.tables");
if(!$recordSet1){
print $this->ErrorMsg();
return false;
}
$recordSet2 = $this->Execute("select * from system.views");
if(!$recordSet2){
print $this->ErrorMsg();
return false;
}
$i=0;
while (!$recordSet1->EOF){
$arr["$i"] = $recordSet1->fields[0];
$recordSet1->MoveNext();
$i=$i+1;
}
if($ttype=='FALSE'){
while (!$recordSet2->EOF){
$arr["$i"] = $recordSet2->fields[0];
$recordSet2->MoveNext();
$i=$i+1;
}
return $arr;
}
elseif($ttype=='VIEWS'){
while (!$recordSet2->EOF){
$arrV["$i"] = $recordSet2->fields[0];
$recordSet2->MoveNext();
$i=$i+1;
}
return $arrV;
}
else{
return $arr;
}
}
function &MetaPrimaryKeys($table, $owner = false)
{
$recordSet = $this->Execute("select table_primary_key from system.tables where name='$table'");
if(!$recordSet){
print $this->ErrorMsg();
return false;
}
$i=0;
while (!$recordSet->EOF){
$arr["$i"] = $recordSet->fields[0];
$recordSet->MoveNext();
$i=$i+1;
}
return $arr;
}
/*
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcdatetime_data_type_changes.asp
/ SQL data type codes /
#define SQL_UNKNOWN_TYPE 0
#define SQL_CHAR 1
#define SQL_NUMERIC 2
#define SQL_DECIMAL 3
#define SQL_INTEGER 4
#define SQL_SMALLINT 5
#define SQL_FLOAT 6
#define SQL_REAL 7
#define SQL_DOUBLE 8
#if (ODBCVER >= 0x0300)
#define SQL_DATETIME 9
#endif
#define SQL_VARCHAR 12
/ One-parameter shortcuts for date/time data types /
#if (ODBCVER >= 0x0300)
#define SQL_TYPE_DATE 91
#define SQL_TYPE_TIME 92
#define SQL_TYPE_TIMESTAMP 93
#define SQL_UNICODE (-95)
#define SQL_UNICODE_VARCHAR (-96)
#define SQL_UNICODE_LONGVARCHAR (-97)
*/
function ODBCTypes($t)
{
switch ((integer)$t) {
case 1:
case 12:
case 0:
case -95:
case -96:
return 'C';
case -97:
case -1: //text
return 'X';
case -4: //image
return 'B';
case 9:
case 91:
return 'D';
case 10:
case 11:
case 92:
case 93:
return 'T';
case 4:
case 5:
case -6:
return 'I';
case -11: // uniqidentifier
return 'R';
case -7: //bit
return 'L';
default:
return 'N';
}
}
function &MetaColumns($table, $normalize = true)
{
global $ADODB_FETCH_MODE;
$false = false;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
/*if (false) { // after testing, confirmed that the following does not work becoz of a bug
$qid2 = ads_tables($this->_connectionID);
$rs = new ADORecordSet_ads($qid2);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$rs->_fetch();
while (!$rs->EOF) {
if ($table == strtoupper($rs->fields[2])) {
$q = $rs->fields[0];
$o = $rs->fields[1];
break;
}
$rs->MoveNext();
}
$rs->Close();
$qid = ads_columns($this->_connectionID,$q,$o,strtoupper($table),'%');
} */
switch ($this->databaseType) {
case 'access':
case 'vfp':
$qid = ads_columns($this->_connectionID);#,'%','',strtoupper($table),'%');
break;
case 'db2':
$colname = "%";
$qid = ads_columns($this->_connectionID, "", $schema, $table, $colname);
break;
default:
$qid = @ads_columns($this->_connectionID,'%','%',strtoupper($table),'%');
if (empty($qid)) $qid = ads_columns($this->_connectionID);
break;
}
if (empty($qid)) return $false;
$rs = new ADORecordSet_ads($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$rs->_fetch();
$retarr = array();
/*
$rs->fields indices
0 TABLE_QUALIFIER
1 TABLE_SCHEM
2 TABLE_NAME
3 COLUMN_NAME
4 DATA_TYPE
5 TYPE_NAME
6 PRECISION
7 LENGTH
8 SCALE
9 RADIX
10 NULLABLE
11 REMARKS
*/
while (!$rs->EOF) {
// adodb_pr($rs->fields);
if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[3];
$fld->type = $this->ODBCTypes($rs->fields[4]);
// ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
// access uses precision to store length for char/varchar
if ($fld->type == 'C' or $fld->type == 'X') {
if ($this->databaseType == 'access')
$fld->max_length = $rs->fields[6];
else if ($rs->fields[4] <= -95) // UNICODE
$fld->max_length = $rs->fields[7]/2;
else
$fld->max_length = $rs->fields[7];
} else
$fld->max_length = $rs->fields[7];
$fld->not_null = !empty($rs->fields[10]);
$fld->scale = $rs->fields[8];
$retarr[strtoupper($fld->name)] = $fld;
} else if (sizeof($retarr)>0)
break;
$rs->MoveNext();
}
$rs->Close(); //-- crashes 4.03pl1 -- why?
if (empty($retarr)) $retarr = false;
return $retarr;
}
// Returns an array of columns names for a given table
function &MetaColumnNames($table, $numIndexes = false, $useattnum = false)
{
$recordSet = $this->Execute("select name from system.columns where parent='$table'");
if(!$recordSet){
print $this->ErrorMsg();
return false;
}
else{
$i=0;
while (!$recordSet->EOF){
$arr["FIELD$i"] = $recordSet->fields[0];
$recordSet->MoveNext();
$i=$i+1;
}
return $arr;
}
}
function Prepare($sql)
{
if (! $this->_bindInputArray) return $sql; // no binding
$stmt = ads_prepare($this->_connectionID,$sql);
if (!$stmt) {
// we don't know whether odbc driver is parsing prepared stmts, so just return sql
return $sql;
}
return array($sql,$stmt,false);
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
{
GLOBAL $php_errormsg;
if (isset($php_errormsg)) $php_errormsg = '';
$this->_error = '';
if ($inputarr) {
if (is_array($sql)) {
$stmtid = $sql[1];
} else {
$stmtid = ads_prepare($this->_connectionID,$sql);
if ($stmtid == false) {
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
return false;
}
}
if (! ads_execute($stmtid,$inputarr)) {
//@ads_free_result($stmtid);
if ($this->_haserrorfunctions) {
$this->_errorMsg = ads_errormsg();
$this->_errorCode = ads_error();
}
return false;
}
} else if (is_array($sql)) {
$stmtid = $sql[1];
if (!ads_execute($stmtid)) {
//@ads_free_result($stmtid);
if ($this->_haserrorfunctions) {
$this->_errorMsg = ads_errormsg();
$this->_errorCode = ads_error();
}
return false;
}
} else
{
$stmtid = ads_exec($this->_connectionID,$sql);
}
$this->_lastAffectedRows = 0;
if ($stmtid)
{
if (@ads_num_fields($stmtid) == 0) {
$this->_lastAffectedRows = ads_num_rows($stmtid);
$stmtid = true;
} else {
$this->_lastAffectedRows = 0;
ads_binmode($stmtid,$this->binmode);
ads_longreadlen($stmtid,$this->maxblobsize);
}
if ($this->_haserrorfunctions)
{
$this->_errorMsg = '';
$this->_errorCode = 0;
}
else
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
}
else
{
if ($this->_haserrorfunctions) {
$this->_errorMsg = ads_errormsg();
$this->_errorCode = ads_error();
} else
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
}
return $stmtid;
}
/*
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
Usage:
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$sql = "UPDATE $table SET $column=? WHERE $where";
$stmtid = ads_prepare($this->_connectionID,$sql);
if ($stmtid == false){
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
return false;
}
if (! ads_execute($stmtid,array($val),array(SQL_BINARY) )){
if ($this->_haserrorfunctions){
$this->_errorMsg = ads_errormsg();
$this->_errorCode = ads_error();
}
return false;
}
return TRUE;
}
// returns true or false
function _close()
{
$ret = @ads_close($this->_connectionID);
$this->_connectionID = false;
return $ret;
}
function _affectedrows()
{
return $this->_lastAffectedRows;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_ads extends ADORecordSet {
var $bind = false;
var $databaseType = "ads";
var $dataProvider = "ads";
var $useFetchArray;
var $_has_stupid_odbc_fetch_api_change;
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
$this->_queryID = $id;
// the following is required for mysql odbc driver in 4.3.1 -- why?
$this->EOF = false;
$this->_currentRow = -1;
//parent::__construct($id);
}
// returns the field object
function &FetchField($fieldOffset = -1)
{
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
$o->name = @ads_field_name($this->_queryID,$off);
$o->type = @ads_field_type($this->_queryID,$off);
$o->max_length = @ads_field_len($this->_queryID,$off);
if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
global $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS) ? @ads_num_rows($this->_queryID) : -1;
$this->_numOfFields = @ads_num_fields($this->_queryID);
// some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
if ($this->_numOfRows == 0) $this->_numOfRows = -1;
//$this->useFetchArray = $this->connection->useFetchArray;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
}
function _seek($row)
{
return false;
}
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
function &GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
$rs =& $this->GetArray($nrows);
return $rs;
}
$savem = $this->fetchMode;
$this->fetchMode = ADODB_FETCH_NUM;
$this->Move($offset);
$this->fetchMode = $savem;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields =& $this->GetRowAssoc();
}
$results = array();
$cnt = 0;
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++] = $this->fields;
$this->MoveNext();
}
return $results;
}
function MoveNext()
{
if ($this->_numOfRows != 0 && !$this->EOF) {
$this->_currentRow++;
if( $this->_fetch() ) {
return true;
}
}
$this->fields = false;
$this->EOF = true;
return false;
}
function _fetch()
{
$this->fields = false;
if ($this->_has_stupid_odbc_fetch_api_change)
$rez = @ads_fetch_into($this->_queryID,$this->fields);
else {
$row = 0;
$rez = @ads_fetch_into($this->_queryID,$row,$this->fields);
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields =& $this->GetRowAssoc();
}
return true;
}
return false;
}
function _close()
{
return @ads_free_result($this->_queryID);
}
}
@@ -1,87 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Support Borland Interbase 6.5 and later
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-ibase.inc.php");
class ADODB_borland_ibase extends ADODB_ibase {
var $databaseType = "borland_ibase";
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->autoCommit = false;
$this->_transactionID = ibase_trans($this->ibasetrans, $this->_connectionID);
return $this->_transactionID;
}
function ServerInfo()
{
$arr['dialect'] = $this->dialect;
switch($arr['dialect']) {
case '':
case '1': $s = 'Interbase 6.5, Dialect 1'; break;
case '2': $s = 'Interbase 6.5, Dialect 2'; break;
default:
case '3': $s = 'Interbase 6.5, Dialect 3'; break;
}
$arr['version'] = '6.5';
$arr['description'] = $s;
return $arr;
}
// Note that Interbase 6.5 uses ROWS instead - don't you love forking wars!
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
// Firebird uses
// SELECT FIRST 5 SKIP 2 col1, col2 FROM TABLE
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
if ($nrows > 0) {
if ($offset <= 0) $str = " ROWS $nrows ";
else {
$a = $offset+1;
$b = $offset+$nrows;
$str = " ROWS $a TO $b";
}
} else {
// ok, skip
$a = $offset + 1;
$str = " ROWS $a TO 999999999"; // 999 million
}
$sql .= $str;
return ($secs2cache) ?
$this->CacheExecute($secs2cache,$sql,$inputarr)
:
$this->Execute($sql,$inputarr);
}
};
class ADORecordSet_borland_ibase extends ADORecordSet_ibase {
var $databaseType = "borland_ibase";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}
-207
View File
@@ -1,207 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4.
Currently unsupported: MetaDatabases, MetaTables and MetaColumns, and also inputarr in Execute.
Native types have been converted to MetaTypes.
Transactions not supported yet.
Limitation of url length. For IIS, see MaxClientRequestBuffer registry value.
http://support.microsoft.com/default.aspx?scid=kb;en-us;260694
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (! defined("_ADODB_CSV_LAYER")) {
define("_ADODB_CSV_LAYER", 1 );
include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
class ADODB_csv extends ADOConnection {
var $databaseType = 'csv';
var $databaseProvider = 'csv';
var $hasInsertID = true;
var $hasAffectedRows = true;
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $_affectedrows=0;
var $_insertid=0;
var $_url;
var $replaceQuote = "''"; // string to use to replace quotes
var $hasTransactions = false;
var $_errorNo = false;
function __construct()
{
}
function _insertid()
{
return $this->_insertid;
}
function _affectedrows()
{
return $this->_affectedrows;
}
function MetaDatabases()
{
return false;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (strtolower(substr($argHostname,0,7)) !== 'http://') return false;
$this->_url = $argHostname;
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (strtolower(substr($argHostname,0,7)) !== 'http://') return false;
$this->_url = $argHostname;
return true;
}
function MetaColumns($table, $normalize=true)
{
return false;
}
// parameters use PostgreSQL convention, not MySQL
function SelectLimit($sql, $nrows = -1, $offset = -1, $inputarr = false, $secs2cache = 0)
{
global $ADODB_FETCH_MODE;
$url = $this->_url.'?sql='.urlencode($sql)."&nrows=$nrows&fetch=".
(($this->fetchMode !== false)?$this->fetchMode : $ADODB_FETCH_MODE).
"&offset=$offset";
$err = false;
$rs = csv2rs($url,$err,false);
if ($this->debug) print "$url<br><i>$err</i><br>";
$at = strpos($err,'::::');
if ($at === false) {
$this->_errorMsg = $err;
$this->_errorNo = (integer)$err;
} else {
$this->_errorMsg = substr($err,$at+4,1024);
$this->_errorNo = -9999;
}
if ($this->_errorNo)
if ($fn = $this->raiseErrorFn) {
$fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,'');
}
if (is_object($rs)) {
$rs->databaseType='csv';
$rs->fetchMode = ($this->fetchMode !== false) ? $this->fetchMode : $ADODB_FETCH_MODE;
$rs->connection = $this;
}
return $rs;
}
// returns queryID or false
function _Execute($sql,$inputarr=false)
{
global $ADODB_FETCH_MODE;
if (!$this->_bindInputArray && $inputarr) {
$sqlarr = explode('?',$sql);
$sql = '';
$i = 0;
foreach($inputarr as $v) {
$sql .= $sqlarr[$i];
if (gettype($v) == 'string')
$sql .= $this->qstr($v);
else if ($v === null)
$sql .= 'NULL';
else
$sql .= $v;
$i += 1;
}
$sql .= $sqlarr[$i];
if ($i+1 != sizeof($sqlarr))
print "Input Array does not match ?: ".htmlspecialchars($sql);
$inputarr = false;
}
$url = $this->_url.'?sql='.urlencode($sql)."&fetch=".
(($this->fetchMode !== false)?$this->fetchMode : $ADODB_FETCH_MODE);
$err = false;
$rs = csv2rs($url,$err,false);
if ($this->debug) print urldecode($url)."<br><i>$err</i><br>";
$at = strpos($err,'::::');
if ($at === false) {
$this->_errorMsg = $err;
$this->_errorNo = (integer)$err;
} else {
$this->_errorMsg = substr($err,$at+4,1024);
$this->_errorNo = -9999;
}
if ($this->_errorNo)
if ($fn = $this->raiseErrorFn) {
$fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr);
}
if (is_object($rs)) {
$rs->fetchMode = ($this->fetchMode !== false) ? $this->fetchMode : $ADODB_FETCH_MODE;
$this->_affectedrows = $rs->affectedrows;
$this->_insertid = $rs->insertid;
$rs->databaseType='csv';
$rs->connection = $this;
}
return $rs;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
return $this->_errorMsg;
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
{
return $this->_errorNo;
}
// returns true or false
function _close()
{
return true;
}
} // class
class ADORecordset_csv extends ADORecordset {
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
function _close()
{
return true;
}
}
} // define
-849
View File
@@ -1,849 +0,0 @@
<?php
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
This is a version of the ADODB driver for DB2. It uses the 'ibm_db2' PECL extension
for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or
higher.
Originally tested with PHP 5.1.1 and Apache 2.0.55 on Windows XP SP2.
More recently tested with PHP 5.1.2 and Apache 2.0.55 on Windows XP SP2.
This file was ported from "adodb-odbc.inc.php" by Larry Menard, "larry.menard#rogers.com".
I ripped out what I believed to be a lot of redundant or obsolete code, but there are
probably still some remnants of the ODBC support in this file; I'm relying on reviewers
of this code to point out any other things that can be removed.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
define("_ADODB_DB2_LAYER", 2 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
class ADODB_db2 extends ADOConnection {
var $databaseType = "db2";
var $fmtDate = "'Y-m-d'";
var $concat_operator = '||';
var $sysTime = 'CURRENT TIME';
var $sysDate = 'CURRENT DATE';
var $sysTimeStamp = 'CURRENT TIMESTAMP';
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $replaceQuote = "''"; // string to use to replace quotes
var $dataProvider = "db2";
var $hasAffectedRows = true;
var $binmode = DB2_BINARY;
var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
// breaking backward-compat
var $_bindInputArray = false;
var $_genIDSQL = "VALUES NEXTVAL FOR %s";
var $_genSeqSQL = "CREATE SEQUENCE %s START WITH %s NO MAXVALUE NO CYCLE";
var $_dropSeqSQL = "DROP SEQUENCE %s";
var $_autocommit = true;
var $_haserrorfunctions = true;
var $_lastAffectedRows = 0;
var $uCaseTables = true; // for meta* functions, uppercase table names
var $hasInsertID = true;
function _insertid()
{
return ADOConnection::GetOne('VALUES IDENTITY_VAL_LOCAL()');
}
function __construct()
{
$this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
}
// returns true or false
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('db2_connect')) {
ADOConnection::outp("Warning: The old ODBC based DB2 driver has been renamed 'odbc_db2'. This ADOdb driver calls PHP's native db2 extension which is not installed.");
return null;
}
// This needs to be set before the connect().
// Replaces the odbc_binmode() call that was in Execute()
ini_set('ibm_db2.binmode', $this->binmode);
if ($argDatabasename && empty($argDSN)) {
if (stripos($argDatabasename,'UID=') && stripos($argDatabasename,'PWD=')) $this->_connectionID = db2_connect($argDatabasename,null,null);
else $this->_connectionID = db2_connect($argDatabasename,$argUsername,$argPassword);
} else {
if ($argDatabasename) $schema = $argDatabasename;
if (stripos($argDSN,'UID=') && stripos($argDSN,'PWD=')) $this->_connectionID = db2_connect($argDSN,null,null);
else $this->_connectionID = db2_connect($argDSN,$argUsername,$argPassword);
}
if (isset($php_errormsg)) $php_errormsg = '';
// For db2_connect(), there is an optional 4th arg. If present, it must be
// an array of valid options. So far, we don't use them.
$this->_errorMsg = @db2_conn_errormsg();
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
if ($this->_connectionID && isset($schema)) $this->Execute("SET SCHEMA=$schema");
return $this->_connectionID != false;
}
// returns true or false
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('db2_connect')) return null;
// This needs to be set before the connect().
// Replaces the odbc_binmode() call that was in Execute()
ini_set('ibm_db2.binmode', $this->binmode);
if (isset($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
if ($argDatabasename && empty($argDSN)) {
if (stripos($argDatabasename,'UID=') && stripos($argDatabasename,'PWD=')) $this->_connectionID = db2_pconnect($argDatabasename,null,null);
else $this->_connectionID = db2_pconnect($argDatabasename,$argUsername,$argPassword);
} else {
if ($argDatabasename) $schema = $argDatabasename;
if (stripos($argDSN,'UID=') && stripos($argDSN,'PWD=')) $this->_connectionID = db2_pconnect($argDSN,null,null);
else $this->_connectionID = db2_pconnect($argDSN,$argUsername,$argPassword);
}
if (isset($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = @db2_conn_errormsg();
if ($this->_connectionID && $this->autoRollback) @db2_rollback($this->_connectionID);
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
if ($this->_connectionID && isset($schema)) $this->Execute("SET SCHEMA=$schema");
return $this->_connectionID != false;
}
// format and return date string in database timestamp format
function DBTimeStamp($ts, $isfld = false)
{
if (empty($ts) && $ts !== 0) return 'null';
if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'YYYY-MM-DD HH24:MI:SS')";
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
// use right() and replace() ?
if (!$col) $col = $this->sysDate;
/* use TO_CHAR() if $fmt is TO_CHAR() allowed fmt */
if ($fmt== 'Y-m-d H:i:s')
return 'TO_CHAR('.$col.", 'YYYY-MM-DD HH24:MI:SS')";
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= $this->concat_operator;
$ch = $fmt[$i];
switch($ch) {
case 'Y':
case 'y':
if ($len==1) return "year($col)";
$s .= "char(year($col))";
break;
case 'M':
if ($len==1) return "monthname($col)";
$s .= "substr(monthname($col),1,3)";
break;
case 'm':
if ($len==1) return "month($col)";
$s .= "right(digits(month($col)),2)";
break;
case 'D':
case 'd':
if ($len==1) return "day($col)";
$s .= "right(digits(day($col)),2)";
break;
case 'H':
case 'h':
if ($len==1) return "hour($col)";
if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
else $s .= "''";
break;
case 'i':
case 'I':
if ($len==1) return "minute($col)";
if ($col != $this->sysDate)
$s .= "right(digits(minute($col)),2)";
else $s .= "''";
break;
case 'S':
case 's':
if ($len==1) return "second($col)";
if ($col != $this->sysDate)
$s .= "right(digits(second($col)),2)";
else $s .= "''";
break;
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
$s .= $this->qstr($ch);
}
}
return $s;
}
function ServerInfo()
{
$row = $this->GetRow("SELECT service_level, fixpack_num FROM TABLE(sysproc.env_get_inst_info())
as INSTANCEINFO");
if ($row) {
$info['version'] = $row[0].':'.$row[1];
$info['fixpack'] = $row[1];
$info['description'] = '';
} else {
return ADOConnection::ServerInfo();
}
return $info;
}
function CreateSequence($seqname='adodbseq',$start=1)
{
if (empty($this->_genSeqSQL)) return false;
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$start));
if (!$ok) return false;
return true;
}
function DropSequence($seqname = 'adodbseq')
{
if (empty($this->_dropSeqSQL)) return false;
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
}
function SelectLimit($sql, $nrows = -1, $offset = -1, $inputArr = false, $secs2cache = 0)
{
$nrows = (integer) $nrows;
if ($offset <= 0) {
// could also use " OPTIMIZE FOR $nrows ROWS "
if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY ";
$rs = $this->Execute($sql,$inputArr);
} else {
if ($offset > 0 && $nrows < 0);
else {
$nrows += $offset;
$sql .= " FETCH FIRST $nrows ROWS ONLY ";
}
$rs = ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
}
return $rs;
}
/*
This algorithm is not very efficient, but works even if table locking
is not available.
Will return false if unable to generate an ID after $MAXLOOPS attempts.
*/
function GenID($seq='adodbseq',$start=1)
{
// if you have to modify the parameter below, your database is overloaded,
// or you need to implement generation of id's yourself!
$num = $this->GetOne("VALUES NEXTVAL FOR $seq");
return $num;
}
function ErrorMsg()
{
if ($this->_haserrorfunctions) {
if ($this->_errorMsg !== false) return $this->_errorMsg;
if (empty($this->_connectionID)) return @db2_conn_errormsg();
return @db2_conn_errormsg($this->_connectionID);
} else return ADOConnection::ErrorMsg();
}
function ErrorNo()
{
if ($this->_haserrorfunctions) {
if ($this->_errorCode !== false) {
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
}
if (empty($this->_connectionID)) $e = @db2_conn_error();
else $e = @db2_conn_error($this->_connectionID);
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
// so we check and patch
if (strlen($e)<=2) return 0;
return $e;
} else return ADOConnection::ErrorNo();
}
function BeginTrans()
{
if (!$this->hasTransactions) return false;
if ($this->transOff) return true;
$this->transCnt += 1;
$this->_autocommit = false;
return db2_autocommit($this->_connectionID,false);
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$this->_autocommit = true;
$ret = db2_commit($this->_connectionID);
db2_autocommit($this->_connectionID,true);
return $ret;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$this->_autocommit = true;
$ret = db2_rollback($this->_connectionID);
db2_autocommit($this->_connectionID,true);
return $ret;
}
function MetaPrimaryKeys($table, $owner = false)
{
global $ADODB_FETCH_MODE;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = @db2_primarykeys($this->_connectionID,'',$schema,$table);
if (!$qid) {
$ADODB_FETCH_MODE = $savem;
return false;
}
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return false;
$arr = $rs->GetArray();
$rs->Close();
$arr2 = array();
for ($i=0; $i < sizeof($arr); $i++) {
if ($arr[$i][3]) $arr2[] = $arr[$i][3];
}
return $arr2;
}
function MetaForeignKeys($table, $owner = FALSE, $upper = FALSE, $asociative = FALSE )
{
global $ADODB_FETCH_MODE;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = @db2_foreign_keys($this->_connectionID,'',$schema,$table);
if (!$qid) {
$ADODB_FETCH_MODE = $savem;
return false;
}
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
/*
$rs->fields indices
0 PKTABLE_CAT
1 PKTABLE_SCHEM
2 PKTABLE_NAME
3 PKCOLUMN_NAME
4 FKTABLE_CAT
5 FKTABLE_SCHEM
6 FKTABLE_NAME
7 FKCOLUMN_NAME
*/
if (!$rs) return false;
$foreign_keys = array();
while (!$rs->EOF) {
if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
if (!is_array($foreign_keys[$rs->fields[5].'.'.$rs->fields[6]]))
$foreign_keys[$rs->fields[5].'.'.$rs->fields[6]] = array();
$foreign_keys[$rs->fields[5].'.'.$rs->fields[6]][$rs->fields[7]] = $rs->fields[3];
}
$rs->MoveNext();
}
$rs->Close();
return $foreign_key;
}
function MetaTables($ttype = false, $schema = false, $mask = false)
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = db2_tables($this->_connectionID);
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) {
$false = false;
return $false;
}
$arr = $rs->GetArray();
$rs->Close();
$arr2 = array();
if ($ttype) {
$isview = strncmp($ttype,'V',1) === 0;
}
for ($i=0; $i < sizeof($arr); $i++) {
if (!$arr[$i][2]) continue;
$type = $arr[$i][3];
$owner = $arr[$i][1];
$schemaval = ($schema) ? $arr[$i][1].'.' : '';
if ($ttype) {
if ($isview) {
if (strncmp($type,'V',1) === 0) $arr2[] = $schemaval.$arr[$i][2];
} else if (strncmp($owner,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2];
} else if (strncmp($owner,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2];
}
return $arr2;
}
/*
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2datetime_data_type_changes.asp
/ SQL data type codes /
#define SQL_UNKNOWN_TYPE 0
#define SQL_CHAR 1
#define SQL_NUMERIC 2
#define SQL_DECIMAL 3
#define SQL_INTEGER 4
#define SQL_SMALLINT 5
#define SQL_FLOAT 6
#define SQL_REAL 7
#define SQL_DOUBLE 8
#if (DB2VER >= 0x0300)
#define SQL_DATETIME 9
#endif
#define SQL_VARCHAR 12
/ One-parameter shortcuts for date/time data types /
#if (DB2VER >= 0x0300)
#define SQL_TYPE_DATE 91
#define SQL_TYPE_TIME 92
#define SQL_TYPE_TIMESTAMP 93
#define SQL_UNICODE (-95)
#define SQL_UNICODE_VARCHAR (-96)
#define SQL_UNICODE_LONGVARCHAR (-97)
*/
function DB2Types($t)
{
switch ((integer)$t) {
case 1:
case 12:
case 0:
case -95:
case -96:
return 'C';
case -97:
case -1: //text
return 'X';
case -4: //image
return 'B';
case 9:
case 91:
return 'D';
case 10:
case 11:
case 92:
case 93:
return 'T';
case 4:
case 5:
case -6:
return 'I';
case -11: // uniqidentifier
return 'R';
case -7: //bit
return 'L';
default:
return 'N';
}
}
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$false = false;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$colname = "%";
$qid = db2_columns($this->_connectionID, "", $schema, $table, $colname);
if (empty($qid)) return $false;
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $false;
$rs->_fetch();
$retarr = array();
/*
$rs->fields indices
0 TABLE_QUALIFIER
1 TABLE_SCHEM
2 TABLE_NAME
3 COLUMN_NAME
4 DATA_TYPE
5 TYPE_NAME
6 PRECISION
7 LENGTH
8 SCALE
9 RADIX
10 NULLABLE
11 REMARKS
*/
while (!$rs->EOF) {
if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[3];
$fld->type = $this->DB2Types($rs->fields[4]);
// ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
// access uses precision to store length for char/varchar
if ($fld->type == 'C' or $fld->type == 'X') {
if ($rs->fields[4] <= -95) // UNICODE
$fld->max_length = $rs->fields[7]/2;
else
$fld->max_length = $rs->fields[7];
} else
$fld->max_length = $rs->fields[7];
$fld->not_null = !empty($rs->fields[10]);
$fld->scale = $rs->fields[8];
$fld->primary_key = false;
$retarr[strtoupper($fld->name)] = $fld;
} else if (sizeof($retarr)>0)
break;
$rs->MoveNext();
}
$rs->Close();
if (empty($retarr)) $retarr = false;
$qid = db2_primary_keys($this->_connectionID, "", $schema, $table);
if (empty($qid)) return $false;
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $retarr;
$rs->_fetch();
/*
$rs->fields indices
0 TABLE_CAT
1 TABLE_SCHEM
2 TABLE_NAME
3 COLUMN_NAME
4 KEY_SEQ
5 PK_NAME
*/
while (!$rs->EOF) {
if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
$retarr[strtoupper($rs->fields[3])]->primary_key = true;
} else if (sizeof($retarr)>0)
break;
$rs->MoveNext();
}
$rs->Close();
if (empty($retarr)) $retarr = false;
return $retarr;
}
function Prepare($sql)
{
if (! $this->_bindInputArray) return $sql; // no binding
$stmt = db2_prepare($this->_connectionID,$sql);
if (!$stmt) {
// we don't know whether db2 driver is parsing prepared stmts, so just return sql
return $sql;
}
return array($sql,$stmt,false);
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
{
GLOBAL $php_errormsg;
if (isset($php_errormsg)) $php_errormsg = '';
$this->_error = '';
if ($inputarr) {
if (is_array($sql)) {
$stmtid = $sql[1];
} else {
$stmtid = db2_prepare($this->_connectionID,$sql);
if ($stmtid == false) {
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
return false;
}
}
if (! db2_execute($stmtid,$inputarr)) {
if ($this->_haserrorfunctions) {
$this->_errorMsg = db2_stmt_errormsg();
$this->_errorCode = db2_stmt_error();
}
return false;
}
} else if (is_array($sql)) {
$stmtid = $sql[1];
if (!db2_execute($stmtid)) {
if ($this->_haserrorfunctions) {
$this->_errorMsg = db2_stmt_errormsg();
$this->_errorCode = db2_stmt_error();
}
return false;
}
} else
$stmtid = @db2_exec($this->_connectionID,$sql);
$this->_lastAffectedRows = 0;
if ($stmtid) {
if (@db2_num_fields($stmtid) == 0) {
$this->_lastAffectedRows = db2_num_rows($stmtid);
$stmtid = true;
} else {
$this->_lastAffectedRows = 0;
}
if ($this->_haserrorfunctions) {
$this->_errorMsg = '';
$this->_errorCode = 0;
} else
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
} else {
if ($this->_haserrorfunctions) {
$this->_errorMsg = db2_stmt_errormsg();
$this->_errorCode = db2_stmt_error();
} else
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
}
return $stmtid;
}
/*
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
Usage:
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
}
// returns true or false
function _close()
{
$ret = @db2_close($this->_connectionID);
$this->_connectionID = false;
return $ret;
}
function _affectedrows()
{
return $this->_lastAffectedRows;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_db2 extends ADORecordSet {
var $bind = false;
var $databaseType = "db2";
var $dataProvider = "db2";
var $useFetchArray;
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
$this->_queryID = $id;
}
// returns the field object
function FetchField($offset = -1)
{
$o= new ADOFieldObject();
$o->name = @db2_field_name($this->_queryID,$offset);
$o->type = @db2_field_type($this->_queryID,$offset);
$o->max_length = db2_field_width($this->_queryID,$offset);
if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
global $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS) ? @db2_num_rows($this->_queryID) : -1;
$this->_numOfFields = @db2_num_fields($this->_queryID);
// some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
if ($this->_numOfRows == 0) $this->_numOfRows = -1;
}
function _seek($row)
{
return false;
}
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
$rs = $this->GetArray($nrows);
return $rs;
}
$savem = $this->fetchMode;
$this->fetchMode = ADODB_FETCH_NUM;
$this->Move($offset);
$this->fetchMode = $savem;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc();
}
$results = array();
$cnt = 0;
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++] = $this->fields;
$this->MoveNext();
}
return $results;
}
function MoveNext()
{
if ($this->_numOfRows != 0 && !$this->EOF) {
$this->_currentRow++;
$this->fields = @db2_fetch_array($this->_queryID);
if ($this->fields) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc();
}
return true;
}
}
$this->fields = false;
$this->EOF = true;
return false;
}
function _fetch()
{
$this->fields = db2_fetch_array($this->_queryID);
if ($this->fields) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc();
}
return true;
}
$this->fields = false;
return false;
}
function _close()
{
return @db2_free_result($this->_queryID);
}
}
-226
View File
@@ -1,226 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-db2.inc.php");
if (!defined('ADODB_DB2OCI')){
define('ADODB_DB2OCI',1);
/*
// regex code for smart remapping of :0, :1 bind vars to ? ?
function _colontrack($p)
{
global $_COLONARR,$_COLONSZ;
$v = (integer) substr($p,1);
if ($v > $_COLONSZ) return $p;
$_COLONARR[] = $v;
return '?';
}
// smart remapping of :0, :1 bind vars to ? ?
function _colonscope($sql,$arr)
{
global $_COLONARR,$_COLONSZ;
$_COLONARR = array();
$_COLONSZ = sizeof($arr);
$sql2 = preg_replace("/(:[0-9]+)/e","_colontrack('\\1')",$sql);
if (empty($_COLONARR)) return array($sql,$arr);
foreach($_COLONARR as $k => $v) {
$arr2[] = $arr[$v];
}
return array($sql2,$arr2);
}
*/
/*
Smart remapping of :0, :1 bind vars to ? ?
Handles colons in comments -- and / * * / and in quoted strings.
*/
function _colonparser($sql,$arr)
{
$lensql = strlen($sql);
$arrsize = sizeof($arr);
$state = 'NORM';
$at = 1;
$ch = $sql[0];
$ch2 = @$sql[1];
$sql2 = '';
$arr2 = array();
$nprev = 0;
while (strlen($ch)) {
switch($ch) {
case '/':
if ($state == 'NORM' && $ch2 == '*') {
$state = 'COMMENT';
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
}
break;
case '*':
if ($state == 'COMMENT' && $ch2 == '/') {
$state = 'NORM';
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
}
break;
case "\n":
case "\r":
if ($state == 'COMMENT2') $state = 'NORM';
break;
case "'":
do {
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
} while ($ch !== "'");
break;
case ':':
if ($state == 'COMMENT' || $state == 'COMMENT2') break;
//echo "$at=$ch $ch2, ";
if ('0' <= $ch2 && $ch2 <= '9') {
$n = '';
$nat = $at;
do {
$at += 1;
$ch = $ch2;
$n .= $ch;
$ch2 = $at < $lensql ? $sql[$at] : '';
} while ('0' <= $ch && $ch <= '9');
#echo "$n $arrsize ] ";
$n = (integer) $n;
if ($n < $arrsize) {
$sql2 .= substr($sql,$nprev,$nat-$nprev-1).'?';
$nprev = $at-1;
$arr2[] = $arr[$n];
}
}
break;
case '-':
if ($state == 'NORM') {
if ($ch2 == '-') $state = 'COMMENT2';
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
}
break;
}
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
}
if ($nprev == 0) {
$sql2 = $sql;
} else {
$sql2 .= substr($sql,$nprev);
}
return array($sql2,$arr2);
}
class ADODB_db2oci extends ADODB_db2 {
var $databaseType = "db2oci";
var $sysTimeStamp = 'sysdate';
var $sysDate = 'trunc(sysdate)';
var $_bindInputArray = true;
function Param($name,$type='C')
{
return ':'.$name;
}
function MetaTables($ttype = false, $schema = false, $mask = false)
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = db2_tables($this->_connectionID);
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) {
$false = false;
return $false;
}
$arr = $rs->GetArray();
$rs->Close();
$arr2 = array();
// adodb_pr($arr);
if ($ttype) {
$isview = strncmp($ttype,'V',1) === 0;
}
for ($i=0; $i < sizeof($arr); $i++) {
if (!$arr[$i][2]) continue;
$type = $arr[$i][3];
$schemaval = ($schema) ? $arr[$i][1].'.' : '';
$name = $schemaval.$arr[$i][2];
$owner = $arr[$i][1];
if (substr($name,0,8) == 'EXPLAIN_') continue;
if ($ttype) {
if ($isview) {
if (strncmp($type,'V',1) === 0) $arr2[] = $name;
} else if (strncmp($type,'T',1) === 0 && strncmp($owner,'SYS',3) !== 0) $arr2[] = $name;
} else if (strncmp($type,'T',1) === 0 && strncmp($owner,'SYS',3) !== 0) $arr2[] = $name;
}
return $arr2;
}
function _Execute($sql, $inputarr=false )
{
if ($inputarr) list($sql,$inputarr) = _colonparser($sql, $inputarr);
return parent::_Execute($sql, $inputarr);
}
};
class ADORecordSet_db2oci extends ADORecordSet_db2 {
var $databaseType = "db2oci";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
} //define
-86
View File
@@ -1,86 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-db2.inc.php");
if (!defined('ADODB_DB2OCI')){
define('ADODB_DB2OCI',1);
/**
* Callback function for preg_replace in _colonscope()
* @param array $p matched patterns
* return string '?' if parameter replaced, :N if not
*/
function _colontrack($p)
{
global $_COLONARR, $_COLONSZ;
$v = (integer) substr($p[1], 1);
if ($v > $_COLONSZ) return $p[1];
$_COLONARR[] = $v;
return '?';
}
/**
* smart remapping of :0, :1 bind vars to ? ?
* @param string $sql SQL statement
* @param array $arr parameters
* @return array
*/
function _colonscope($sql,$arr)
{
global $_COLONARR,$_COLONSZ;
$_COLONARR = array();
$_COLONSZ = sizeof($arr);
$sql2 = preg_replace_callback('/(:[0-9]+)/', '_colontrack', $sql);
if (empty($_COLONARR)) return array($sql,$arr);
foreach($_COLONARR as $k => $v) {
$arr2[] = $arr[$v];
}
return array($sql2,$arr2);
}
class ADODB_db2oci extends ADODB_db2 {
var $databaseType = "db2oci";
var $sysTimeStamp = 'sysdate';
var $sysDate = 'trunc(sysdate)';
function _Execute($sql, $inputarr = false)
{
if ($inputarr) list($sql,$inputarr) = _colonscope($sql, $inputarr);
return parent::_Execute($sql, $inputarr);
}
};
class ADORecordSet_db2oci extends ADORecordSet_odbc {
var $databaseType = "db2oci";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
} //define
-267
View File
@@ -1,267 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Contribution by Frank M. Kromann <frank@frontbase.com>.
Set tabs to 8.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (! defined("_ADODB_FBSQL_LAYER")) {
define("_ADODB_FBSQL_LAYER", 1 );
class ADODB_fbsql extends ADOConnection {
var $databaseType = 'fbsql';
var $hasInsertID = true;
var $hasAffectedRows = true;
var $metaTablesSQL = "SHOW TABLES";
var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $hasLimit = false;
function __construct()
{
}
function _insertid()
{
return fbsql_insert_id($this->_connectionID);
}
function _affectedrows()
{
return fbsql_affected_rows($this->_connectionID);
}
function MetaDatabases()
{
$qid = fbsql_list_dbs($this->_connectionID);
$arr = array();
$i = 0;
$max = fbsql_num_rows($qid);
while ($i < $max) {
$arr[] = fbsql_tablename($qid,$i);
$i += 1;
}
return $arr;
}
// returns concatenated string
function Concat()
{
$s = "";
$arr = func_get_args();
$first = true;
$s = implode(',',$arr);
if (sizeof($arr) > 0) return "CONCAT($s)";
else return '';
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
$this->_connectionID = fbsql_connect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
$this->_connectionID = fbsql_pconnect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
}
function MetaColumns($table, $normalize=true)
{
if ($this->metaColumnsSQL) {
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($rs === false) return false;
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
// split type into type(length):
if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array)) {
$fld->type = $query_array[1];
$fld->max_length = $query_array[2];
} else {
$fld->max_length = -1;
}
$fld->not_null = ($rs->fields[2] != 'YES');
$fld->primary_key = ($rs->fields[3] == 'PRI');
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
$fld->binary = (strpos($fld->type,'blob') !== false);
$retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
return false;
}
// returns true or false
function SelectDB($dbName)
{
$this->database = $dbName;
if ($this->_connectionID) {
return @fbsql_select_db($dbName,$this->_connectionID);
}
else return false;
}
// returns queryID or false
function _query($sql,$inputarr=false)
{
return fbsql_query("$sql;",$this->_connectionID);
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
$this->_errorMsg = @fbsql_error($this->_connectionID);
return $this->_errorMsg;
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
{
return @fbsql_errno($this->_connectionID);
}
// returns true or false
function _close()
{
return @fbsql_close($this->_connectionID);
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_fbsql extends ADORecordSet{
var $databaseType = "fbsql";
var $canSeek = true;
function __construct($queryID,$mode=false)
{
if (!$mode) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode) {
case ADODB_FETCH_NUM: $this->fetchMode = FBSQL_NUM; break;
case ADODB_FETCH_ASSOC: $this->fetchMode = FBSQL_ASSOC; break;
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = FBSQL_BOTH; break;
}
return parent::__construct($queryID);
}
function _initrs()
{
GLOBAL $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS) ? @fbsql_num_rows($this->_queryID):-1;
$this->_numOfFields = @fbsql_num_fields($this->_queryID);
}
function FetchField($fieldOffset = -1) {
if ($fieldOffset != -1) {
$o = @fbsql_fetch_field($this->_queryID, $fieldOffset);
//$o->max_length = -1; // fbsql returns the max length less spaces -- so it is unrealiable
$f = @fbsql_field_flags($this->_queryID,$fieldOffset);
$o->binary = (strpos($f,'binary')!== false);
}
else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
$o = @fbsql_fetch_field($this->_queryID);// fbsql returns the max length less spaces -- so it is unrealiable
//$o->max_length = -1;
}
return $o;
}
function _seek($row)
{
return @fbsql_data_seek($this->_queryID,$row);
}
function _fetch($ignore_fields=false)
{
$this->fields = @fbsql_fetch_array($this->_queryID,$this->fetchMode);
return ($this->fields == true);
}
function _close() {
return @fbsql_free_result($this->_queryID);
}
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$len = -1; // fbsql max_length is not accurate
switch (strtoupper($t)) {
case 'CHARACTER':
case 'CHARACTER VARYING':
case 'BLOB':
case 'CLOB':
case 'BIT':
case 'BIT VARYING':
if ($len <= $this->blobSize) return 'C';
// so we have to check whether binary...
case 'IMAGE':
case 'LONGBLOB':
case 'BLOB':
case 'MEDIUMBLOB':
return !empty($fieldobj->binary) ? 'B' : 'X';
case 'DATE': return 'D';
case 'TIME':
case 'TIME WITH TIME ZONE':
case 'TIMESTAMP':
case 'TIMESTAMP WITH TIME ZONE': return 'T';
case 'PRIMARY_KEY':
return 'R';
case 'INTEGER':
case 'SMALLINT':
case 'BOOLEAN':
if (!empty($fieldobj->primary_key)) return 'R';
else return 'I';
default: return 'N';
}
}
} //class
} // defined
@@ -1,73 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-ibase.inc.php");
class ADODB_firebird extends ADODB_ibase {
var $databaseType = "firebird";
var $dialect = 3;
var $sysTimeStamp = "CURRENT_TIMESTAMP"; //"cast('NOW' as timestamp)";
function ServerInfo()
{
$arr['dialect'] = $this->dialect;
switch($arr['dialect']) {
case '':
case '1': $s = 'Firebird Dialect 1'; break;
case '2': $s = 'Firebird Dialect 2'; break;
default:
case '3': $s = 'Firebird Dialect 3'; break;
}
$arr['version'] = ADOConnection::_findvers($s);
$arr['description'] = $s;
return $arr;
}
// Note that Interbase 6.5 uses this ROWS instead - don't you love forking wars!
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
{
$nrows = (integer) $nrows;
$offset = (integer) $offset;
$str = 'SELECT ';
if ($nrows >= 0) $str .= "FIRST $nrows ";
$str .=($offset>=0) ? "SKIP $offset " : '';
$sql = preg_replace('/^[ \t]*select/i',$str,$sql);
if ($secs)
$rs = $this->CacheExecute($secs,$sql,$inputarr);
else
$rs = $this->Execute($sql,$inputarr);
return $rs;
}
};
class ADORecordSet_firebird extends ADORecordSet_ibase {
var $databaseType = "firebird";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}
-918
View File
@@ -1,918 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Latest version is available at http://adodb.sourceforge.net
Interbase data driver. Requires interbase client. Works on Windows and Unix.
3 Jan 2002 -- suggestions by Hans-Peter Oeri <kampfcaspar75@oeri.ch>
changed transaction handling and added experimental blob stuff
Docs to interbase at the website
http://www.synectics.co.za/php3/tutorial/IB_PHP3_API.html
To use gen_id(), see
http://www.volny.cz/iprenosil/interbase/ip_ib_code.htm#_code_creategen
$rs = $conn->Execute('select gen_id(adodb,1) from rdb$database');
$id = $rs->fields[0];
$conn->Execute("insert into table (id, col1,...) values ($id, $val1,...)");
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB_ibase extends ADOConnection {
var $databaseType = "ibase";
var $dataProvider = "ibase";
var $replaceQuote = "''"; // string to use to replace quotes
var $ibase_datefmt = '%Y-%m-%d'; // For hours,mins,secs change to '%Y-%m-%d %H:%M:%S';
var $fmtDate = "'Y-m-d'";
var $ibase_timestampfmt = "%Y-%m-%d %H:%M:%S";
var $ibase_timefmt = "%H:%M:%S";
var $fmtTimeStamp = "'Y-m-d, H:i:s'";
var $concat_operator='||';
var $_transactionID;
var $metaTablesSQL = "select rdb\$relation_name from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
//OPN STUFF start
var $metaColumnsSQL = "select a.rdb\$field_name, a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc";
//OPN STUFF end
var $ibasetrans;
var $hasGenID = true;
var $_bindInputArray = true;
var $buffers = 0;
var $dialect = 1;
var $sysDate = "cast('TODAY' as timestamp)";
var $sysTimeStamp = "CURRENT_TIMESTAMP"; //"cast('NOW' as timestamp)";
var $ansiOuter = true;
var $hasAffectedRows = false;
var $poorAffectedRows = true;
var $blobEncodeType = 'C';
var $role = false;
function __construct()
{
if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$persist=false)
{
if (!function_exists('ibase_pconnect')) return null;
if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
$fn = ($persist) ? 'ibase_pconnect':'ibase_connect';
if ($this->role)
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->charSet,$this->buffers,$this->dialect,$this->role);
else
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->charSet,$this->buffers,$this->dialect);
if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
$this->replaceQuote = "''";
}
if ($this->_connectionID === false) {
$this->_handleerror();
return false;
}
// PHP5 change.
if (function_exists('ibase_timefmt')) {
ibase_timefmt($this->ibase_datefmt,IBASE_DATE );
if ($this->dialect == 1) {
ibase_timefmt($this->ibase_datefmt,IBASE_TIMESTAMP );
}
else {
ibase_timefmt($this->ibase_timestampfmt,IBASE_TIMESTAMP );
}
ibase_timefmt($this->ibase_timefmt,IBASE_TIME );
} else {
ini_set("ibase.timestampformat", $this->ibase_timestampfmt);
ini_set("ibase.dateformat", $this->ibase_datefmt);
ini_set("ibase.timeformat", $this->ibase_timefmt);
}
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,true);
}
function MetaPrimaryKeys($table,$owner_notused=false,$internalKey=false)
{
if ($internalKey) {
return array('RDB$DB_KEY');
}
$table = strtoupper($table);
$sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME
FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
WHERE I.RDB$RELATION_NAME=\''.$table.'\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\'
ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';
$a = $this->GetCol($sql,false,true);
if ($a && sizeof($a)>0) return $a;
return false;
}
function ServerInfo()
{
$arr['dialect'] = $this->dialect;
switch($arr['dialect']) {
case '':
case '1': $s = 'Interbase 5.5 or earlier'; break;
case '2': $s = 'Interbase 5.6'; break;
default:
case '3': $s = 'Interbase 6.0'; break;
}
$arr['version'] = ADOConnection::_findvers($s);
$arr['description'] = $s;
return $arr;
}
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->autoCommit = false;
$this->_transactionID = $this->_connectionID;//ibase_trans($this->ibasetrans, $this->_connectionID);
return $this->_transactionID;
}
function CommitTrans($ok=true)
{
if (!$ok) {
return $this->RollbackTrans();
}
if ($this->transOff) {
return true;
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$ret = false;
$this->autoCommit = true;
if ($this->_transactionID) {
//print ' commit ';
$ret = ibase_commit($this->_transactionID);
}
$this->_transactionID = false;
return $ret;
}
// there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
// it appears that ibase extension cannot support multiple concurrent queryid's
function _Execute($sql,$inputarr=false)
{
global $ADODB_COUNTRECS;
if ($this->_logsql) {
$savecrecs = $ADODB_COUNTRECS;
$ADODB_COUNTRECS = true; // force countrecs
$ret = ADOConnection::_Execute($sql,$inputarr);
$ADODB_COUNTRECS = $savecrecs;
} else {
$ret = ADOConnection::_Execute($sql,$inputarr);
}
return $ret;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$ret = false;
$this->autoCommit = true;
if ($this->_transactionID) {
$ret = ibase_rollback($this->_transactionID);
}
$this->_transactionID = false;
return $ret;
}
function MetaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$table = strtoupper($table);
$sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";
if (!$primary) {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
} else {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
}
// get index details
$rs = $this->Execute($sql);
if (!is_object($rs)) {
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $false;
}
$indexes = array();
while ($row = $rs->FetchRow()) {
$index = $row[0];
if (!isset($indexes[$index])) {
if (is_null($row[3])) {
$row[3] = 0;
}
$indexes[$index] = array(
'unique' => ($row[3] == 1),
'columns' => array()
);
}
$sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '".$index."' ORDER BY RDB\$FIELD_POSITION ASC";
$rs1 = $this->Execute($sql);
while ($row1 = $rs1->FetchRow()) {
$indexes[$index]['columns'][$row1[2]] = $row1[1];
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $indexes;
}
// See http://community.borland.com/article/0,1410,25844,00.html
function RowLock($tables,$where,$col=false)
{
if ($this->autoCommit) {
$this->BeginTrans();
}
$this->Execute("UPDATE $table SET $col=$col WHERE $where "); // is this correct - jlim?
return 1;
}
function CreateSequence($seqname = 'adodbseq', $startID = 1)
{
$ok = $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
if (!$ok) return false;
return $this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
}
function DropSequence($seqname = 'adodbseq')
{
$seqname = strtoupper($seqname);
$this->Execute("delete from RDB\$GENERATORS where RDB\$GENERATOR_NAME='$seqname'");
}
function GenID($seqname='adodbseq',$startID=1)
{
$getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
$rs = @$this->Execute($getnext);
if (!$rs) {
$this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
$this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
$rs = $this->Execute($getnext);
}
if ($rs && !$rs->EOF) {
$this->genID = (integer) reset($rs->fields);
}
else {
$this->genID = 0; // false
}
if ($rs) {
$rs->Close();
}
return $this->genID;
}
function SelectDB($dbName)
{
return false;
}
function _handleerror()
{
$this->_errorMsg = ibase_errmsg();
}
function ErrorNo()
{
if (preg_match('/error code = ([\-0-9]*)/i', $this->_errorMsg,$arr)) return (integer) $arr[1];
else return 0;
}
function ErrorMsg()
{
return $this->_errorMsg;
}
function Prepare($sql)
{
$stmt = ibase_prepare($this->_connectionID,$sql);
if (!$stmt) return false;
return array($sql,$stmt);
}
// returns query ID if successful, otherwise false
// there have been reports of problems with nested queries - the code is probably not re-entrant?
function _query($sql,$iarr=false)
{
if (!$this->autoCommit && $this->_transactionID) {
$conn = $this->_transactionID;
$docommit = false;
} else {
$conn = $this->_connectionID;
$docommit = true;
}
if (is_array($sql)) {
$fn = 'ibase_execute';
$sql = $sql[1];
if (is_array($iarr)) {
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack
$fnarr = array_merge( array($sql) , $iarr);
$ret = call_user_func_array($fn,$fnarr);
} else {
switch(sizeof($iarr)) {
case 1: $ret = $fn($sql,$iarr[0]); break;
case 2: $ret = $fn($sql,$iarr[0],$iarr[1]); break;
case 3: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2]); break;
case 4: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
case 5: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
case 6: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
case 7: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
default: ADOConnection::outp( "Too many parameters to ibase query $sql");
case 8: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
}
}
} else $ret = $fn($sql);
} else {
$fn = 'ibase_query';
if (is_array($iarr)) {
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
$fnarr = array_merge( array($conn,$sql) , $iarr);
$ret = call_user_func_array($fn,$fnarr);
} else {
switch(sizeof($iarr)) {
case 1: $ret = $fn($conn,$sql,$iarr[0]); break;
case 2: $ret = $fn($conn,$sql,$iarr[0],$iarr[1]); break;
case 3: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2]); break;
case 4: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
case 5: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
case 6: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
case 7: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
default: ADOConnection::outp( "Too many parameters to ibase query $sql");
case 8: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
}
}
} else $ret = $fn($conn,$sql);
}
if ($docommit && $ret === true) {
ibase_commit($this->_connectionID);
}
$this->_handleerror();
return $ret;
}
// returns true or false
function _close()
{
if (!$this->autoCommit) {
@ibase_rollback($this->_connectionID);
}
return @ibase_close($this->_connectionID);
}
//OPN STUFF start
function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $dialect3)
{
$fscale = abs($fscale);
$fld->max_length = $flen;
$fld->scale = null;
switch($ftype){
case 7:
case 8:
if ($dialect3) {
switch($fsubtype){
case 0:
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
break;
case 1:
$fld->type = 'numeric';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
case 2:
$fld->type = 'decimal';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
} // switch
} else {
if ($fscale !=0) {
$fld->type = 'decimal';
$fld->scale = $fscale;
$fld->max_length = ($ftype == 7 ? 4 : 9);
} else {
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
}
}
break;
case 16:
if ($dialect3) {
switch($fsubtype){
case 0:
$fld->type = 'decimal';
$fld->max_length = 18;
$fld->scale = 0;
break;
case 1:
$fld->type = 'numeric';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
case 2:
$fld->type = 'decimal';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
} // switch
}
break;
case 10:
$fld->type = 'float';
break;
case 14:
$fld->type = 'char';
break;
case 27:
if ($fscale !=0) {
$fld->type = 'decimal';
$fld->max_length = 15;
$fld->scale = 5;
} else {
$fld->type = 'double';
}
break;
case 35:
if ($dialect3) {
$fld->type = 'timestamp';
} else {
$fld->type = 'date';
}
break;
case 12:
$fld->type = 'date';
break;
case 13:
$fld->type = 'time';
break;
case 37:
$fld->type = 'varchar';
break;
case 40:
$fld->type = 'cstring';
break;
case 261:
$fld->type = 'blob';
$fld->max_length = -1;
break;
} // switch
}
//OPN STUFF end
// returns array of ADOFieldObjects for current table
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
$ADODB_FETCH_MODE = $save;
$false = false;
if ($rs === false) {
return $false;
}
$retarr = array();
//OPN STUFF start
$dialect3 = ($this->dialect==3 ? true : false);
//OPN STUFF end
while (!$rs->EOF) { //print_r($rs->fields);
$fld = new ADOFieldObject();
$fld->name = trim($rs->fields[0]);
//OPN STUFF start
$this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
if (isset($rs->fields[1]) && $rs->fields[1]) {
$fld->not_null = true;
}
if (isset($rs->fields[2])) {
$fld->has_default = true;
$d = substr($rs->fields[2],strlen('default '));
switch ($fld->type)
{
case 'smallint':
case 'integer': $fld->default_value = (int) $d; break;
case 'char':
case 'blob':
case 'text':
case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;
case 'double':
case 'float': $fld->default_value = (float) $d; break;
default: $fld->default_value = $d; break;
}
// case 35:$tt = 'TIMESTAMP'; break;
}
if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {
$fld->sub_type = $rs->fields[5];
} else {
$fld->sub_type = null;
}
//OPN STUFF end
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
if ( empty($retarr)) return $false;
else return $retarr;
}
function BlobEncode( $blob )
{
$blobid = ibase_blob_create( $this->_connectionID);
ibase_blob_add( $blobid, $blob );
return ibase_blob_close( $blobid );
}
// since we auto-decode all blob's since 2.42,
// BlobDecode should not do any transforms
function BlobDecode($blob)
{
return $blob;
}
// old blobdecode function
// still used to auto-decode all blob's
function _BlobDecode_old( $blob )
{
$blobid = ibase_blob_open($this->_connectionID, $blob );
$realblob = ibase_blob_get( $blobid,$this->maxblobsize); // 2nd param is max size of blob -- Kevin Boillet <kevinboillet@yahoo.fr>
while($string = ibase_blob_get($blobid, 8192)){
$realblob .= $string;
}
ibase_blob_close( $blobid );
return( $realblob );
}
function _BlobDecode( $blob )
{
if (ADODB_PHPVER >= 0x5000) {
$blob_data = ibase_blob_info($this->_connectionID, $blob );
$blobid = ibase_blob_open($this->_connectionID, $blob );
} else {
$blob_data = ibase_blob_info( $blob );
$blobid = ibase_blob_open( $blob );
}
if( $blob_data[0] > $this->maxblobsize ) {
$realblob = ibase_blob_get($blobid, $this->maxblobsize);
while($string = ibase_blob_get($blobid, 8192)){
$realblob .= $string;
}
} else {
$realblob = ibase_blob_get($blobid, $blob_data[0]);
}
ibase_blob_close( $blobid );
return( $realblob );
}
function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
{
$fd = fopen($path,'rb');
if ($fd === false) return false;
$blob_id = ibase_blob_create($this->_connectionID);
/* fill with data */
while ($val = fread($fd,32768)){
ibase_blob_add($blob_id, $val);
}
/* close and get $blob_id_str for inserting into table */
$blob_id_str = ibase_blob_close($blob_id);
fclose($fd);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
/*
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
Usage:
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$blob_id = ibase_blob_create($this->_connectionID);
// ibase_blob_add($blob_id, $val);
// replacement that solves the problem by which only the first modulus 64K /
// of $val are stored at the blob field ////////////////////////////////////
// Thx Abel Berenstein aberenstein#afip.gov.ar
$len = strlen($val);
$chunk_size = 32768;
$tail_size = $len % $chunk_size;
$n_chunks = ($len - $tail_size) / $chunk_size;
for ($n = 0; $n < $n_chunks; $n++) {
$start = $n * $chunk_size;
$data = substr($val, $start, $chunk_size);
ibase_blob_add($blob_id, $data);
}
if ($tail_size) {
$start = $n_chunks * $chunk_size;
$data = substr($val, $start, $tail_size);
ibase_blob_add($blob_id, $data);
}
// end replacement /////////////////////////////////////////////////////////
$blob_id_str = ibase_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
function OldUpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$blob_id = ibase_blob_create($this->_connectionID);
ibase_blob_add($blob_id, $val);
$blob_id_str = ibase_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
// Format date column in sql string given an input format that understands Y M D
// Only since Interbase 6.0 - uses EXTRACT
// problem - does not zero-fill the day and month yet
function SQLDate($fmt, $col=false)
{
if (!$col) $col = $this->sysDate;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '||';
$ch = $fmt[$i];
switch($ch) {
case 'Y':
case 'y':
$s .= "extract(year from $col)";
break;
case 'M':
case 'm':
$s .= "extract(month from $col)";
break;
case 'Q':
case 'q':
$s .= "cast(((extract(month from $col)+2) / 3) as integer)";
break;
case 'D':
case 'd':
$s .= "(extract(day from $col))";
break;
case 'H':
case 'h':
$s .= "(extract(hour from $col))";
break;
case 'I':
case 'i':
$s .= "(extract(minute from $col))";
break;
case 'S':
case 's':
$s .= "CAST((extract(second from $col)) AS INTEGER)";
break;
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
$s .= $this->qstr($ch);
break;
}
}
return $s;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_ibase extends ADORecordSet
{
var $databaseType = "ibase";
var $bind=false;
var $_cacheType;
function __construct($id,$mode=false)
{
global $ADODB_FETCH_MODE;
$this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;
parent::__construct($id);
}
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
function FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$ibf = ibase_field_info($this->_queryID,$fieldOffset);
$name = empty($ibf['alias']) ? $ibf['name'] : $ibf['alias'];
switch (ADODB_ASSOC_CASE) {
case ADODB_ASSOC_CASE_UPPER:
$fld->name = strtoupper($name);
break;
case ADODB_ASSOC_CASE_LOWER:
$fld->name = strtolower($name);
break;
case ADODB_ASSOC_CASE_NATIVE:
default:
$fld->name = $name;
break;
}
$fld->type = $ibf['type'];
$fld->max_length = $ibf['length'];
/* This needs to be populated from the metadata */
$fld->not_null = false;
$fld->has_default = false;
$fld->default_value = 'null';
return $fld;
}
function _initrs()
{
$this->_numOfRows = -1;
$this->_numOfFields = @ibase_num_fields($this->_queryID);
// cache types for blob decode check
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
$f1 = $this->FetchField($i);
$this->_cacheType[] = $f1->type;
}
}
function _seek($row)
{
return false;
}
function _fetch()
{
$f = @ibase_fetch_row($this->_queryID);
if ($f === false) {
$this->fields = false;
return false;
}
// OPN stuff start - optimized
// fix missing nulls and decode blobs automatically
global $ADODB_ANSI_PADDING_OFF;
//$ADODB_ANSI_PADDING_OFF=1;
$rtrim = !empty($ADODB_ANSI_PADDING_OFF);
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
if ($this->_cacheType[$i]=="BLOB") {
if (isset($f[$i])) {
$f[$i] = $this->connection->_BlobDecode($f[$i]);
} else {
$f[$i] = null;
}
} else {
if (!isset($f[$i])) {
$f[$i] = null;
} else if ($rtrim && is_string($f[$i])) {
$f[$i] = rtrim($f[$i]);
}
}
}
// OPN stuff end
$this->fields = $f;
if ($this->fetchMode == ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc();
} else if ($this->fetchMode == ADODB_FETCH_BOTH) {
$this->fields = array_merge($this->fields,$this->GetRowAssoc());
}
return true;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _close()
{
return @ibase_free_result($this->_queryID);
}
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
case 'CHAR':
return 'C';
case 'TEXT':
case 'VARCHAR':
case 'VARYING':
if ($len <= $this->blobSize) return 'C';
return 'X';
case 'BLOB':
return 'B';
case 'TIMESTAMP':
case 'DATE': return 'D';
case 'TIME': return 'T';
//case 'T': return 'T';
//case 'L': return 'L';
case 'INT':
case 'SHORT':
case 'INTEGER': return 'I';
default: return 'N';
}
}
}
@@ -1,41 +0,0 @@
<?php
/**
* @version v5.20.9 21-Dec-2016
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://php.weblogs.com
*
* Informix 9 driver that supports SELECT FIRST
*
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR.'/drivers/adodb-informix72.inc.php');
class ADODB_informix extends ADODB_informix72 {
var $databaseType = "informix";
var $hasTop = 'FIRST';
var $ansiOuter = true;
function IfNull( $field, $ifNull )
{
return " NVL($field, $ifNull) "; // if Informix 9.X or 10.X
}
}
class ADORecordset_informix extends ADORecordset_informix72 {
var $databaseType = "informix";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}
@@ -1,525 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim. All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Informix port by Mitchell T. Young (mitch@youngfamily.org)
Further mods by "Samuel CARRIERE" <samuel_carriere@hotmail.com>
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (!defined('IFX_SCROLL')) define('IFX_SCROLL',1);
class ADODB_informix72 extends ADOConnection {
var $databaseType = "informix72";
var $dataProvider = "informix";
var $replaceQuote = "''"; // string to use to replace quotes
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $hasInsertID = true;
var $hasAffectedRows = true;
var $substr = 'substr';
var $metaTablesSQL="select tabname,tabtype from systables where tabtype in ('T','V') and owner!='informix'"; //Don't get informix tables and pseudo-tables
var $metaColumnsSQL =
"select c.colname, c.coltype, c.collength, d.default,c.colno
from syscolumns c, systables t,outer sysdefaults d
where c.tabid=t.tabid and d.tabid=t.tabid and d.colno=c.colno
and tabname='%s' order by c.colno";
var $metaPrimaryKeySQL =
"select part1,part2,part3,part4,part5,part6,part7,part8 from
systables t,sysconstraints s,sysindexes i where t.tabname='%s'
and s.tabid=t.tabid and s.constrtype='P'
and i.idxname=s.idxname";
var $concat_operator = '||';
var $lastQuery = false;
var $has_insertid = true;
var $_autocommit = true;
var $_bindInputArray = true; // set to true if ADOConnection.Execute() permits binding of array parameters.
var $sysDate = 'TODAY';
var $sysTimeStamp = 'CURRENT';
var $cursorType = IFX_SCROLL; // IFX_SCROLL or IFX_HOLD or 0
function __construct()
{
// alternatively, use older method:
//putenv("DBDATE=Y4MD-");
// force ISO date format
putenv('GL_DATE=%Y-%m-%d');
if (function_exists('ifx_byteasvarchar')) {
ifx_byteasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content.
ifx_textasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content.
ifx_blobinfile_mode(0); // Mode "0" means save Byte-Blobs in memory, and mode "1" means save Byte-Blobs in a file.
}
}
function ServerInfo()
{
if (isset($this->version)) return $this->version;
$arr['description'] = $this->GetOne("select DBINFO('version','full') from systables where tabid = 1");
$arr['version'] = $this->GetOne("select DBINFO('version','major') || DBINFO('version','minor') from systables where tabid = 1");
$this->version = $arr;
return $arr;
}
function _insertid()
{
$sqlca =ifx_getsqlca($this->lastQuery);
return @$sqlca["sqlerrd1"];
}
function _affectedrows()
{
if ($this->lastQuery) {
return @ifx_affected_rows ($this->lastQuery);
}
return 0;
}
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->Execute('BEGIN');
$this->_autocommit = false;
return true;
}
function CommitTrans($ok=true)
{
if (!$ok) return $this->RollbackTrans();
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$this->Execute('COMMIT');
$this->_autocommit = true;
return true;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$this->Execute('ROLLBACK');
$this->_autocommit = true;
return true;
}
function RowLock($tables,$where,$col='1 as adodbignore')
{
if ($this->_autocommit) $this->BeginTrans();
return $this->GetOne("select $col from $tables where $where for update");
}
/* Returns: the last error message from previous database operation
Note: This function is NOT available for Microsoft SQL Server. */
function ErrorMsg()
{
if (!empty($this->_logsql)) return $this->_errorMsg;
$this->_errorMsg = ifx_errormsg();
return $this->_errorMsg;
}
function ErrorNo()
{
preg_match("/.*SQLCODE=([^\]]*)/",ifx_error(),$parse);
if (is_array($parse) && isset($parse[1])) return (int)$parse[1];
return 0;
}
function MetaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$procedures = array ();
// get index details
$likepattern = '';
if ($NamePattern) {
$likepattern = " WHERE procname LIKE '".$NamePattern."'";
}
$rs = $this->Execute('SELECT procname, isproc FROM sysprocedures'.$likepattern);
if (is_object($rs)) {
// parse index data into array
while ($row = $rs->FetchRow()) {
$procedures[$row[0]] = array(
'type' => ($row[1] == 'f' ? 'FUNCTION' : 'PROCEDURE'),
'catalog' => '',
'schema' => '',
'remarks' => ''
);
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $procedures;
}
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$false = false;
if (!empty($this->metaColumnsSQL)) {
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ($rs === false) return $false;
$rspkey = $this->Execute(sprintf($this->metaPrimaryKeySQL,$table)); //Added to get primary key colno items
$retarr = array();
while (!$rs->EOF) { //print_r($rs->fields);
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
/* //!eos.
$rs->fields[1] is not the correct adodb type
$rs->fields[2] is not correct max_length, because can include not-null bit
$fld->type = $rs->fields[1];
$fld->primary_key=$rspkey->fields && array_search($rs->fields[4],$rspkey->fields); //Added to set primary key flag
$fld->max_length = $rs->fields[2];*/
$pr=ifx_props($rs->fields[1],$rs->fields[2]); //!eos
$fld->type = $pr[0] ;//!eos
$fld->primary_key=$rspkey->fields && array_search($rs->fields[4],$rspkey->fields);
$fld->max_length = $pr[1]; //!eos
$fld->precision = $pr[2] ;//!eos
$fld->not_null = $pr[3]=="N"; //!eos
if (trim($rs->fields[3]) != "AAAAAA 0") {
$fld->has_default = 1;
$fld->default_value = $rs->fields[3];
} else {
$fld->has_default = 0;
}
$retarr[strtolower($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
$rspkey->Close(); //!eos
return $retarr;
}
return $false;
}
function xMetaColumns($table)
{
return ADOConnection::MetaColumns($table,false);
}
function MetaForeignKeys($table, $owner=false, $upper=false) //!Eos
{
$sql = "
select tr.tabname,updrule,delrule,
i.part1 o1,i2.part1 d1,i.part2 o2,i2.part2 d2,i.part3 o3,i2.part3 d3,i.part4 o4,i2.part4 d4,
i.part5 o5,i2.part5 d5,i.part6 o6,i2.part6 d6,i.part7 o7,i2.part7 d7,i.part8 o8,i2.part8 d8
from systables t,sysconstraints s,sysindexes i,
sysreferences r,systables tr,sysconstraints s2,sysindexes i2
where t.tabname='$table'
and s.tabid=t.tabid and s.constrtype='R' and r.constrid=s.constrid
and i.idxname=s.idxname and tr.tabid=r.ptabid
and s2.constrid=r.primary and i2.idxname=s2.idxname";
$rs = $this->Execute($sql);
if (!$rs || $rs->EOF) return false;
$arr = $rs->GetArray();
$a = array();
foreach($arr as $v) {
$coldest=$this->metaColumnNames($v["tabname"]);
$colorig=$this->metaColumnNames($table);
$colnames=array();
for($i=1;$i<=8 && $v["o$i"] ;$i++) {
$colnames[]=$coldest[$v["d$i"]-1]."=".$colorig[$v["o$i"]-1];
}
if($upper)
$a[strtoupper($v["tabname"])] = $colnames;
else
$a[$v["tabname"]] = $colnames;
}
return $a;
}
function UpdateBlob($table, $column, $val, $where, $blobtype = 'BLOB')
{
$type = ($blobtype == 'TEXT') ? 1 : 0;
$blobid = ifx_create_blob($type,0,$val);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blobid));
}
function BlobDecode($blobid)
{
return function_exists('ifx_byteasvarchar') ? $blobid : @ifx_get_blob($blobid);
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('ifx_connect')) return null;
$dbs = $argDatabasename . "@" . $argHostname;
if ($argHostname) putenv("INFORMIXSERVER=$argHostname");
putenv("INFORMIXSERVER=".trim($argHostname));
$this->_connectionID = ifx_connect($dbs,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('ifx_connect')) return null;
$dbs = $argDatabasename . "@" . $argHostname;
putenv("INFORMIXSERVER=".trim($argHostname));
$this->_connectionID = ifx_pconnect($dbs,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
}
/*
// ifx_do does not accept bind parameters - weird ???
function Prepare($sql)
{
$stmt = ifx_prepare($sql);
if (!$stmt) return $sql;
else return array($sql,$stmt);
}
*/
// returns query ID if successful, otherwise false
function _query($sql,$inputarr=false)
{
global $ADODB_COUNTRECS;
// String parameters have to be converted using ifx_create_char
if ($inputarr) {
foreach($inputarr as $v) {
if (gettype($v) == 'string') {
$tab[] = ifx_create_char($v);
}
else {
$tab[] = $v;
}
}
}
// In case of select statement, we use a scroll cursor in order
// to be able to call "move", or "movefirst" statements
if (!$ADODB_COUNTRECS && preg_match("/^\s*select/is", $sql)) {
if ($inputarr) {
$this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType, $tab);
}
else {
$this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType);
}
}
else {
if ($inputarr) {
$this->lastQuery = ifx_query($sql,$this->_connectionID, $tab);
}
else {
$this->lastQuery = ifx_query($sql,$this->_connectionID);
}
}
// Following line have been commented because autocommit mode is
// not supported by informix SE 7.2
//if ($this->_autocommit) ifx_query('COMMIT',$this->_connectionID);
return $this->lastQuery;
}
// returns true or false
function _close()
{
$this->lastQuery = false;
if($this->_connectionID) {
return ifx_close($this->_connectionID);
}
return true;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_informix72 extends ADORecordSet {
var $databaseType = "informix72";
var $canSeek = true;
var $_fieldprops = false;
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id);
}
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
function FetchField($fieldOffset = -1)
{
if (empty($this->_fieldprops)) {
$fp = ifx_fieldproperties($this->_queryID);
foreach($fp as $k => $v) {
$o = new ADOFieldObject;
$o->name = $k;
$arr = explode(';',$v); //"SQLTYPE;length;precision;scale;ISNULLABLE"
$o->type = $arr[0];
$o->max_length = $arr[1];
$this->_fieldprops[] = $o;
$o->not_null = $arr[4]=="N";
}
}
$ret = $this->_fieldprops[$fieldOffset];
return $ret;
}
function _initrs()
{
$this->_numOfRows = -1; // ifx_affected_rows not reliable, only returns estimate -- ($ADODB_COUNTRECS)? ifx_affected_rows($this->_queryID):-1;
$this->_numOfFields = ifx_num_fields($this->_queryID);
}
function _seek($row)
{
return @ifx_fetch_row($this->_queryID, (int) $row);
}
function MoveLast()
{
$this->fields = @ifx_fetch_row($this->_queryID, "LAST");
if ($this->fields) $this->EOF = false;
$this->_currentRow = -1;
if ($this->fetchMode == ADODB_FETCH_NUM) {
foreach($this->fields as $v) {
$arr[] = $v;
}
$this->fields = $arr;
}
return true;
}
function MoveFirst()
{
$this->fields = @ifx_fetch_row($this->_queryID, "FIRST");
if ($this->fields) $this->EOF = false;
$this->_currentRow = 0;
if ($this->fetchMode == ADODB_FETCH_NUM) {
foreach($this->fields as $v) {
$arr[] = $v;
}
$this->fields = $arr;
}
return true;
}
function _fetch($ignore_fields=false)
{
$this->fields = @ifx_fetch_row($this->_queryID);
if (!is_array($this->fields)) return false;
if ($this->fetchMode == ADODB_FETCH_NUM) {
foreach($this->fields as $v) {
$arr[] = $v;
}
$this->fields = $arr;
}
return true;
}
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close()
{
if($this->_queryID) {
return ifx_free_result($this->_queryID);
}
return true;
}
}
/** !Eos
* Auxiliar function to Parse coltype,collength. Used by Metacolumns
* return: array ($mtype,$length,$precision,$nullable) (similar to ifx_fieldpropierties)
*/
function ifx_props($coltype,$collength){
$itype=fmod($coltype+1,256);
$nullable=floor(($coltype+1) /256) ?"N":"Y";
$mtype=substr(" CIIFFNNDN TBXCC ",$itype,1);
switch ($itype){
case 2:
$length=4;
case 6:
case 9:
case 14:
$length=floor($collength/256);
$precision=fmod($collength,256);
break;
default:
$precision=0;
$length=$collength;
}
return array($mtype,$length,$precision,$nullable);
}
-428
View File
@@ -1,428 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 8.
Revision 1: (02/25/2005) Updated codebase to include the _inject_bind_options function. This allows
users to access the options in the ldap_set_option function appropriately. Most importantly
LDAP Version 3 is now supported. See the examples for more information. Also fixed some minor
bugs that surfaced when PHP error levels were set high.
Joshua Eldridge (joshuae74#hotmail.com)
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (!defined('LDAP_ASSOC')) {
define('LDAP_ASSOC',ADODB_FETCH_ASSOC);
define('LDAP_NUM',ADODB_FETCH_NUM);
define('LDAP_BOTH',ADODB_FETCH_BOTH);
}
class ADODB_ldap extends ADOConnection {
var $databaseType = 'ldap';
var $dataProvider = 'ldap';
# Connection information
var $username = false;
var $password = false;
# Used during searches
var $filter;
var $dn;
var $version;
var $port = 389;
# Options configuration information
var $LDAP_CONNECT_OPTIONS;
# error on binding, eg. "Binding: invalid credentials"
var $_bind_errmsg = "Binding: %s";
function __construct()
{
}
// returns true or false
function _connect( $host, $username, $password, $ldapbase)
{
global $LDAP_CONNECT_OPTIONS;
if ( !function_exists( 'ldap_connect' ) ) return null;
if (strpos($host,'ldap://') === 0 || strpos($host,'ldaps://') === 0) {
$this->_connectionID = @ldap_connect($host);
} else {
$conn_info = array( $host,$this->port);
if ( strstr( $host, ':' ) ) {
$conn_info = explode( ':', $host );
}
$this->_connectionID = @ldap_connect( $conn_info[0], $conn_info[1] );
}
if (!$this->_connectionID) {
$e = 'Could not connect to ' . $conn_info[0];
$this->_errorMsg = $e;
if ($this->debug) ADOConnection::outp($e);
return false;
}
if( count( $LDAP_CONNECT_OPTIONS ) > 0 ) {
$this->_inject_bind_options( $LDAP_CONNECT_OPTIONS );
}
if ($username) {
$bind = @ldap_bind( $this->_connectionID, $username, $password );
} else {
$username = 'anonymous';
$bind = @ldap_bind( $this->_connectionID );
}
if (!$bind) {
$e = sprintf($this->_bind_errmsg,ldap_error($this->_connectionID));
$this->_errorMsg = $e;
if ($this->debug) ADOConnection::outp($e);
return false;
}
$this->_errorMsg = '';
$this->database = $ldapbase;
return $this->_connectionID;
}
/*
Valid Domain Values for LDAP Options:
LDAP_OPT_DEREF (integer)
LDAP_OPT_SIZELIMIT (integer)
LDAP_OPT_TIMELIMIT (integer)
LDAP_OPT_PROTOCOL_VERSION (integer)
LDAP_OPT_ERROR_NUMBER (integer)
LDAP_OPT_REFERRALS (boolean)
LDAP_OPT_RESTART (boolean)
LDAP_OPT_HOST_NAME (string)
LDAP_OPT_ERROR_STRING (string)
LDAP_OPT_MATCHED_DN (string)
LDAP_OPT_SERVER_CONTROLS (array)
LDAP_OPT_CLIENT_CONTROLS (array)
Make sure to set this BEFORE calling Connect()
Example:
$LDAP_CONNECT_OPTIONS = Array(
Array (
"OPTION_NAME"=>LDAP_OPT_DEREF,
"OPTION_VALUE"=>2
),
Array (
"OPTION_NAME"=>LDAP_OPT_SIZELIMIT,
"OPTION_VALUE"=>100
),
Array (
"OPTION_NAME"=>LDAP_OPT_TIMELIMIT,
"OPTION_VALUE"=>30
),
Array (
"OPTION_NAME"=>LDAP_OPT_PROTOCOL_VERSION,
"OPTION_VALUE"=>3
),
Array (
"OPTION_NAME"=>LDAP_OPT_ERROR_NUMBER,
"OPTION_VALUE"=>13
),
Array (
"OPTION_NAME"=>LDAP_OPT_REFERRALS,
"OPTION_VALUE"=>FALSE
),
Array (
"OPTION_NAME"=>LDAP_OPT_RESTART,
"OPTION_VALUE"=>FALSE
)
);
*/
function _inject_bind_options( $options ) {
foreach( $options as $option ) {
ldap_set_option( $this->_connectionID, $option["OPTION_NAME"], $option["OPTION_VALUE"] )
or die( "Unable to set server option: " . $option["OPTION_NAME"] );
}
}
/* returns _queryID or false */
function _query($sql,$inputarr=false)
{
$rs = @ldap_search( $this->_connectionID, $this->database, $sql );
$this->_errorMsg = ($rs) ? '' : 'Search error on '.$sql.': '.ldap_error($this->_connectionID);
return $rs;
}
function ErrorMsg()
{
return $this->_errorMsg;
}
function ErrorNo()
{
return @ldap_errno($this->_connectionID);
}
/* closes the LDAP connection */
function _close()
{
@ldap_close( $this->_connectionID );
$this->_connectionID = false;
}
function SelectDB($db) {
$this->database = $db;
return true;
} // SelectDB
function ServerInfo()
{
if( !empty( $this->version ) ) {
return $this->version;
}
$version = array();
/*
Determines how aliases are handled during search.
LDAP_DEREF_NEVER (0x00)
LDAP_DEREF_SEARCHING (0x01)
LDAP_DEREF_FINDING (0x02)
LDAP_DEREF_ALWAYS (0x03)
The LDAP_DEREF_SEARCHING value means aliases are dereferenced during the search but
not when locating the base object of the search. The LDAP_DEREF_FINDING value means
aliases are dereferenced when locating the base object but not during the search.
Default: LDAP_DEREF_NEVER
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_DEREF, $version['LDAP_OPT_DEREF'] ) ;
switch ( $version['LDAP_OPT_DEREF'] ) {
case 0:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_NEVER';
case 1:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_SEARCHING';
case 2:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_FINDING';
case 3:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_ALWAYS';
}
/*
A limit on the number of entries to return from a search.
LDAP_NO_LIMIT (0) means no limit.
Default: LDAP_NO_LIMIT
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_SIZELIMIT, $version['LDAP_OPT_SIZELIMIT'] );
if ( $version['LDAP_OPT_SIZELIMIT'] == 0 ) {
$version['LDAP_OPT_SIZELIMIT'] = 'LDAP_NO_LIMIT';
}
/*
A limit on the number of seconds to spend on a search.
LDAP_NO_LIMIT (0) means no limit.
Default: LDAP_NO_LIMIT
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_TIMELIMIT, $version['LDAP_OPT_TIMELIMIT'] );
if ( $version['LDAP_OPT_TIMELIMIT'] == 0 ) {
$version['LDAP_OPT_TIMELIMIT'] = 'LDAP_NO_LIMIT';
}
/*
Determines whether the LDAP library automatically follows referrals returned by LDAP servers or not.
LDAP_OPT_ON
LDAP_OPT_OFF
Default: ON
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_REFERRALS, $version['LDAP_OPT_REFERRALS'] );
if ( $version['LDAP_OPT_REFERRALS'] == 0 ) {
$version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_OFF';
} else {
$version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_ON';
}
/*
Determines whether LDAP I/O operations are automatically restarted if they abort prematurely.
LDAP_OPT_ON
LDAP_OPT_OFF
Default: OFF
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_RESTART, $version['LDAP_OPT_RESTART'] );
if ( $version['LDAP_OPT_RESTART'] == 0 ) {
$version['LDAP_OPT_RESTART'] = 'LDAP_OPT_OFF';
} else {
$version['LDAP_OPT_RESTART'] = 'LDAP_OPT_ON';
}
/*
This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server.
LDAP_VERSION2 (2)
LDAP_VERSION3 (3)
Default: LDAP_VERSION2 (2)
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_PROTOCOL_VERSION, $version['LDAP_OPT_PROTOCOL_VERSION'] );
if ( $version['LDAP_OPT_PROTOCOL_VERSION'] == 2 ) {
$version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION2';
} else {
$version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION3';
}
/* The host name (or list of hosts) for the primary LDAP server. */
ldap_get_option( $this->_connectionID, LDAP_OPT_HOST_NAME, $version['LDAP_OPT_HOST_NAME'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_ERROR_NUMBER, $version['LDAP_OPT_ERROR_NUMBER'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_ERROR_STRING, $version['LDAP_OPT_ERROR_STRING'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_MATCHED_DN, $version['LDAP_OPT_MATCHED_DN'] );
return $this->version = $version;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_ldap extends ADORecordSet{
var $databaseType = "ldap";
var $canSeek = false;
var $_entryID; /* keeps track of the entry resource identifier */
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM:
$this->fetchMode = LDAP_NUM;
break;
case ADODB_FETCH_ASSOC:
$this->fetchMode = LDAP_ASSOC;
break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = LDAP_BOTH;
break;
}
parent::__construct($queryID);
}
function _initrs()
{
/*
This could be teaked to respect the $COUNTRECS directive from ADODB
It's currently being used in the _fetch() function and the
GetAssoc() function
*/
$this->_numOfRows = ldap_count_entries( $this->connection->_connectionID, $this->_queryID );
}
/*
Return whole recordset as a multi-dimensional associative array
*/
function GetAssoc($force_array = false, $first2cols = false)
{
$records = $this->_numOfRows;
$results = array();
for ( $i=0; $i < $records; $i++ ) {
foreach ( $this->fields as $k=>$v ) {
if ( is_array( $v ) ) {
if ( $v['count'] == 1 ) {
$results[$i][$k] = $v[0];
} else {
array_shift( $v );
$results[$i][$k] = $v;
}
}
}
}
return $results;
}
function GetRowAssoc($upper = ADODB_ASSOC_CASE)
{
$results = array();
foreach ( $this->fields as $k=>$v ) {
if ( is_array( $v ) ) {
if ( $v['count'] == 1 ) {
$results[$k] = $v[0];
} else {
array_shift( $v );
$results[$k] = $v;
}
}
}
return $results;
}
function GetRowNums()
{
$results = array();
foreach ( $this->fields as $k=>$v ) {
static $i = 0;
if (is_array( $v )) {
if ( $v['count'] == 1 ) {
$results[$i] = $v[0];
} else {
array_shift( $v );
$results[$i] = $v;
}
$i++;
}
}
return $results;
}
function _fetch()
{
if ( $this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0 ) {
return false;
}
if ( $this->_currentRow == 0 ) {
$this->_entryID = ldap_first_entry( $this->connection->_connectionID, $this->_queryID );
} else {
$this->_entryID = ldap_next_entry( $this->connection->_connectionID, $this->_entryID );
}
$this->fields = ldap_get_attributes( $this->connection->_connectionID, $this->_entryID );
$this->_numOfFields = $this->fields['count'];
switch ( $this->fetchMode ) {
case LDAP_ASSOC:
$this->fields = $this->GetRowAssoc();
break;
case LDAP_NUM:
$this->fields = array_merge($this->GetRowNums(),$this->GetRowAssoc());
break;
case LDAP_BOTH:
default:
$this->fields = $this->GetRowNums();
break;
}
return is_array( $this->fields );
}
function _close() {
@ldap_free_result( $this->_queryID );
$this->_queryID = false;
}
}
-1178
View File
@@ -1,1178 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Native mssql driver. Requires mssql client. Works on Windows.
To configure for Unix, see
http://phpbuilder.com/columns/alberto20000919.php3
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
//----------------------------------------------------------------
// MSSQL returns dates with the format Oct 13 2002 or 13 Oct 2002
// and this causes tons of problems because localized versions of
// MSSQL will return the dates in dmy or mdy order; and also the
// month strings depends on what language has been configured. The
// following two variables allow you to control the localization
// settings - Ugh.
//
// MORE LOCALIZATION INFO
// ----------------------
// To configure datetime, look for and modify sqlcommn.loc,
// typically found in c:\mssql\install
// Also read :
// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
// Alternatively use:
// CONVERT(char(12),datecol,120)
//----------------------------------------------------------------
// has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
if (ADODB_PHPVER >= 0x4300) {
// docs say 4.2.0, but testing shows only since 4.3.0 does it work!
ini_set('mssql.datetimeconvert',0);
} else {
global $ADODB_mssql_mths; // array, months must be upper-case
$ADODB_mssql_date_order = 'mdy';
$ADODB_mssql_mths = array(
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
}
//---------------------------------------------------------------------------
// Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
// just after you connect to the database. Supports mdy and dmy only.
// Not required for PHP 4.2.0 and above.
function AutoDetect_MSSQL_Date_Order($conn)
{
global $ADODB_mssql_date_order;
$adate = $conn->GetOne('select getdate()');
if ($adate) {
$anum = (int) $adate;
if ($anum > 0) {
if ($anum > 31) {
//ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
} else
$ADODB_mssql_date_order = 'dmy';
} else
$ADODB_mssql_date_order = 'mdy';
}
}
class ADODB_mssql extends ADOConnection {
var $databaseType = "mssql";
var $dataProvider = "mssql";
var $replaceQuote = "''"; // string to use to replace quotes
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d\TH:i:s'";
var $hasInsertID = true;
var $substr = "substring";
var $length = 'len';
var $hasAffectedRows = true;
var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
var $metaColumnsSQL = # xtype==61 is datetime
"select c.name,t.name,c.length,c.isnullable, c.status,
(case when c.xusertype=61 then 0 else c.xprec end),
(case when c.xusertype=61 then 0 else c.xscale end)
from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
var $hasGenID = true;
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
var $sysTimeStamp = 'GetDate()';
var $_has_mssql_init;
var $maxParameterLen = 4000;
var $arrayClass = 'ADORecordSet_array_mssql';
var $uniqueSort = true;
var $leftOuter = '*=';
var $rightOuter = '=*';
var $ansiOuter = true; // for mssql7 or later
var $poorAffectedRows = true;
var $identitySQL = 'select SCOPE_IDENTITY()'; // 'select SCOPE_IDENTITY'; # for mssql 2000
var $uniqueOrderBy = true;
var $_bindInputArray = true;
var $forceNewConnect = false;
function __construct()
{
$this->_has_mssql_init = (strnatcmp(PHP_VERSION,'4.1.0')>=0);
}
function ServerInfo()
{
global $ADODB_FETCH_MODE;
if ($this->fetchMode === false) {
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
} else
$savem = $this->SetFetchMode(ADODB_FETCH_NUM);
if (0) {
$stmt = $this->PrepareSP('sp_server_info');
$val = 2;
$this->Parameter($stmt,$val,'attribute_id');
$row = $this->GetRow($stmt);
}
$row = $this->GetRow("execute sp_server_info 2");
if ($this->fetchMode === false) {
$ADODB_FETCH_MODE = $savem;
} else
$this->SetFetchMode($savem);
$arr['description'] = $row[2];
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
function IfNull( $field, $ifNull )
{
return " ISNULL($field, $ifNull) "; // if MS SQL Server
}
function _insertid()
{
// SCOPE_IDENTITY()
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// they are in the same stored procedure, function, or batch.
if ($this->lastInsID !== false) {
return $this->lastInsID; // InsID from sp_executesql call
} else {
return $this->GetOne($this->identitySQL);
}
}
/**
* Correctly quotes a string so that all strings are escaped. We prefix and append
* to the string single-quotes.
* An example is $db->qstr("Don't bother",magic_quotes_runtime());
*
* @param s the string to quote
* @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc().
* This undoes the stupidity of magic quotes for GPC.
*
* @return quoted string to be sent back to database
*/
function qstr($s,$magic_quotes=false)
{
if (!$magic_quotes) {
return "'".str_replace("'",$this->replaceQuote,$s)."'";
}
// undo magic quotes for " unless sybase is on
$sybase = ini_get('magic_quotes_sybase');
if (!$sybase) {
$s = str_replace('\\"','"',$s);
if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything
return "'$s'";
else {// change \' to '' for sybase/mssql
$s = str_replace('\\\\','\\',$s);
return "'".str_replace("\\'",$this->replaceQuote,$s)."'";
}
} else {
return "'".$s."'";
}
}
// moodle change end - see readme_moodle.txt
function _affectedrows()
{
return $this->GetOne('select @@rowcount');
}
var $_dropSeqSQL = "drop table %s";
function CreateSequence($seq='adodbseq',$start=1)
{
$this->Execute('BEGIN TRANSACTION adodbseq');
$start -= 1;
$this->Execute("create table $seq (id float(53))");
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
if (!$ok) {
$this->Execute('ROLLBACK TRANSACTION adodbseq');
return false;
}
$this->Execute('COMMIT TRANSACTION adodbseq');
return true;
}
function GenID($seq='adodbseq',$start=1)
{
//$this->debug=1;
$this->Execute('BEGIN TRANSACTION adodbseq');
$ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
if (!$ok) {
$this->Execute("create table $seq (id float(53))");
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
if (!$ok) {
$this->Execute('ROLLBACK TRANSACTION adodbseq');
return false;
}
$this->Execute('COMMIT TRANSACTION adodbseq');
return $start;
}
$num = $this->GetOne("select id from $seq");
$this->Execute('COMMIT TRANSACTION adodbseq');
return $num;
// in old implementation, pre 1.90, we returned GUID...
//return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) AS 'Char'");
}
function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
if ($nrows > 0 && $offset <= 0) {
$sql = preg_replace(
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
if ($secs2cache)
$rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
else
$rs = $this->Execute($sql,$inputarr);
} else
$rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
if (!$col) $col = $this->sysTimeStamp;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '+';
$ch = $fmt[$i];
switch($ch) {
case 'Y':
case 'y':
$s .= "datename(yyyy,$col)";
break;
case 'M':
$s .= "convert(char(3),$col,0)";
break;
case 'm':
$s .= "replace(str(month($col),2),' ','0')";
break;
case 'Q':
case 'q':
$s .= "datename(quarter,$col)";
break;
case 'D':
case 'd':
$s .= "replace(str(day($col),2),' ','0')";
break;
case 'h':
$s .= "substring(convert(char(14),$col,0),13,2)";
break;
case 'H':
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'i':
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
break;
case 's':
$s .= "replace(str(datepart(ss,$col),2),' ','0')";
break;
case 'a':
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
$s .= $this->qstr($ch);
break;
}
}
return $s;
}
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
$ok = $this->Execute('BEGIN TRAN');
return $ok;
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$ok = $this->Execute('COMMIT TRAN');
return $ok;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$ok = $this->Execute('ROLLBACK TRAN');
return $ok;
}
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
$this->Execute('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
return;
}
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
/*
Usage:
$this->BeginTrans();
$this->RowLock('table1,table2','table1.id=33 and table2.id=table1.id'); # lock row 33 for both tables
# some operation on both tables table1 and table2
$this->CommitTrans();
See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
*/
function RowLock($tables,$where,$col='1 as adodbignore')
{
if ($col == '1 as adodbignore') $col = 'top 1 null as ignore';
if (!$this->transCnt) $this->BeginTrans();
return $this->GetOne("select $col from $tables with (ROWLOCK,HOLDLOCK) where $where");
}
function MetaColumns($table, $normalize=true)
{
// $arr = ADOConnection::MetaColumns($table);
// return $arr;
$this->_findschema($table,$schema);
if ($schema) {
$dbName = $this->database;
$this->SelectDB($schema);
}
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($schema) {
$this->SelectDB($dbName);
}
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
$false = false;
return $false;
}
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->not_null = (!$rs->fields[3]);
$fld->auto_increment = ($rs->fields[4] == 128); // sys.syscolumns status field. 0x80 = 128 ref: http://msdn.microsoft.com/en-us/library/ms186816.aspx
if (isset($rs->fields[5]) && $rs->fields[5]) {
if ($rs->fields[5]>0) $fld->max_length = $rs->fields[5];
$fld->scale = $rs->fields[6];
if ($fld->scale>0) $fld->max_length += 1;
} else
$fld->max_length = $rs->fields[2];
if ($save == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
$retarr[strtoupper($fld->name)] = $fld;
}
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
function MetaIndexes($table,$primary=false, $owner=false)
{
$table = $this->qstr($table);
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
ORDER BY O.name, I.Name, K.keyno";
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute($sql);
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return FALSE;
}
$indexes = array();
while ($row = $rs->FetchRow()) {
if ($primary && !$row[5]) continue;
$indexes[$row[0]]['unique'] = $row[6];
$indexes[$row[0]]['columns'][] = $row[1];
}
return $indexes;
}
function MetaForeignKeys($table, $owner=false, $upper=false)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$table = $this->qstr(strtoupper($table));
$sql =
"select object_name(constid) as constraint_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
col_name(rkeyid, rkey) as referenced_column_name
from sysforeignkeys
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
$constraints = $this->GetArray($sql);
$ADODB_FETCH_MODE = $save;
$arr = false;
foreach($constraints as $constr) {
//print_r($constr);
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
}
if (!$arr) return false;
$arr2 = false;
foreach($arr as $k => $v) {
foreach($v as $a => $b) {
if ($upper) $a = strtoupper($a);
$arr2[$a] = $b;
}
}
return $arr2;
}
//From: Fernando Moreira <FMoreira@imediata.pt>
function MetaDatabases()
{
if(@mssql_select_db("master")) {
$qry=$this->metaDatabasesSQL;
if($rs=@mssql_query($qry,$this->_connectionID)){
$tmpAr=$ar=array();
while($tmpAr=@mssql_fetch_row($rs))
$ar[]=$tmpAr[0];
@mssql_select_db($this->database);
if(sizeof($ar))
return($ar);
else
return(false);
} else {
@mssql_select_db($this->database);
return(false);
}
}
return(false);
}
// "Stein-Aksel Basma" <basma@accelero.no>
// tested with MSSQL 2000
function MetaPrimaryKeys($table, $owner=false)
{
global $ADODB_FETCH_MODE;
$schema = '';
$this->_findschema($table,$schema);
if (!$schema) $schema = $this->database;
if ($schema) $schema = "and k.table_catalog like '$schema%'";
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
information_schema.table_constraints tc
where tc.constraint_name = k.constraint_name and tc.constraint_type =
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$a = $this->GetCol($sql);
$ADODB_FETCH_MODE = $savem;
if ($a && sizeof($a)>0) return $a;
$false = false;
return $false;
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(($mask));
$this->metaTablesSQL .= " AND name like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
function SelectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {
return @mssql_select_db($dbName);
}
else return false;
}
function ErrorMsg()
{
if (empty($this->_errorMsg)){
$this->_errorMsg = mssql_get_last_message();
}
return $this->_errorMsg;
}
function ErrorNo()
{
if ($this->_logsql && $this->_errorCode !== false) return $this->_errorCode;
if (empty($this->_errorMsg)) {
$this->_errorMsg = mssql_get_last_message();
}
$id = @mssql_query("select @@ERROR",$this->_connectionID);
if (!$id) return false;
$arr = mssql_fetch_array($id);
@mssql_free_result($id);
if (is_array($arr)) return $arr[0];
else return -1;
}
// returns true or false, newconnect supported since php 5.1.0.
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$newconnect=false)
{
if (!function_exists('mssql_pconnect')) return null;
$this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword,$newconnect);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('mssql_pconnect')) return null;
$this->_connectionID = mssql_pconnect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
// persistent connections can forget to rollback on crash, so we do it here.
if ($this->autoRollback) {
$cnt = $this->GetOne('select @@TRANCOUNT');
while (--$cnt >= 0) $this->Execute('ROLLBACK TRAN');
}
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
}
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
}
function Prepare($sql)
{
$sqlarr = explode('?',$sql);
if (sizeof($sqlarr) <= 1) return $sql;
$sql2 = $sqlarr[0];
for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {
$sql2 .= '@P'.($i-1) . $sqlarr[$i];
}
return array($sql,$this->qstr($sql2),$max,$sql2);
}
function PrepareSP($sql,$param=true)
{
if (!$this->_has_mssql_init) {
ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
return $sql;
}
$stmt = mssql_init($sql,$this->_connectionID);
if (!$stmt) return $sql;
return array($sql,$stmt);
}
// returns concatenated string
// MSSQL requires integers to be cast as strings
// automatically cast every datatype to VARCHAR(255)
// @author David Rogers (introspectshun)
function Concat()
{
$s = "";
$arr = func_get_args();
// Split single record on commas, if possible
if (sizeof($arr) == 1) {
foreach ($arr as $arg) {
$args = explode(',', $arg);
}
$arr = $args;
}
array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
$s = implode('+',$arr);
if (sizeof($arr) > 0) return "$s";
return '';
}
/*
Usage:
$stmt = $db->PrepareSP('SP_RUNSOMETHING'); -- takes 2 params, @myid and @group
# note that the parameter does not have @ in front!
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group',false,64);
$db->Execute($stmt);
@param $stmt Statement returned by Prepare() or PrepareSP().
@param $var PHP variable to bind to. Can set to null (for isNull support).
@param $name Name of stored procedure variable name to bind to.
@param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
@param [$maxLen] Holds an maximum length of the variable.
@param [$type] The data type of $var. Legal values depend on driver.
See mssql_bind documentation at php.net.
*/
function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=4000, $type=false)
{
if (!$this->_has_mssql_init) {
ADOConnection::outp( "Parameter: mssql_bind only available since PHP 4.1.0");
return false;
}
$isNull = is_null($var); // php 4.0.4 and above...
if ($type === false)
switch(gettype($var)) {
default:
case 'string': $type = SQLVARCHAR; break;
case 'double': $type = SQLFLT8; break;
case 'integer': $type = SQLINT4; break;
case 'boolean': $type = SQLINT1; break; # SQLBIT not supported in 4.1.0
}
if ($this->debug) {
$prefix = ($isOutput) ? 'Out' : 'In';
$ztype = (empty($type)) ? 'false' : $type;
ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
}
/*
See http://phplens.com/lens/lensforum/msgs.php?id=7231
RETVAL is HARD CODED into php_mssql extension:
The return value (a long integer value) is treated like a special OUTPUT parameter,
called "RETVAL" (without the @). See the example at mssql_execute to
see how it works. - type: one of this new supported PHP constants.
SQLTEXT, SQLVARCHAR,SQLCHAR, SQLINT1,SQLINT2, SQLINT4, SQLBIT,SQLFLT8
*/
if ($name !== 'RETVAL') $name = '@'.$name;
return mssql_bind($stmt[1], $name, $var, $type, $isOutput, $isNull, $maxLen);
}
/*
Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
So all your blobs must be of type "image".
Remember to set in php.ini the following...
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 0 ; zero to pass through
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 0 ; zero to pass through
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
if (strtoupper($blobtype) == 'CLOB') {
$sql = "UPDATE $table SET $column='" . $val . "' WHERE $where";
return $this->Execute($sql) != false;
}
$sql = "UPDATE $table SET $column=0x".bin2hex($val)." WHERE $where";
return $this->Execute($sql) != false;
}
// returns query ID if successful, otherwise false
function _query($sql,$inputarr=false)
{
$this->_errorMsg = false;
if (is_array($inputarr)) {
# bind input params with sp_executesql:
# see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm
# works only with sql server 7 and newer
$getIdentity = false;
if (!is_array($sql) && preg_match('/^\\s*insert/i', $sql)) {
$getIdentity = true;
$sql .= (preg_match('/;\\s*$/i', $sql) ? ' ' : '; ') . $this->identitySQL;
}
if (!is_array($sql)) $sql = $this->Prepare($sql);
$params = '';
$decl = '';
$i = 0;
foreach($inputarr as $v) {
if ($decl) {
$decl .= ', ';
$params .= ', ';
}
if (is_string($v)) {
$len = strlen($v);
if ($len == 0) $len = 1;
if ($len > 4000 ) {
// NVARCHAR is max 4000 chars. Let's use NTEXT
$decl .= "@P$i NTEXT";
} else {
$decl .= "@P$i NVARCHAR($len)";
}
$params .= "@P$i=N". (strncmp($v,"'",1)==0? $v : $this->qstr($v));
} else if (is_integer($v)) {
$decl .= "@P$i INT";
$params .= "@P$i=".$v;
} else if (is_float($v)) {
$decl .= "@P$i FLOAT";
$params .= "@P$i=".$v;
} else if (is_bool($v)) {
$decl .= "@P$i INT"; # Used INT just in case BIT in not supported on the user's MSSQL version. It will cast appropriately.
$params .= "@P$i=".(($v)?'1':'0'); # True == 1 in MSSQL BIT fields and acceptable for storing logical true in an int field
} else {
$decl .= "@P$i CHAR"; # Used char because a type is required even when the value is to be NULL.
$params .= "@P$i=NULL";
}
$i += 1;
}
$decl = $this->qstr($decl);
if ($this->debug) ADOConnection::outp("<font size=-1>sp_executesql N{$sql[1]},N$decl,$params</font>");
$rez = mssql_query("sp_executesql N{$sql[1]},N$decl,$params", $this->_connectionID);
if ($getIdentity) {
$arr = @mssql_fetch_row($rez);
$this->lastInsID = isset($arr[0]) ? $arr[0] : false;
@mssql_data_seek($rez, 0);
}
} else if (is_array($sql)) {
# PrepareSP()
$rez = mssql_execute($sql[1]);
$this->lastInsID = false;
} else {
$rez = mssql_query($sql,$this->_connectionID);
$this->lastInsID = false;
}
return $rez;
}
// returns true or false
function _close()
{
if ($this->transCnt) $this->RollbackTrans();
$rez = @mssql_close($this->_connectionID);
$this->_connectionID = false;
return $rez;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssql::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_mssql extends ADORecordSet {
var $databaseType = "mssql";
var $canSeek = true;
var $hasFetchAssoc; // see http://phplens.com/lens/lensforum/msgs.php?id=6083
// _mths works only in non-localised system
function __construct($id,$mode=false)
{
// freedts check...
$this->hasFetchAssoc = function_exists('mssql_fetch_assoc');
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id,$mode);
}
function _initrs()
{
GLOBAL $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS)? @mssql_num_rows($this->_queryID):-1;
$this->_numOfFields = @mssql_num_fields($this->_queryID);
}
//Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
// get next resultset - requires PHP 4.0.5 or later
function NextRecordSet()
{
if (!mssql_next_result($this->_queryID)) return false;
$this->_inited = false;
$this->bind = false;
$this->_currentRow = -1;
$this->Init();
return true;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode != ADODB_FETCH_NUM) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
function FetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$f = @mssql_fetch_field($this->_queryID, $fieldOffset);
}
else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
$f = @mssql_fetch_field($this->_queryID);
}
$false = false;
if (empty($f)) return $false;
return $f;
}
function _seek($row)
{
return @mssql_data_seek($this->_queryID, $row);
}
// speedup
function MoveNext()
{
if ($this->EOF) return false;
$this->_currentRow++;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
if ($this->fetchMode & ADODB_FETCH_NUM) {
//ADODB_FETCH_BOTH mode
$this->fields = @mssql_fetch_array($this->_queryID);
}
else {
if ($this->hasFetchAssoc) {// only for PHP 4.2.0 or later
$this->fields = @mssql_fetch_assoc($this->_queryID);
} else {
$flds = @mssql_fetch_array($this->_queryID);
if (is_array($flds)) {
$fassoc = array();
foreach($flds as $k => $v) {
if (is_numeric($k)) continue;
$fassoc[$k] = $v;
}
$this->fields = $fassoc;
} else
$this->fields = false;
}
}
if (is_array($this->fields)) {
if (ADODB_ASSOC_CASE == 0) {
foreach($this->fields as $k=>$v) {
$kn = strtolower($k);
if ($kn <> $k) {
unset($this->fields[$k]);
$this->fields[$kn] = $v;
}
}
} else if (ADODB_ASSOC_CASE == 1) {
foreach($this->fields as $k=>$v) {
$kn = strtoupper($k);
if ($kn <> $k) {
unset($this->fields[$k]);
$this->fields[$kn] = $v;
}
}
}
}
} else {
$this->fields = @mssql_fetch_row($this->_queryID);
}
if ($this->fields) return true;
$this->EOF = true;
return false;
}
// INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
// also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
function _fetch($ignore_fields=false)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
if ($this->fetchMode & ADODB_FETCH_NUM) {
//ADODB_FETCH_BOTH mode
$this->fields = @mssql_fetch_array($this->_queryID);
} else {
if ($this->hasFetchAssoc) // only for PHP 4.2.0 or later
$this->fields = @mssql_fetch_assoc($this->_queryID);
else {
$this->fields = @mssql_fetch_array($this->_queryID);
if (@is_array($$this->fields)) {
$fassoc = array();
foreach($$this->fields as $k => $v) {
if (is_integer($k)) continue;
$fassoc[$k] = $v;
}
$this->fields = $fassoc;
}
}
}
if (!$this->fields) {
} else if (ADODB_ASSOC_CASE == 0) {
foreach($this->fields as $k=>$v) {
$kn = strtolower($k);
if ($kn <> $k) {
unset($this->fields[$k]);
$this->fields[$kn] = $v;
}
}
} else if (ADODB_ASSOC_CASE == 1) {
foreach($this->fields as $k=>$v) {
$kn = strtoupper($k);
if ($kn <> $k) {
unset($this->fields[$k]);
$this->fields[$kn] = $v;
}
}
}
} else {
$this->fields = @mssql_fetch_row($this->_queryID);
}
return $this->fields;
}
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close()
{
if($this->_queryID) {
$rez = mssql_free_result($this->_queryID);
$this->_queryID = false;
return $rez;
}
return true;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssql::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
}
}
class ADORecordSet_array_mssql extends ADORecordSet_array {
function __construct($id=-1,$mode=false)
{
parent::__construct($id,$mode);
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
if ($ADODB_mssql_date_order == 'dmy') {
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
return parent::UnixDate($v);
}
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[1];
$themth = substr(strtoupper($rr[2]),0,3);
} else {
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
return parent::UnixDate($v);
}
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[2];
$themth = substr(strtoupper($rr[1]),0,3);
}
$themth = $ADODB_mssql_mths[$themth];
if ($themth <= 0) return false;
// h-m-s-MM-DD-YY
return mktime(0,0,0,$themth,$theday,$rr[3]);
}
static function UnixTimeStamp($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
if ($ADODB_mssql_date_order == 'dmy') {
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[1];
$themth = substr(strtoupper($rr[2]),0,3);
} else {
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[2];
$themth = substr(strtoupper($rr[1]),0,3);
}
$themth = $ADODB_mssql_mths[$themth];
if ($themth <= 0) return false;
switch (strtoupper($rr[6])) {
case 'P':
if ($rr[4]<12) $rr[4] += 12;
break;
case 'A':
if ($rr[4]==12) $rr[4] = 0;
break;
default:
break;
}
// h-m-s-MM-DD-YY
return mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
}
}
/*
Code Example 1:
select object_name(constid) as constraint_name,
object_name(fkeyid) as table_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
col_name(rkeyid, rkey) as referenced_column_name
from sysforeignkeys
where object_name(fkeyid) = x
order by constraint_name, table_name, referenced_table_name, keyno
Code Example 2:
select constraint_name,
column_name,
ordinal_position
from information_schema.key_column_usage
where constraint_catalog = db_name()
and table_name = x
order by constraint_name, ordinal_position
http://www.databasejournal.com/scripts/article.php/1440551
*/
-249
View File
@@ -1,249 +0,0 @@
<?php
/// $Id $
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// ADOdb - Database Abstraction Library for PHP //
// http://adodb.sourceforge.net/ //
// //
// Copyright (c) 2000-2014 John Lim (jlim\@natsoft.com.my) //
// All rights reserved. //
// Released under both BSD license and LGPL library license. //
// Whenever there is any discrepancy between the two licenses, //
// the BSD license will take precedence //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 2001-3001 Martin Dougiamas http://dougiamas.com //
// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
/**
* MSSQL Driver with auto-prepended "N" for correct unicode storage
* of SQL literal strings. Intended to be used with MSSQL drivers that
* are sending UCS-2 data to MSSQL (FreeTDS and ODBTP) in order to get
* true cross-db compatibility from the application point of view.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
// one useful constant
if (!defined('SINGLEQUOTE')) define('SINGLEQUOTE', "'");
include_once(ADODB_DIR.'/drivers/adodb-mssql.inc.php');
class ADODB_mssql_n extends ADODB_mssql {
var $databaseType = "mssql_n";
function _query($sql,$inputarr=false)
{
$sql = $this->_appendN($sql);
return ADODB_mssql::_query($sql,$inputarr);
}
/**
* This function will intercept all the literals used in the SQL, prepending the "N" char to them
* in order to allow mssql to store properly data sent in the correct UCS-2 encoding (by freeTDS
* and ODBTP) keeping SQL compatibility at ADOdb level (instead of hacking every project to add
* the "N" notation when working against MSSQL.
*
* The orginal note indicated that this hack should only be used if ALL the char-based columns
* in your DB are of type nchar, nvarchar and ntext, but testing seems to indicate that SQL server
* doesn't seem to care if the statement is used against char etc fields.
*
* @todo This function should raise an ADOdb error if one of the transformations fail
*
* @param mixed $inboundData Either a string containing an SQL statement
* or an array with resources from prepared statements
*
* @return mixed
*/
function _appendN($inboundData) {
$inboundIsArray = false;
if (is_array($inboundData))
{
$inboundIsArray = true;
$inboundArray = $inboundData;
} else
$inboundArray = (array)$inboundData;
/*
* All changes will be placed here
*/
$outboundArray = $inboundArray;
foreach($inboundArray as $inboundKey=>$inboundValue)
{
if (is_resource($inboundValue))
{
/*
* Prepared statement resource
*/
if ($this->debug)
ADOConnection::outp("{$this->databaseType} index $inboundKey value is resource, continue");
continue;
}
if (strpos($inboundValue, SINGLEQUOTE) === false)
{
/*
* Check we have something to manipulate
*/
if ($this->debug)
ADOConnection::outp("{$this->databaseType} index $inboundKey value $inboundValue has no single quotes, continue");
continue;
}
/*
* Check we haven't an odd number of single quotes (this can cause problems below
* and should be considered one wrong SQL). Exit with debug info.
*/
if ((substr_count($inboundValue, SINGLEQUOTE) & 1))
{
if ($this->debug)
ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Wrong number of quotes (odd)");
break;
}
/*
* Check we haven't any backslash + single quote combination. It should mean wrong
* backslashes use (bad magic_quotes_sybase?). Exit with debug info.
*/
$regexp = '/(\\\\' . SINGLEQUOTE . '[^' . SINGLEQUOTE . '])/';
if (preg_match($regexp, $inboundValue))
{
if ($this->debug)
ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Found bad use of backslash + single quote");
break;
}
/*
* Remove pairs of single-quotes
*/
$pairs = array();
$regexp = '/(' . SINGLEQUOTE . SINGLEQUOTE . ')/';
preg_match_all($regexp, $inboundValue, $list_of_pairs);
if ($list_of_pairs)
{
foreach (array_unique($list_of_pairs[0]) as $key=>$value)
$pairs['<@#@#@PAIR-'.$key.'@#@#@>'] = $value;
if (!empty($pairs))
$inboundValue = str_replace($pairs, array_keys($pairs), $inboundValue);
}
/*
* Remove the rest of literals present in the query
*/
$literals = array();
$regexp = '/(N?' . SINGLEQUOTE . '.*?' . SINGLEQUOTE . ')/is';
preg_match_all($regexp, $inboundValue, $list_of_literals);
if ($list_of_literals)
{
foreach (array_unique($list_of_literals[0]) as $key=>$value)
$literals['<#@#@#LITERAL-'.$key.'#@#@#>'] = $value;
if (!empty($literals))
$inboundValue = str_replace($literals, array_keys($literals), $inboundValue);
}
/*
* Analyse literals to prepend the N char to them if their contents aren't numeric
*/
if (!empty($literals))
{
foreach ($literals as $key=>$value) {
if (!is_numeric(trim($value, SINGLEQUOTE)))
/*
* Non numeric string, prepend our dear N, whilst
* Trimming potentially existing previous "N"
*/
$literals[$key] = 'N' . trim($value, 'N');
}
}
/*
* Re-apply literals to the text
*/
if (!empty($literals))
$inboundValue = str_replace(array_keys($literals), $literals, $inboundValue);
/*
* Any pairs followed by N' must be switched to N' followed by those pairs
* (or strings beginning with single quotes will fail)
*/
$inboundValue = preg_replace("/((<@#@#@PAIR-(\d+)@#@#@>)+)N'/", "N'$1", $inboundValue);
/*
* Re-apply pairs of single-quotes to the text
*/
if (!empty($pairs))
$inboundValue = str_replace(array_keys($pairs), $pairs, $inboundValue);
/*
* Print transformation if debug = on
*/
if (strcmp($inboundValue,$inboundArray[$inboundKey]) <> 0 && $this->debug)
ADOConnection::outp("{$this->databaseType} internal transformation: {$inboundArray[$inboundKey]} to {$inboundValue}");
if (strcmp($inboundValue,$inboundArray[$inboundKey]) <> 0)
/*
* Place the transformed value into the outbound array
*/
$outboundArray[$inboundKey] = $inboundValue;
}
/*
* Any transformations are in the $outboundArray
*/
if ($inboundIsArray)
return $outboundArray;
/*
* We passed a string in originally
*/
return $outboundArray[0];
}
}
class ADORecordset_mssql_n extends ADORecordset_mssql {
var $databaseType = "mssql_n";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}
@@ -1,1197 +0,0 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Native mssql driver. Requires mssql client. Works on Windows.
http://www.microsoft.com/sql/technologies/php/default.mspx
To configure for Unix, see
http://phpbuilder.com/columns/alberto20000919.php3
$stream = sqlsrv_get_field($stmt, $index, SQLSRV_SQLTYPE_STREAM(SQLSRV_ENC_BINARY));
stream_filter_append($stream, "convert.iconv.ucs-2/utf-8"); // Voila, UTF-8 can be read directly from $stream
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (!function_exists('sqlsrv_configure')) {
die("mssqlnative extension not installed");
}
if (!function_exists('sqlsrv_set_error_handling')) {
function sqlsrv_set_error_handling($constant) {
sqlsrv_configure("WarningsReturnAsErrors", $constant);
}
}
if (!function_exists('sqlsrv_log_set_severity')) {
function sqlsrv_log_set_severity($constant) {
sqlsrv_configure("LogSeverity", $constant);
}
}
if (!function_exists('sqlsrv_log_set_subsystems')) {
function sqlsrv_log_set_subsystems($constant) {
sqlsrv_configure("LogSubsystems", $constant);
}
}
//----------------------------------------------------------------
// MSSQL returns dates with the format Oct 13 2002 or 13 Oct 2002
// and this causes tons of problems because localized versions of
// MSSQL will return the dates in dmy or mdy order; and also the
// month strings depends on what language has been configured. The
// following two variables allow you to control the localization
// settings - Ugh.
//
// MORE LOCALIZATION INFO
// ----------------------
// To configure datetime, look for and modify sqlcommn.loc,
// typically found in c:\mssql\install
// Also read :
// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
// Alternatively use:
// CONVERT(char(12),datecol,120)
//
// Also if your month is showing as month-1,
// e.g. Jan 13, 2002 is showing as 13/0/2002, then see
// http://phplens.com/lens/lensforum/msgs.php?id=7048&x=1
// it's a localisation problem.
//----------------------------------------------------------------
// has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
if (ADODB_PHPVER >= 0x4300) {
// docs say 4.2.0, but testing shows only since 4.3.0 does it work!
ini_set('mssql.datetimeconvert',0);
} else {
global $ADODB_mssql_mths; // array, months must be upper-case
$ADODB_mssql_date_order = 'mdy';
$ADODB_mssql_mths = array(
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
}
class ADODB_mssqlnative extends ADOConnection {
var $databaseType = "mssqlnative";
var $dataProvider = "mssqlnative";
var $replaceQuote = "''"; // string to use to replace quotes
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d\TH:i:s'";
var $hasInsertID = true;
var $substr = "substring";
var $length = 'len';
var $hasAffectedRows = true;
var $poorAffectedRows = false;
var $metaDatabasesSQL = "select name from sys.sysdatabases where name <> 'master'";
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
var $metaColumnsSQL =
"select c.name,
t.name as type,
c.length,
c.xprec as precision,
c.xscale as scale,
c.isnullable as nullable,
c.cdefault as default_value,
c.xtype,
t.length as type_length,
sc.is_identity
from syscolumns c
join systypes t on t.xusertype=c.xusertype
join sysobjects o on o.id=c.id
join sys.tables st on st.name=o.name
join sys.columns sc on sc.object_id = st.object_id and sc.name=c.name
where o.name='%s'";
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
var $hasGenID = true;
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
var $sysTimeStamp = 'GetDate()';
var $maxParameterLen = 4000;
var $arrayClass = 'ADORecordSet_array_mssqlnative';
var $uniqueSort = true;
var $leftOuter = '*=';
var $rightOuter = '=*';
var $ansiOuter = true; // for mssql7 or later
var $identitySQL = 'select SCOPE_IDENTITY()'; // 'select SCOPE_IDENTITY'; # for mssql 2000
var $uniqueOrderBy = true;
var $_bindInputArray = true;
var $_dropSeqSQL = "drop table %s";
var $connectionInfo = array();
var $cachedSchemaFlush = false;
var $sequences = false;
var $mssql_version = '';
function __construct()
{
if ($this->debug) {
ADOConnection::outp("<pre>");
sqlsrv_set_error_handling( SQLSRV_ERRORS_LOG_ALL );
sqlsrv_log_set_severity( SQLSRV_LOG_SEVERITY_ALL );
sqlsrv_log_set_subsystems(SQLSRV_LOG_SYSTEM_ALL);
sqlsrv_configure('WarningsReturnAsErrors', 0);
} else {
sqlsrv_set_error_handling(0);
sqlsrv_log_set_severity(0);
sqlsrv_log_set_subsystems(SQLSRV_LOG_SYSTEM_ALL);
sqlsrv_configure('WarningsReturnAsErrors', 0);
}
}
/**
* Initializes the SQL Server version.
* Dies if connected to a non-supported version (2000 and older)
*/
function ServerVersion() {
$data = $this->ServerInfo();
preg_match('/^\d{2}/', $data['version'], $matches);
$version = (int)reset($matches);
// We only support SQL Server 2005 and up
if($version < 9) {
die("SQL SERVER VERSION {$data['version']} NOT SUPPORTED IN mssqlnative DRIVER");
}
$this->mssql_version = $version;
}
function ServerInfo() {
global $ADODB_FETCH_MODE;
static $arr = false;
if (is_array($arr))
return $arr;
if ($this->fetchMode === false) {
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
} elseif ($this->fetchMode >=0 && $this->fetchMode <=2) {
$savem = $this->fetchMode;
} else
$savem = $this->SetFetchMode(ADODB_FETCH_NUM);
$arrServerInfo = sqlsrv_server_info($this->_connectionID);
$ADODB_FETCH_MODE = $savem;
$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
$arr['version'] = $arrServerInfo['SQLServerVersion'];//ADOConnection::_findvers($arr['description']);
return $arr;
}
function IfNull( $field, $ifNull )
{
return " ISNULL($field, $ifNull) "; // if MS SQL Server
}
function _insertid()
{
// SCOPE_IDENTITY()
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// they are in the same stored procedure, function, or batch.
return $this->lastInsertID;
}
function _affectedrows()
{
if ($this->_queryID)
return sqlsrv_rows_affected($this->_queryID);
}
function GenID($seq='adodbseq',$start=1) {
if (!$this->mssql_version)
$this->ServerVersion();
switch($this->mssql_version){
case 9:
case 10:
return $this->GenID2008($seq, $start);
break;
default:
return $this->GenID2012($seq, $start);
break;
}
}
function CreateSequence($seq='adodbseq',$start=1)
{
if (!$this->mssql_version)
$this->ServerVersion();
switch($this->mssql_version){
case 9:
case 10:
return $this->CreateSequence2008($seq, $start);
break;
default:
return $this->CreateSequence2012($seq, $start);
break;
}
}
/**
* For Server 2005,2008, duplicate a sequence with an identity table
*/
function CreateSequence2008($seq='adodbseq',$start=1)
{
if($this->debug) ADOConnection::outp("<hr>CreateSequence($seq,$start)");
sqlsrv_begin_transaction($this->_connectionID);
$start -= 1;
$this->Execute("create table $seq (id int)");//was float(53)
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
if (!$ok) {
if($this->debug) ADOConnection::outp("<hr>Error: ROLLBACK");
sqlsrv_rollback($this->_connectionID);
return false;
}
sqlsrv_commit($this->_connectionID);
return true;
}
/**
* Proper Sequences Only available to Server 2012 and up
*/
function CreateSequence2012($seq='adodbseq',$start=1){
if (!$this->sequences){
$sql = "SELECT name FROM sys.sequences";
$this->sequences = $this->GetCol($sql);
}
$ok = $this->Execute("CREATE SEQUENCE $seq START WITH $start INCREMENT BY 1");
if (!$ok)
die("CANNOT CREATE SEQUENCE" . print_r(sqlsrv_errors(),true));
$this->sequences[] = $seq;
}
/**
* For Server 2005,2008, duplicate a sequence with an identity table
*/
function GenID2008($seq='adodbseq',$start=1)
{
if($this->debug) ADOConnection::outp("<hr>CreateSequence($seq,$start)");
sqlsrv_begin_transaction($this->_connectionID);
$ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
if (!$ok) {
$start -= 1;
$this->Execute("create table $seq (id int)");//was float(53)
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
if (!$ok) {
if($this->debug) ADOConnection::outp("<hr>Error: ROLLBACK");
sqlsrv_rollback($this->_connectionID);
return false;
}
}
$num = $this->GetOne("select id from $seq");
sqlsrv_commit($this->_connectionID);
return $num;
}
/**
* Only available to Server 2012 and up
* Cannot do this the normal adodb way by trapping an error if the
* sequence does not exist because sql server will auto create a
* sequence with the starting number of -9223372036854775808
*/
function GenID2012($seq='adodbseq',$start=1)
{
/*
* First time in create an array of sequence names that we
* can use in later requests to see if the sequence exists
* the overhead is creating a list of sequences every time
* we need access to at least 1. If we really care about
* performance, we could maybe flag a 'nocheck' class variable
*/
if (!$this->sequences){
$sql = "SELECT name FROM sys.sequences";
$this->sequences = $this->GetCol($sql);
}
if (!is_array($this->sequences)
|| is_array($this->sequences) && !in_array($seq,$this->sequences)){
$this->CreateSequence2012($seq, $start);
}
$num = $this->GetOne("SELECT NEXT VALUE FOR $seq");
return $num;
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
if (!$col) $col = $this->sysTimeStamp;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '+';
$ch = $fmt[$i];
switch($ch) {
case 'Y':
case 'y':
$s .= "datename(yyyy,$col)";
break;
case 'M':
$s .= "convert(char(3),$col,0)";
break;
case 'm':
$s .= "replace(str(month($col),2),' ','0')";
break;
case 'Q':
case 'q':
$s .= "datename(quarter,$col)";
break;
case 'D':
case 'd':
$s .= "replace(str(day($col),2),' ','0')";
break;
case 'h':
$s .= "substring(convert(char(14),$col,0),13,2)";
break;
case 'H':
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'i':
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
break;
case 's':
$s .= "replace(str(datepart(ss,$col),2),' ','0')";
break;
case 'a':
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
$s .= $this->qstr($ch);
break;
}
}
return $s;
}
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
if ($this->debug) ADOConnection::outp('<hr>begin transaction');
sqlsrv_begin_transaction($this->_connectionID);
return true;
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if ($this->debug) ADOConnection::outp('<hr>commit transaction');
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
sqlsrv_commit($this->_connectionID);
return true;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->debug) ADOConnection::outp('<hr>rollback transaction');
if ($this->transCnt) $this->transCnt -= 1;
sqlsrv_rollback($this->_connectionID);
return true;
}
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
$this->Execute('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
return;
}
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
/*
Usage:
$this->BeginTrans();
$this->RowLock('table1,table2','table1.id=33 and table2.id=table1.id'); # lock row 33 for both tables
# some operation on both tables table1 and table2
$this->CommitTrans();
See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
*/
function RowLock($tables,$where,$col='1 as adodbignore')
{
if ($col == '1 as adodbignore') $col = 'top 1 null as ignore';
if (!$this->transCnt) $this->BeginTrans();
return $this->GetOne("select $col from $tables with (ROWLOCK,HOLDLOCK) where $where");
}
function SelectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {
$rs = $this->Execute('USE '.$dbName);
if($rs) {
return true;
} else return false;
}
else return false;
}
function ErrorMsg()
{
$retErrors = sqlsrv_errors(SQLSRV_ERR_ALL);
if($retErrors != null) {
foreach($retErrors as $arrError) {
$this->_errorMsg .= "SQLState: ".$arrError[ 'SQLSTATE']."\n";
$this->_errorMsg .= "Error Code: ".$arrError[ 'code']."\n";
$this->_errorMsg .= "Message: ".$arrError[ 'message']."\n";
}
} else {
$this->_errorMsg = "No errors found";
}
return $this->_errorMsg;
}
function ErrorNo()
{
$err = sqlsrv_errors(SQLSRV_ERR_ALL);
if($err[0]) return $err[0]['code'];
else return 0;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sqlsrv_connect')) return null;
$connectionInfo = $this->connectionInfo;
$connectionInfo["Database"]=$argDatabasename;
$connectionInfo["UID"]=$argUsername;
$connectionInfo["PWD"]=$argPassword;
foreach ($this->connectionParameters as $parameter=>$value)
$connectionInfo[$parameter] = $value;
if ($this->debug) ADOConnection::outp("<hr>connecting... hostname: $argHostname params: ".var_export($connectionInfo,true));
//if ($this->debug) ADOConnection::outp("<hr>_connectionID before: ".serialize($this->_connectionID));
if(!($this->_connectionID = sqlsrv_connect($argHostname,$connectionInfo))) {
if ($this->debug) ADOConnection::outp( "<hr><b>errors</b>: ".print_r( sqlsrv_errors(), true));
return false;
}
//if ($this->debug) ADOConnection::outp(" _connectionID after: ".serialize($this->_connectionID));
//if ($this->debug) ADOConnection::outp("<hr>defined functions: <pre>".var_export(get_defined_functions(),true)."</pre>");
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
//return null;//not implemented. NOTE: Persistent connections have no effect if PHP is used as a CGI program. (FastCGI!)
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
function Prepare($sql)
{
return $sql; // prepare does not work properly with bind parameters as bind parameters are managed by sqlsrv_prepare!
$stmt = sqlsrv_prepare( $this->_connectionID, $sql);
if (!$stmt) return $sql;
return array($sql,$stmt);
}
// returns concatenated string
// MSSQL requires integers to be cast as strings
// automatically cast every datatype to VARCHAR(255)
// @author David Rogers (introspectshun)
function Concat()
{
$s = "";
$arr = func_get_args();
// Split single record on commas, if possible
if (sizeof($arr) == 1) {
foreach ($arr as $arg) {
$args = explode(',', $arg);
}
$arr = $args;
}
array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
$s = implode('+',$arr);
if (sizeof($arr) > 0) return "$s";
return '';
}
/*
Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
So all your blobs must be of type "image".
Remember to set in php.ini the following...
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 0 ; zero to pass through
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 0 ; zero to pass through
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
if (strtoupper($blobtype) == 'CLOB') {
$sql = "UPDATE $table SET $column='" . $val . "' WHERE $where";
return $this->Execute($sql) != false;
}
$sql = "UPDATE $table SET $column=0x".bin2hex($val)." WHERE $where";
return $this->Execute($sql) != false;
}
// returns query ID if successful, otherwise false
function _query($sql,$inputarr=false)
{
$this->_errorMsg = false;
if (is_array($sql)) $sql = $sql[1];
$insert = false;
// handle native driver flaw for retrieving the last insert ID
if(preg_match('/^\W*insert[\s\w()",.]+values\s*\((?:[^;\']|\'\'|(?:(?:\'\')*\'[^\']+\'(?:\'\')*))*;?$/i', $sql)) {
$insert = true;
$sql .= '; '.$this->identitySQL; // select scope_identity()
}
if($inputarr) {
$rez = sqlsrv_query($this->_connectionID, $sql, $inputarr);
} else {
$rez = sqlsrv_query($this->_connectionID,$sql);
}
if ($this->debug) ADOConnection::outp("<hr>running query: ".var_export($sql,true)."<hr>input array: ".var_export($inputarr,true)."<hr>result: ".var_export($rez,true));
if(!$rez) {
$rez = false;
} else if ($insert) {
// retrieve the last insert ID (where applicable)
while ( sqlsrv_next_result($rez) ) {
sqlsrv_fetch($rez);
$this->lastInsertID = sqlsrv_get_field($rez, 0);
}
}
return $rez;
}
// returns true or false
function _close()
{
if ($this->transCnt) $this->RollbackTrans();
$rez = @sqlsrv_close($this->_connectionID);
$this->_connectionID = false;
return $rez;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssqlnative::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssqlnative::UnixTimeStamp($v);
}
function MetaIndexes($table,$primary=false, $owner = false)
{
$table = $this->qstr($table);
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
ORDER BY O.name, I.Name, K.keyno";
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute($sql);
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return FALSE;
}
$indexes = array();
while ($row = $rs->FetchRow()) {
if (!$primary && $row[5]) continue;
$indexes[$row[0]]['unique'] = $row[6];
$indexes[$row[0]]['columns'][] = $row[1];
}
return $indexes;
}
function MetaForeignKeys($table, $owner=false, $upper=false)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$table = $this->qstr(strtoupper($table));
$sql =
"select object_name(constid) as constraint_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
col_name(rkeyid, rkey) as referenced_column_name
from sysforeignkeys
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
$constraints =& $this->GetArray($sql);
$ADODB_FETCH_MODE = $save;
$arr = false;
foreach($constraints as $constr) {
//print_r($constr);
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
}
if (!$arr) return false;
$arr2 = false;
foreach($arr as $k => $v) {
foreach($v as $a => $b) {
if ($upper) $a = strtoupper($a);
$arr2[$a] = $b;
}
}
return $arr2;
}
//From: Fernando Moreira <FMoreira@imediata.pt>
function MetaDatabases()
{
$this->SelectDB("master");
$rs =& $this->Execute($this->metaDatabasesSQL);
$rows = $rs->GetRows();
$ret = array();
for($i=0;$i<count($rows);$i++) {
$ret[] = $rows[$i][0];
}
$this->SelectDB($this->database);
if($ret)
return $ret;
else
return false;
}
// "Stein-Aksel Basma" <basma@accelero.no>
// tested with MSSQL 2000
function MetaPrimaryKeys($table, $owner=false)
{
global $ADODB_FETCH_MODE;
$schema = '';
$this->_findschema($table,$schema);
if (!$schema) $schema = $this->database;
if ($schema) $schema = "and k.table_catalog like '$schema%'";
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
information_schema.table_constraints tc
where tc.constraint_name = k.constraint_name and tc.constraint_type =
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$a = $this->GetCol($sql);
$ADODB_FETCH_MODE = $savem;
if ($a && sizeof($a)>0) return $a;
$false = false;
return $false;
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(($mask));
$this->metaTablesSQL .= " AND name like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
function MetaColumns($table, $upper=true, $schema=false){
# start adg
static $cached_columns = array();
if ($this->cachedSchemaFlush)
$cached_columns = array();
if (array_key_exists($table,$cached_columns)){
return $cached_columns[$table];
}
# end adg
if (!$this->mssql_version)
$this->ServerVersion();
$this->_findschema($table,$schema);
if ($schema) {
$dbName = $this->database;
$this->SelectDB($schema);
}
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($schema) {
$this->SelectDB($dbName);
}
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
$false = false;
return $false;
}
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
if (array_key_exists(0,$rs->fields)) {
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
$fld->precision = $rs->fields[3];
$fld->scale = $rs->fields[4];
$fld->not_null =!$rs->fields[5];
$fld->has_default = $rs->fields[6];
$fld->xtype = $rs->fields[7];
$fld->type_length = $rs->fields[8];
$fld->auto_increment= $rs->fields[9];
} else {
$fld->name = $rs->fields['name'];
$fld->type = $rs->fields['type'];
$fld->max_length = $rs->fields['length'];
$fld->precision = $rs->fields['precision'];
$fld->scale = $rs->fields['scale'];
$fld->not_null =!$rs->fields['nullable'];
$fld->has_default = $rs->fields['default_value'];
$fld->xtype = $rs->fields['xtype'];
$fld->type_length = $rs->fields['type_length'];
$fld->auto_increment= $rs->fields['is_identity'];
}
if ($save == ADODB_FETCH_NUM)
$retarr[] = $fld;
else
$retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
# start adg
$cached_columns[$table] = $retarr;
# end adg
return $retarr;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_mssqlnative extends ADORecordSet {
var $databaseType = "mssqlnative";
var $canSeek = false;
var $fieldOffset = 0;
// _mths works only in non-localised system
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id,$mode);
}
function _initrs()
{
global $ADODB_COUNTRECS;
# KMN # if ($this->connection->debug) ADOConnection::outp("(before) ADODB_COUNTRECS: {$ADODB_COUNTRECS} _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
/*$retRowsAff = sqlsrv_rows_affected($this->_queryID);//"If you need to determine the number of rows a query will return before retrieving the actual results, appending a SELECT COUNT ... query would let you get that information, and then a call to next_result would move you to the "real" results."
ADOConnection::outp("rowsaff: ".serialize($retRowsAff));
$this->_numOfRows = ($ADODB_COUNTRECS)? $retRowsAff:-1;*/
$this->_numOfRows = -1;//not supported
$fieldmeta = sqlsrv_field_metadata($this->_queryID);
$this->_numOfFields = ($fieldmeta)? count($fieldmeta):-1;
# KMN # if ($this->connection->debug) ADOConnection::outp("(after) _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
/*
* Copy the oracle method and cache the metadata at init time
*/
if ($this->_numOfFields>0) {
$this->_fieldobjs = array();
$max = $this->_numOfFields;
for ($i=0;$i<$max; $i++) $this->_fieldobjs[] = $this->_FetchField($i);
}
}
//Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
// get next resultset - requires PHP 4.0.5 or later
function NextRecordSet()
{
if (!sqlsrv_next_result($this->_queryID)) return false;
$this->_inited = false;
$this->bind = false;
$this->_currentRow = -1;
$this->Init();
return true;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode != ADODB_FETCH_NUM) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved.
Designed By jcortinap#jc.com.mx
*/
function _FetchField($fieldOffset = -1)
{
$_typeConversion = array(
-155 => 'datetimeoffset',
-154 => 'time',
-152 => 'xml',
-151 => 'udt',
-11 => 'uniqueidentifier',
-10 => 'ntext',
-9 => 'nvarchar',
-8 => 'nchar',
-7 => 'bit',
-6 => 'tinyint',
-5 => 'bigint',
-4 => 'image',
-3 => 'varbinary',
-2 => 'timestamp',
-1 => 'text',
1 => 'char',
2 => 'numeric',
3 => 'decimal',
4 => 'int',
5 => 'smallint',
6 => 'float',
7 => 'real',
12 => 'varchar',
91 => 'date',
93 => 'datetime'
);
$fa = @sqlsrv_field_metadata($this->_queryID);
if ($fieldOffset != -1) {
$fa = $fa[$fieldOffset];
}
$false = false;
if (empty($fa)) {
$f = false;//PHP Notice: Only variable references should be returned by reference
}
else
{
// Convert to an object
$fa = array_change_key_case($fa, CASE_LOWER);
$fb = array();
if ($fieldOffset != -1)
{
$fb = array(
'name' => $fa['name'],
'max_length' => $fa['size'],
'column_source' => $fa['name'],
'type' => $_typeConversion[$fa['type']]
);
}
else
{
foreach ($fa as $key => $value)
{
$fb[] = array(
'name' => $value['name'],
'max_length' => $value['size'],
'column_source' => $value['name'],
'type' => $_typeConversion[$value['type']]
);
}
}
$f = (object) $fb;
}
return $f;
}
/*
* Fetchfield copies the oracle method, it loads the field information
* into the _fieldobjs array once, to save multiple calls to the
* sqlsrv_field_metadata function
*
* @author KM Newnham
* @date 02/20/2013
*/
function FetchField($fieldOffset = -1)
{
return $this->_fieldobjs[$fieldOffset];
}
function _seek($row)
{
return false;//There is no support for cursors in the driver at this time. All data is returned via forward-only streams.
}
// speedup
function MoveNext()
{
//# KMN # if ($this->connection->debug) ADOConnection::outp("movenext()");
//# KMN # if ($this->connection->debug) ADOConnection::outp("eof (beginning): ".$this->EOF);
if ($this->EOF) return false;
$this->_currentRow++;
// # KMN # if ($this->connection->debug) ADOConnection::outp("_currentRow: ".$this->_currentRow);
if ($this->_fetch()) return true;
$this->EOF = true;
//# KMN # if ($this->connection->debug) ADOConnection::outp("eof (end): ".$this->EOF);
return false;
}
// INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
// also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
function _fetch($ignore_fields=false)
{
# KMN # if ($this->connection->debug) ADOConnection::outp("_fetch()");
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
if ($this->fetchMode & ADODB_FETCH_NUM) {
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: both");
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_BOTH);
} else {
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: assoc");
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_ASSOC);
}
if (is_array($this->fields)) {
if (ADODB_ASSOC_CASE == 0) {
foreach($this->fields as $k=>$v) {
$this->fields[strtolower($k)] = $v;
}
} else if (ADODB_ASSOC_CASE == 1) {
foreach($this->fields as $k=>$v) {
$this->fields[strtoupper($k)] = $v;
}
}
}
} else {
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: num");
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_NUMERIC);
}
if(is_array($this->fields) && array_key_exists(1,$this->fields) && !array_key_exists(0,$this->fields)) {//fix fetch numeric keys since they're not 0 based
$arrFixed = array();
foreach($this->fields as $key=>$value) {
if(is_numeric($key)) {
$arrFixed[$key-1] = $value;
} else {
$arrFixed[$key] = $value;
}
}
//if($this->connection->debug) ADOConnection::outp("<hr>fixing non 0 based return array, old: ".print_r($this->fields,true)." new: ".print_r($arrFixed,true));
$this->fields = $arrFixed;
}
if(is_array($this->fields)) {
foreach($this->fields as $key=>$value) {
if (is_object($value) && method_exists($value, 'format')) {//is DateTime object
$this->fields[$key] = $value->format("Y-m-d\TH:i:s\Z");
}
}
}
if($this->fields === null) $this->fields = false;
# KMN # if ($this->connection->debug) ADOConnection::outp("<hr>after _fetch, fields: <pre>".print_r($this->fields,true)." backtrace: ".adodb_backtrace(false));
return $this->fields;
}
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close()
{
if(is_object($this->_queryID)) {
$rez = sqlsrv_free_stmt($this->_queryID);
$this->_queryID = false;
return $rez;
}
return true;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssqlnative::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssqlnative::UnixTimeStamp($v);
}
}
class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
function __construct($id=-1,$mode=false)
{
parent::__construct($id,$mode);
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
if ($ADODB_mssql_date_order == 'dmy') {
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
return parent::UnixDate($v);
}
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[1];
$themth = substr(strtoupper($rr[2]),0,3);
} else {
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
return parent::UnixDate($v);
}
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[2];
$themth = substr(strtoupper($rr[1]),0,3);
}
$themth = $ADODB_mssql_mths[$themth];
if ($themth <= 0) return false;
// h-m-s-MM-DD-YY
return adodb_mktime(0,0,0,$themth,$theday,$rr[3]);
}
static function UnixTimeStamp($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
if ($ADODB_mssql_date_order == 'dmy') {
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[1];
$themth = substr(strtoupper($rr[2]),0,3);
} else {
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[2];
$themth = substr(strtoupper($rr[1]),0,3);
}
$themth = $ADODB_mssql_mths[$themth];
if ($themth <= 0) return false;
switch (strtoupper($rr[6])) {
case 'P':
if ($rr[4]<12) $rr[4] += 12;
break;
case 'A':
if ($rr[4]==12) $rr[4] = 0;
break;
default:
break;
}
// h-m-s-MM-DD-YY
return adodb_mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
}
}
/*
Code Example 1:
select object_name(constid) as constraint_name,
object_name(fkeyid) as table_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
col_name(rkeyid, rkey) as referenced_column_name
from sysforeignkeys
where object_name(fkeyid) = x
order by constraint_name, table_name, referenced_table_name, keyno
Code Example 2:
select constraint_name,
column_name,
ordinal_position
from information_schema.key_column_usage
where constraint_catalog = db_name()
and table_name = x
order by constraint_name, ordinal_position
http://www.databasejournal.com/scripts/article.php/1440551
*/
@@ -1,58 +0,0 @@
<?php
/**
* @version v5.20.9 21-Dec-2016
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://php.weblogs.com
*
* Portable MSSQL Driver that supports || instead of +
*
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
/*
The big difference between mssqlpo and it's parent mssql is that mssqlpo supports
the more standard || string concatenation operator.
*/
include_once(ADODB_DIR.'/drivers/adodb-mssql.inc.php');
class ADODB_mssqlpo extends ADODB_mssql {
var $databaseType = "mssqlpo";
var $concat_operator = '||';
function PrepareSP($sql, $param = true)
{
if (!$this->_has_mssql_init) {
ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
return $sql;
}
if (is_string($sql)) $sql = str_replace('||','+',$sql);
$stmt = mssql_init($sql,$this->_connectionID);
if (!$stmt) return $sql;
return array($sql,$stmt);
}
function _query($sql,$inputarr=false)
{
if (is_string($sql)) $sql = str_replace('||','+',$sql);
return ADODB_mssql::_query($sql,$inputarr);
}
}
class ADORecordset_mssqlpo extends ADORecordset_mssql {
var $databaseType = "mssqlpo";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}

Some files were not shown because too many files have changed in this diff Show More