github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/cmd/query_gen/tables.go (about) 1 package main 2 3 import qgen "github.com/Azareal/Gosora/query_gen" 4 5 var mysqlPre = "utf8mb4" 6 var mysqlCol = "utf8mb4_general_ci" 7 8 var tables []string 9 10 type tblColumn = qgen.DBTableColumn 11 type tC = tblColumn 12 type tblKey = qgen.DBTableKey 13 14 func createTables(a qgen.Adapter) error { 15 tables = nil 16 f := func(table, charset, collation string, cols []tC, keys []tblKey) error { 17 tables = append(tables, table) 18 return qgen.Install.CreateTable(table, charset, collation, cols, keys) 19 } 20 return createTables2(a, f) 21 } 22 23 func createTables2(a qgen.Adapter, f func(table, charset, collation string, columns []tC, keys []tblKey) error) (err error) { 24 createTable := func(table, charset, collation string, cols []tC, keys []tblKey) { 25 if err != nil { 26 return 27 } 28 err = f(table, charset, collation, cols, keys) 29 } 30 bcol := func(col string, val bool) qgen.DBTableColumn { 31 if val { 32 return tC{col, "boolean", 0, false, false, "1"} 33 } 34 return tC{col, "boolean", 0, false, false, "0"} 35 } 36 ccol := func(col string, size int, sdefault string) qgen.DBTableColumn { 37 return tC{col, "varchar", size, false, false, sdefault} 38 } 39 text := func(params ...string) qgen.DBTableColumn { 40 if len(params) == 0 { 41 return tC{"", "text", 0, false, false, ""} 42 } 43 col, sdefault := params[0], "" 44 if len(params) > 1 { 45 sdefault = params[1] 46 if sdefault == "" { 47 sdefault = "''" 48 } 49 } 50 return tC{col, "text", 0, false, false, sdefault} 51 } 52 createdAt := func(coll ...string) qgen.DBTableColumn { 53 var col string 54 if len(coll) > 0 { 55 col = coll[0] 56 } 57 if col == "" { 58 col = "createdAt" 59 } 60 return tC{col, "createdAt", 0, false, false, ""} 61 } 62 63 createTable("users", mysqlPre, mysqlCol, 64 []tC{ 65 {"uid", "int", 0, false, true, ""}, 66 ccol("name", 100, ""), 67 ccol("password", 100, ""), 68 69 ccol("salt", 80, "''"), 70 {"group", "int", 0, false, false, ""}, // TODO: Make this a foreign key 71 bcol("active", false), 72 bcol("is_super_admin", false), 73 createdAt(), 74 {"lastActiveAt", "datetime", 0, false, false, ""}, 75 ccol("session", 200, "''"), 76 //ccol("authToken", 200, "''"), 77 ccol("last_ip", 200, "''"), 78 {"profile_comments", "int", 0, false, false, "0"}, 79 {"who_can_convo", "int", 0, false, false, "0"}, 80 {"enable_embeds", "int", 0, false, false, "-1"}, 81 ccol("email", 200, "''"), 82 ccol("avatar", 100, "''"), 83 text("message"), 84 85 // TODO: Drop these columns? 86 ccol("url_prefix", 20, "''"), 87 ccol("url_name", 100, "''"), 88 //text("pub_key"), 89 90 {"level", "smallint", 0, false, false, "0"}, 91 {"score", "int", 0, false, false, "0"}, 92 {"posts", "int", 0, false, false, "0"}, 93 {"bigposts", "int", 0, false, false, "0"}, 94 {"megaposts", "int", 0, false, false, "0"}, 95 {"topics", "int", 0, false, false, "0"}, 96 {"liked", "int", 0, false, false, "0"}, 97 98 // These two are to bound liked queries with little bits of information we know about the user to reduce the server load 99 {"oldestItemLikedCreatedAt", "datetime", 0, false, false, ""}, // For internal use only, semantics may change 100 {"lastLiked", "datetime", 0, false, false, ""}, // For internal use only, semantics may change 101 102 //{"penalty_count","int",0,false,false,"0"}, 103 {"temp_group", "int", 0, false, false, "0"}, // For temporary groups, set this to zero when a temporary group isn't in effect 104 }, 105 []tK{ 106 {"uid", "primary", "", false}, 107 {"name", "unique", "", false}, 108 }, 109 ) 110 111 createTable("users_groups", mysqlPre, mysqlCol, 112 []tC{ 113 {"gid", "int", 0, false, true, ""}, 114 ccol("name", 100, ""), 115 text("permissions"), 116 text("plugin_perms"), 117 bcol("is_mod", false), 118 bcol("is_admin", false), 119 bcol("is_banned", false), 120 {"user_count", "int", 0, false, false, "0"}, // TODO: Implement this 121 122 ccol("tag", 50, "''"), 123 }, 124 []tK{ 125 {"gid", "primary", "", false}, 126 }, 127 ) 128 129 createTable("users_groups_promotions", mysqlPre, mysqlCol, 130 []tC{ 131 {"pid", "int", 0, false, true, ""}, 132 {"from_gid", "int", 0, false, false, ""}, 133 {"to_gid", "int", 0, false, false, ""}, 134 bcol("two_way", false), // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set 135 136 // Requirements 137 {"level", "int", 0, false, false, ""}, 138 {"posts", "int", 0, false, false, "0"}, 139 {"minTime", "int", 0, false, false, ""}, // How long someone needs to have been in their current group before being promoted 140 {"registeredFor", "int", 0, false, false, "0"}, // minutes 141 }, 142 []tK{ 143 {"pid", "primary", "", false}, 144 }, 145 ) 146 147 /* 148 createTable("users_groups_promotions_scheduled","","", 149 []tC{ 150 {"prid","int",0,false,false,""}, 151 {"uid","int",0,false,false,""}, 152 {"runAt","datetime",0,false,false,""}, 153 }, 154 []tK{ 155 // TODO: Test to see that the compound primary key works 156 {"prid,uid", "primary", "", false}, 157 }, 158 ) 159 */ 160 161 createTable("users_2fa_keys", mysqlPre, mysqlCol, 162 []tC{ 163 {"uid", "int", 0, false, false, ""}, 164 ccol("secret", 100, ""), 165 ccol("scratch1", 50, ""), 166 ccol("scratch2", 50, ""), 167 ccol("scratch3", 50, ""), 168 ccol("scratch4", 50, ""), 169 ccol("scratch5", 50, ""), 170 ccol("scratch6", 50, ""), 171 ccol("scratch7", 50, ""), 172 ccol("scratch8", 50, ""), 173 {"createdAt", "createdAt", 0, false, false, ""}, 174 }, 175 []tK{ 176 {"uid", "primary", "", false}, 177 }, 178 ) 179 180 // What should we do about global penalties? Put them on the users table for speed? Or keep them here? 181 // Should we add IP Penalties? No, that's a stupid idea, just implement IP Bans properly. What about shadowbans? 182 // TODO: Perm overrides 183 // TODO: Add a mod-queue and other basic auto-mod features. This is needed for awaiting activation and the mod_queue penalty flag 184 // TODO: Add a penalty type where a user is stopped from creating plugin_guilds social groups 185 // TODO: Shadow bans. We will probably have a CanShadowBan permission for this, as we *really* don't want people using this lightly. 186 /*createTable("users_penalties","","", 187 []tC{ 188 {"uid","int",0,false,false,""}, 189 {"element_id","int",0,false,false,""}, 190 ccol("element_type",50,""), //forum, profile?, and social_group. Leave blank for global. 191 text("overrides","{}"), 192 193 bcol("mod_queue",false), 194 bcol("shadow_ban",false), 195 bcol("no_avatar",false), // Coming Soon. Should this be a perm override instead? 196 197 // Do we *really* need rate-limit penalty types? Are we going to be allowing bots or something? 198 //{"posts_per_hour","int",0,false,false,"0"}, 199 //{"topics_per_hour","int",0,false,false,"0"}, 200 //{"posts_count","int",0,false,false,"0"}, 201 //{"topic_count","int",0,false,false,"0"}, 202 //{"last_hour","int",0,false,false,"0"}, // UNIX Time, as we don't need to do anything too fancy here. When an hour has elapsed since that time, reset the hourly penalty counters. 203 204 {"issued_by","int",0,false,false,""}, 205 createdAt("issued_at"), 206 {"expires_at","datetime",0,false,false,""}, 207 }, nil, 208 )*/ 209 210 createTable("users_groups_scheduler", "", "", 211 []tC{ 212 {"uid", "int", 0, false, false, ""}, 213 {"set_group", "int", 0, false, false, ""}, 214 215 {"issued_by", "int", 0, false, false, ""}, 216 createdAt("issued_at"), 217 {"revert_at", "datetime", 0, false, false, ""}, 218 {"temporary", "boolean", 0, false, false, ""}, // special case for permanent bans to do the necessary bookkeeping, might be removed in the future 219 }, 220 []tK{ 221 {"uid", "primary", "", false}, 222 }, 223 ) 224 225 // TODO: Can we use a piece of software dedicated to persistent queues for this rather than relying on the database for it? 226 createTable("users_avatar_queue", "", "", 227 []tC{ 228 {"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key 229 }, 230 []tK{ 231 {"uid", "primary", "", false}, 232 }, 233 ) 234 235 // TODO: Should we add a users prefix to this table to fit the "unofficial convention"? 236 // TODO: Add an autoincrement key? 237 createTable("emails", "", "", 238 []tC{ 239 ccol("email", 200, ""), 240 {"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key 241 bcol("validated", false), 242 ccol("token", 200, "''"), 243 }, nil, 244 ) 245 246 // TODO: Allow for patterns in domains, if the bots try to shake things up there? 247 /* 248 createTable("email_domain_blacklist", "", "", 249 []tC{ 250 ccol("domain", 200, ""), 251 bcol("gtld", false), 252 }, 253 []tK{ 254 {"domain", "primary"}, 255 }, 256 ) 257 */ 258 259 // TODO: Implement password resets 260 createTable("password_resets", "", "", 261 []tC{ 262 ccol("email", 200, ""), 263 {"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key 264 ccol("validated", 200, ""), // Token given once the one-use token is consumed, used to prevent multiple people consuming the same one-use token 265 ccol("token", 200, ""), 266 createdAt(), 267 }, nil, 268 ) 269 270 createTable("forums", mysqlPre, mysqlCol, 271 []tC{ 272 {"fid", "int", 0, false, true, ""}, 273 ccol("name", 100, ""), 274 ccol("desc", 200, ""), 275 ccol("tmpl", 200, "''"), 276 bcol("active", true), 277 {"order", "int", 0, false, false, "0"}, 278 {"topicCount", "int", 0, false, false, "0"}, 279 ccol("preset", 100, "''"), 280 {"parentID", "int", 0, false, false, "0"}, 281 ccol("parentType", 50, "''"), 282 {"lastTopicID", "int", 0, false, false, "0"}, 283 {"lastReplyerID", "int", 0, false, false, "0"}, 284 }, 285 []tK{ 286 {"fid", "primary", "", false}, 287 }, 288 ) 289 290 createTable("forums_permissions", "", "", 291 []tC{ 292 {"fid", "int", 0, false, false, ""}, 293 {"gid", "int", 0, false, false, ""}, 294 ccol("preset", 100, "''"), 295 text("permissions", "{}"), 296 }, 297 []tK{ 298 // TODO: Test to see that the compound primary key works 299 {"fid,gid", "primary", "", false}, 300 }, 301 ) 302 303 createTable("topics", mysqlPre, mysqlCol, 304 []tC{ 305 {"tid", "int", 0, false, true, ""}, 306 ccol("title", 100, ""), // TODO: Increase the max length to 200? 307 text("content"), 308 text("parsed_content"), 309 createdAt(), 310 {"lastReplyAt", "datetime", 0, false, false, ""}, 311 {"lastReplyBy", "int", 0, false, false, ""}, 312 {"lastReplyID", "int", 0, false, false, "0"}, 313 {"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key 314 bcol("is_closed", false), 315 bcol("sticky", false), 316 // TODO: Add an index for this 317 {"parentID", "int", 0, false, false, "2"}, 318 ccol("ip", 200, "''"), 319 {"postCount", "int", 0, false, false, "1"}, 320 {"likeCount", "int", 0, false, false, "0"}, 321 {"attachCount", "int", 0, false, false, "0"}, 322 {"words", "int", 0, false, false, "0"}, 323 {"views", "int", 0, false, false, "0"}, 324 //{"dayViews", "int", 0, false, false, "0"}, 325 {"weekEvenViews", "int", 0, false, false, "0"}, 326 {"weekOddViews", "int", 0, false, false, "0"}, 327 ///{"weekViews", "int", 0, false, false, "0"}, 328 ///{"lastWeekViews", "int", 0, false, false, "0"}, 329 //{"monthViews", "int", 0, false, false, "0"}, 330 // ? - A little hacky, maybe we could do something less likely to bite us with huge numbers of topics? 331 // TODO: Add an index for this? 332 //{"lastMonth", "datetime", 0, false, false, ""}, 333 ccol("css_class", 100, "''"), 334 {"poll", "int", 0, false, false, "0"}, 335 ccol("data", 200, "''"), 336 }, 337 []tK{ 338 {"tid", "primary", "", false}, 339 {"title", "fulltext", "", false}, 340 {"content", "fulltext", "", false}, 341 }, 342 ) 343 344 createTable("replies", mysqlPre, mysqlCol, 345 []tC{ 346 {"rid", "int", 0, false, true, ""}, // TODO: Rename to replyID? 347 {"tid", "int", 0, false, false, ""}, // TODO: Rename to topicID? 348 text("content"), 349 text("parsed_content"), 350 createdAt(), 351 {"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key 352 {"lastEdit", "int", 0, false, false, "0"}, 353 {"lastEditBy", "int", 0, false, false, "0"}, 354 {"lastUpdated", "datetime", 0, false, false, ""}, 355 ccol("ip", 200, "''"), 356 {"likeCount", "int", 0, false, false, "0"}, 357 {"attachCount", "int", 0, false, false, "0"}, 358 {"words", "int", 0, false, false, "1"}, // ? - replies has a default of 1 and topics has 0? why? 359 ccol("actionType", 20, "''"), 360 {"poll", "int", 0, false, false, "0"}, 361 }, 362 []tK{ 363 {"rid", "primary", "", false}, 364 {"content", "fulltext", "", false}, 365 }, 366 ) 367 368 createTable("attachments", mysqlPre, mysqlCol, 369 []tC{ 370 {"attachID", "int", 0, false, true, ""}, 371 {"sectionID", "int", 0, false, false, "0"}, 372 ccol("sectionTable", 200, "forums"), 373 {"originID", "int", 0, false, false, ""}, 374 ccol("originTable", 200, "replies"), 375 {"uploadedBy", "int", 0, false, false, ""}, // TODO; Make this a foreign key 376 ccol("path", 200, ""), 377 ccol("extra", 200, ""), 378 }, 379 []tK{ 380 {"attachID", "primary", "", false}, 381 }, 382 ) 383 384 createTable("revisions", mysqlPre, mysqlCol, 385 []tC{ 386 {"reviseID", "int", 0, false, true, ""}, 387 text("content"), 388 {"contentID", "int", 0, false, false, ""}, 389 ccol("contentType", 100, "replies"), 390 createdAt(), 391 // TODO: Add a createdBy column? 392 }, 393 []tK{ 394 {"reviseID", "primary", "", false}, 395 }, 396 ) 397 398 createTable("polls", mysqlPre, mysqlCol, 399 []tC{ 400 {"pollID", "int", 0, false, true, ""}, 401 {"parentID", "int", 0, false, false, "0"}, 402 ccol("parentTable", 100, "topics"), // topics, replies 403 {"type", "int", 0, false, false, "0"}, 404 {"options", "json", 0, false, false, ""}, 405 {"votes", "int", 0, false, false, "0"}, 406 }, 407 []tK{ 408 {"pollID", "primary", "", false}, 409 }, 410 ) 411 412 createTable("polls_options", "", "", 413 []tC{ 414 {"pollID", "int", 0, false, false, ""}, 415 {"option", "int", 0, false, false, "0"}, 416 {"votes", "int", 0, false, false, "0"}, 417 }, nil, 418 ) 419 420 createTable("polls_votes", mysqlPre, mysqlCol, 421 []tC{ 422 {"pollID", "int", 0, false, false, ""}, 423 {"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key 424 {"option", "int", 0, false, false, "0"}, 425 createdAt("castAt"), 426 ccol("ip", 200, "''"), 427 }, nil, 428 ) 429 430 createTable("users_replies", mysqlPre, mysqlCol, 431 []tC{ 432 {"rid", "int", 0, false, true, ""}, 433 {"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key 434 text("content"), 435 text("parsed_content"), 436 createdAt(), 437 {"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key 438 {"lastEdit", "int", 0, false, false, "0"}, 439 {"lastEditBy", "int", 0, false, false, "0"}, 440 ccol("ip", 200, "''"), 441 }, 442 []tK{ 443 {"rid", "primary", "", false}, 444 }, 445 ) 446 447 createTable("likes", "", "", 448 []tC{ 449 {"weight", "tinyint", 0, false, false, "1"}, 450 {"targetItem", "int", 0, false, false, ""}, 451 ccol("targetType", 50, "replies"), 452 {"sentBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key 453 createdAt(), 454 {"recalc", "tinyint", 0, false, false, "0"}, 455 }, nil, 456 ) 457 458 //columns("participants,createdBy,createdAt,lastReplyBy,lastReplyAt").Where("cid=?") 459 createTable("conversations", "", "", 460 []tC{ 461 {"cid", "int", 0, false, true, ""}, 462 {"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key 463 createdAt(), 464 {"lastReplyAt", "datetime", 0, false, false, ""}, 465 {"lastReplyBy", "int", 0, false, false, ""}, 466 }, 467 []tK{ 468 {"cid", "primary", "", false}, 469 }, 470 ) 471 472 createTable("conversations_posts", "", "", 473 []tC{ 474 {"pid", "int", 0, false, true, ""}, 475 {"cid", "int", 0, false, false, ""}, 476 {"createdBy", "int", 0, false, false, ""}, 477 ccol("body", 50, ""), 478 ccol("post", 50, "''"), 479 }, 480 []tK{ 481 {"pid", "primary", "", false}, 482 }, 483 ) 484 485 createTable("conversations_participants", "", "", 486 []tC{ 487 {"uid", "int", 0, false, false, ""}, 488 {"cid", "int", 0, false, false, ""}, 489 }, nil, 490 ) 491 492 /* 493 createTable("users_friends", "", "", 494 []tC{ 495 {"uid", "int", 0, false, false, ""}, 496 {"uid2", "int", 0, false, false, ""}, 497 }, nil, 498 ) 499 createTable("users_friends_invites", "", "", 500 []tC{ 501 {"requester", "int", 0, false, false, ""}, 502 {"target", "int", 0, false, false, ""}, 503 }, nil, 504 ) 505 */ 506 507 createTable("users_blocks", "", "", 508 []tC{ 509 {"blocker", "int", 0, false, false, ""}, 510 {"blockedUser", "int", 0, false, false, ""}, 511 }, nil, 512 ) 513 514 createTable("activity_stream_matches", "", "", 515 []tC{ 516 {"watcher", "int", 0, false, false, ""}, // TODO: Make this a foreign key 517 {"asid", "int", 0, false, false, ""}, // TODO: Make this a foreign key 518 }, 519 []tK{ 520 {"asid,asid", "foreign", "activity_stream", true}, 521 }, 522 ) 523 524 createTable("activity_stream", "", "", 525 []tC{ 526 {"asid", "int", 0, false, true, ""}, 527 {"actor", "int", 0, false, false, ""}, /* the one doing the act */ // TODO: Make this a foreign key 528 {"targetUser", "int", 0, false, false, ""}, /* the user who created the item the actor is acting on, some items like forums may lack a targetUser field */ 529 ccol("event", 50, ""), /* mention, like, reply (as in the act of replying to an item, not the reply item type, you can "reply" to a forum by making a topic in it), friend_invite */ 530 ccol("elementType", 50, ""), /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */ 531 532 // replacement for elementType 533 tC{"elementTable", "int", 0, false, false, "0"}, 534 535 {"elementID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */ 536 createdAt(), 537 ccol("extra", 200, "''"), 538 }, 539 []tK{ 540 {"asid", "primary", "", false}, 541 }, 542 ) 543 544 createTable("activity_subscriptions", "", "", 545 []tC{ 546 {"user", "int", 0, false, false, ""}, // TODO: Make this a foreign key 547 {"targetID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */ 548 ccol("targetType", 50, ""), /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */ 549 {"level", "int", 0, false, false, "0"}, /* 0: Mentions (aka the global default for any post), 1: Replies To You, 2: All Replies*/ 550 }, nil, 551 ) 552 553 /* Due to MySQL's design, we have to drop the unique keys for table settings, plugins, and themes down from 200 to 180 or it will error */ 554 createTable("settings", "", "", 555 []tC{ 556 ccol("name", 180, ""), 557 ccol("content", 250, ""), 558 ccol("type", 50, ""), 559 ccol("constraints", 200, "''"), 560 }, 561 []tK{ 562 {"name", "unique", "", false}, 563 }, 564 ) 565 566 createTable("word_filters", "", "", 567 []tC{ 568 {"wfid", "int", 0, false, true, ""}, 569 ccol("find", 200, ""), 570 ccol("replacement", 200, ""), 571 }, 572 []tK{ 573 {"wfid", "primary", "", false}, 574 }, 575 ) 576 577 createTable("plugins", "", "", 578 []tC{ 579 ccol("uname", 180, ""), 580 bcol("active", false), 581 bcol("installed", false), 582 }, 583 []tK{ 584 {"uname", "unique", "", false}, 585 }, 586 ) 587 588 createTable("themes", "", "", 589 []tC{ 590 ccol("uname", 180, ""), 591 bcol("default", false), 592 //text("profileUserVars"), 593 }, 594 []tK{ 595 {"uname", "unique", "", false}, 596 }, 597 ) 598 599 createTable("widgets", "", "", 600 []tC{ 601 {"wid", "int", 0, false, true, ""}, 602 {"position", "int", 0, false, false, ""}, 603 ccol("side", 100, ""), 604 ccol("type", 100, ""), 605 bcol("active", false), 606 ccol("location", 100, ""), 607 text("data"), 608 }, 609 []tK{ 610 {"wid", "primary", "", false}, 611 }, 612 ) 613 614 createTable("menus", "", "", 615 []tC{ 616 {"mid", "int", 0, false, true, ""}, 617 }, 618 []tK{ 619 {"mid", "primary", "", false}, 620 }, 621 ) 622 623 createTable("menu_items", "", "", 624 []tC{ 625 {"miid", "int", 0, false, true, ""}, 626 {"mid", "int", 0, false, false, ""}, 627 ccol("name", 200, "''"), 628 ccol("htmlID", 200, "''"), 629 ccol("cssClass", 200, "''"), 630 ccol("position", 100, ""), 631 ccol("path", 200, "''"), 632 ccol("aria", 200, "''"), 633 ccol("tooltip", 200, "''"), 634 ccol("tmplName", 200, "''"), 635 {"order", "int", 0, false, false, "0"}, 636 637 bcol("guestOnly", false), 638 bcol("memberOnly", false), 639 bcol("staffOnly", false), 640 bcol("adminOnly", false), 641 }, 642 []tK{ 643 {"miid", "primary", "", false}, 644 }, 645 ) 646 647 createTable("pages", mysqlPre, mysqlCol, 648 []tC{ 649 {"pid", "int", 0, false, true, ""}, 650 //ccol("path", 200, ""), 651 ccol("name", 200, ""), 652 ccol("title", 200, ""), 653 text("body"), 654 // TODO: Make this a table? 655 text("allowedGroups"), 656 {"menuID", "int", 0, false, false, "-1"}, // simple sidebar menu 657 }, 658 []tK{ 659 {"pid", "primary", "", false}, 660 }, 661 ) 662 663 createTable("registration_logs", "", "", 664 []tC{ 665 {"rlid", "int", 0, false, true, ""}, 666 ccol("username", 100, ""), 667 {"email", "varchar", 100, false, false, ""}, 668 ccol("failureReason", 100, ""), 669 bcol("success", false), // Did this attempt succeed? 670 ccol("ipaddress", 200, ""), 671 createdAt("doneAt"), 672 }, 673 []tK{ 674 {"rlid", "primary", "", false}, 675 }, 676 ) 677 678 createTable("login_logs", "", "", 679 []tC{ 680 {"lid", "int", 0, false, true, ""}, 681 {"uid", "int", 0, false, false, ""}, 682 683 bcol("success", false), // Did this attempt succeed? 684 ccol("ipaddress", 200, ""), 685 createdAt("doneAt"), 686 }, 687 []tK{ 688 {"lid", "primary", "", false}, 689 }, 690 ) 691 692 createTable("moderation_logs", "", "", 693 []tC{ 694 ccol("action", 100, ""), 695 {"elementID", "int", 0, false, false, ""}, 696 ccol("elementType", 100, ""), 697 ccol("ipaddress", 200, ""), 698 {"actorID", "int", 0, false, false, ""}, // TODO: Make this a foreign key 699 {"doneAt", "datetime", 0, false, false, ""}, 700 text("extra"), 701 }, nil, 702 ) 703 704 createTable("administration_logs", "", "", 705 []tC{ 706 ccol("action", 100, ""), 707 {"elementID", "int", 0, false, false, ""}, 708 ccol("elementType", 100, ""), 709 ccol("ipaddress", 200, ""), 710 {"actorID", "int", 0, false, false, ""}, // TODO: Make this a foreign key 711 {"doneAt", "datetime", 0, false, false, ""}, 712 text("extra"), 713 }, nil, 714 ) 715 716 createTable("viewchunks", "", "", 717 []tC{ 718 {"count", "int", 0, false, false, "0"}, 719 {"avg", "int", 0, false, false, "0"}, 720 {"createdAt", "datetime", 0, false, false, ""}, 721 ccol("route", 200, ""), // TODO: set a default empty here 722 }, nil, 723 ) 724 725 createTable("viewchunks_agents", "", "", 726 []tC{ 727 {"count", "int", 0, false, false, "0"}, 728 {"createdAt", "datetime", 0, false, false, ""}, 729 ccol("browser", 200, ""), // googlebot, firefox, opera, etc. 730 //ccol("version",0,""), // the version of the browser or bot 731 }, nil, 732 ) 733 734 createTable("viewchunks_systems", "", "", 735 []tC{ 736 {"count", "int", 0, false, false, "0"}, 737 {"createdAt", "datetime", 0, false, false, ""}, 738 ccol("system", 200, ""), // windows, android, unknown, etc. 739 }, nil, 740 ) 741 742 createTable("viewchunks_langs", "", "", 743 []tC{ 744 {"count", "int", 0, false, false, "0"}, 745 {"createdAt", "datetime", 0, false, false, ""}, 746 ccol("lang", 200, ""), // en, ru, etc. 747 }, nil, 748 ) 749 750 createTable("viewchunks_referrers", "", "", 751 []tC{ 752 {"count", "int", 0, false, false, "0"}, 753 {"createdAt", "datetime", 0, false, false, ""}, 754 ccol("domain", 200, ""), 755 }, nil, 756 ) 757 758 createTable("viewchunks_forums", "", "", 759 []tC{ 760 {"count", "int", 0, false, false, "0"}, 761 {"createdAt", "datetime", 0, false, false, ""}, 762 {"forum", "int", 0, false, false, ""}, 763 }, nil, 764 ) 765 766 createTable("topicchunks", "", "", 767 []tC{ 768 {"count", "int", 0, false, false, "0"}, 769 {"createdAt", "datetime", 0, false, false, ""}, 770 // TODO: Add a column for the parent forum? 771 }, nil, 772 ) 773 774 createTable("postchunks", "", "", 775 []tC{ 776 {"count", "int", 0, false, false, "0"}, 777 {"createdAt", "datetime", 0, false, false, ""}, 778 // TODO: Add a column for the parent topic / profile? 779 }, nil, 780 ) 781 782 createTable("memchunks", "", "", 783 []tC{ 784 {"count", "int", 0, false, false, "0"}, 785 {"stack", "int", 0, false, false, "0"}, 786 {"heap", "int", 0, false, false, "0"}, 787 {"createdAt", "datetime", 0, false, false, ""}, 788 }, nil, 789 ) 790 791 createTable("perfchunks", "", "", 792 []tC{ 793 {"low", "int", 0, false, false, "0"}, 794 {"high", "int", 0, false, false, "0"}, 795 {"avg", "int", 0, false, false, "0"}, 796 {"createdAt", "datetime", 0, false, false, ""}, 797 }, nil, 798 ) 799 800 createTable("sync", "", "", 801 []tC{ 802 {"last_update", "datetime", 0, false, false, ""}, 803 }, nil, 804 ) 805 806 createTable("updates", "", "", 807 []tC{ 808 {"dbVersion", "int", 0, false, false, "0"}, 809 }, nil, 810 ) 811 812 createTable("meta", "", "", 813 []tC{ 814 ccol("name", 200, ""), 815 ccol("value", 200, ""), 816 }, nil, 817 ) 818 819 /*createTable("tables", "", "", 820 []tC{ 821 {"id", "int", 0, false, true, ""}, 822 ccol("name", 200, ""), 823 }, 824 []tK{ 825 {"id", "primary", "", false}, 826 {"name", "unique", "", false}, 827 }, 828 )*/ 829 830 return err 831 }